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; 41217ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 413416022c9SBarry Smith row = im[k]; 4145ef9f2a5SBarry Smith if (row < 0) continue; 4152515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 416e32f2f54SBarry 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); 4173b2fbd54SBarry Smith #endif 418720833daSHong Zhang rp = aj + ai[row]; 419*876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 42017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 421416022c9SBarry Smith low = 0; 422c71e6ed7SBarry Smith high = nrow; 42317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4245ef9f2a5SBarry Smith if (in[l] < 0) continue; 4252515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 426e32f2f54SBarry 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); 4273b2fbd54SBarry Smith #endif 428bfeeae90SHong Zhang col = in[l]; 429720833daSHong Zhang if (!A->structure_only) { 4304b0e389bSBarry Smith if (roworiented) { 4315ef9f2a5SBarry Smith value = v[l + k*n]; 432bef8e0ddSBarry Smith } else { 4334b0e389bSBarry Smith value = v[k + l*m]; 4344b0e389bSBarry Smith } 435720833daSHong Zhang } else { /* A->structure_only */ 436720833daSHong Zhang value = 1; /* avoid 'continue' below? */ 437720833daSHong Zhang } 438dcd36c23SBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) continue; 43936db0b34SBarry Smith 4402205254eSKarl Rupp if (col <= lastcol) low = 0; 4412205254eSKarl Rupp else high = nrow; 442e2ee6c50SBarry Smith lastcol = col; 443416022c9SBarry Smith while (high-low > 5) { 444416022c9SBarry Smith t = (low+high)/2; 445416022c9SBarry Smith if (rp[t] > col) high = t; 446416022c9SBarry Smith else low = t; 44717ab2063SBarry Smith } 448416022c9SBarry Smith for (i=low; i<high; i++) { 44917ab2063SBarry Smith if (rp[i] > col) break; 45017ab2063SBarry Smith if (rp[i] == col) { 451*876c6284SHong Zhang if (!A->structure_only) { 452416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 45317ab2063SBarry Smith else ap[i] = value; 454720833daSHong Zhang } 455e44c0bd4SBarry Smith low = i + 1; 45617ab2063SBarry Smith goto noinsert; 45717ab2063SBarry Smith } 45817ab2063SBarry Smith } 459dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 460c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 461e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 462720833daSHong Zhang if (A->structure_only) { 463*876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 464720833daSHong Zhang } else { 465fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 466720833daSHong Zhang } 467c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 468416022c9SBarry Smith /* shift up all the later entries in this row */ 469416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 47017ab2063SBarry Smith rp[ii+1] = rp[ii]; 471*876c6284SHong Zhang if (!A->structure_only) ap[ii+1] = ap[ii]; 472720833daSHong Zhang } 47317ab2063SBarry Smith rp[i] = col; 474*876c6284SHong Zhang if (!A->structure_only) ap[i] = value; 475416022c9SBarry Smith low = i + 1; 476e56f5c9eSBarry Smith A->nonzerostate++; 477e44c0bd4SBarry Smith noinsert:; 47817ab2063SBarry Smith } 47917ab2063SBarry Smith ailen[row] = nrow; 48017ab2063SBarry Smith } 4813a40ed3dSBarry Smith PetscFunctionReturn(0); 48217ab2063SBarry Smith } 48317ab2063SBarry Smith 48481824310SBarry Smith 485a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4867eb43aa7SLois Curfman McInnes { 4877eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 48897f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 48997f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 49054f21887SBarry Smith MatScalar *ap,*aa = a->a; 4917eb43aa7SLois Curfman McInnes 4923a40ed3dSBarry Smith PetscFunctionBegin; 4937eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 4947eb43aa7SLois Curfman McInnes row = im[k]; 495e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 496e32f2f54SBarry 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); 497bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 4987eb43aa7SLois Curfman McInnes nrow = ailen[row]; 4997eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 500e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 501e32f2f54SBarry 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); 502bfeeae90SHong Zhang col = in[l]; 5037eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 5047eb43aa7SLois Curfman McInnes while (high-low > 5) { 5057eb43aa7SLois Curfman McInnes t = (low+high)/2; 5067eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 5077eb43aa7SLois Curfman McInnes else low = t; 5087eb43aa7SLois Curfman McInnes } 5097eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 5107eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5117eb43aa7SLois Curfman McInnes if (rp[i] == col) { 512b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5137eb43aa7SLois Curfman McInnes goto finished; 5147eb43aa7SLois Curfman McInnes } 5157eb43aa7SLois Curfman McInnes } 51697e567efSBarry Smith *v++ = 0.0; 5177eb43aa7SLois Curfman McInnes finished:; 5187eb43aa7SLois Curfman McInnes } 5197eb43aa7SLois Curfman McInnes } 5203a40ed3dSBarry Smith PetscFunctionReturn(0); 5217eb43aa7SLois Curfman McInnes } 5227eb43aa7SLois Curfman McInnes 52317ab2063SBarry Smith 524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 52517ab2063SBarry Smith { 526416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5276849ba73SBarry Smith PetscErrorCode ierr; 5286f69ff64SBarry Smith PetscInt i,*col_lens; 5296f69ff64SBarry Smith int fd; 530b37d52dbSMark F. Adams FILE *file; 53117ab2063SBarry Smith 5323a40ed3dSBarry Smith PetscFunctionBegin; 533b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 534854ce69bSBarry Smith ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr); 5352205254eSKarl Rupp 5360700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 537d0f46423SBarry Smith col_lens[1] = A->rmap->n; 538d0f46423SBarry Smith col_lens[2] = A->cmap->n; 539416022c9SBarry Smith col_lens[3] = a->nz; 540416022c9SBarry Smith 541416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 542d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 543416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 54417ab2063SBarry Smith } 545d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 546606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 547416022c9SBarry Smith 548416022c9SBarry Smith /* store column indices (zero start index) */ 5496f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 550416022c9SBarry Smith 551416022c9SBarry Smith /* store nonzero values */ 5526f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 553b37d52dbSMark F. Adams 554b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 555b37d52dbSMark F. Adams if (file) { 55633d57670SJed Brown fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs)); 557b37d52dbSMark F. Adams } 5583a40ed3dSBarry Smith PetscFunctionReturn(0); 55917ab2063SBarry Smith } 560416022c9SBarry Smith 56109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 562cd155464SBarry Smith 563dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 564416022c9SBarry Smith { 565416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 566dfbe8321SBarry Smith PetscErrorCode ierr; 56760e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 568e060cb09SBarry Smith const char *name; 569f3ef73ceSBarry Smith PetscViewerFormat format; 57017ab2063SBarry Smith 5713a40ed3dSBarry Smith PetscFunctionBegin; 57243e49210SHong Zhang if (!a->a) PetscFunctionReturn(0); 57343e49210SHong Zhang 574b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 57571c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 57697f1f81fSBarry Smith PetscInt nofinalvalue = 0; 57760e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 578c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 579d00d2cf4SBarry Smith nofinalvalue = 1; 580d00d2cf4SBarry Smith } 581d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 582d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 58377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 584fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 585fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 586fbfe6fa7SJed Brown #else 58777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 588fbfe6fa7SJed Brown #endif 589b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 59017ab2063SBarry Smith 59117ab2063SBarry Smith for (i=0; i<m; i++) { 59260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 593aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 594a9bf72d8SJed 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); 59517ab2063SBarry Smith #else 59660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 59717ab2063SBarry Smith #endif 59817ab2063SBarry Smith } 59917ab2063SBarry Smith } 600d00d2cf4SBarry Smith if (nofinalvalue) { 601c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 602c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 603c337ccceSJed Brown #else 604d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 605c337ccceSJed Brown #endif 606d00d2cf4SBarry Smith } 607317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 608fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 609d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 61068369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 611cd155464SBarry Smith PetscFunctionReturn(0); 612fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 613d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 61444cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 61577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 61660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 617aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 61836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 61960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 62036db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 62160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 62236db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 62360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6246831982aSBarry Smith } 62544cd7ae7SLois Curfman McInnes #else 62660e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 62744cd7ae7SLois Curfman McInnes #endif 62844cd7ae7SLois Curfman McInnes } 629b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 63044cd7ae7SLois Curfman McInnes } 631d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 632fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 63397f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 634d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 635854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 636496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 637496be53dSLois Curfman McInnes sptr[i] = nzd+1; 63860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 639496be53dSLois Curfman McInnes if (a->j[j] >= i) { 640aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 64136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 642496be53dSLois Curfman McInnes #else 643496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 644496be53dSLois Curfman McInnes #endif 645496be53dSLois Curfman McInnes } 646496be53dSLois Curfman McInnes } 647496be53dSLois Curfman McInnes } 6482e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 64977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 6502e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 6512205254eSKarl Rupp if (i+4<m) { 6522205254eSKarl 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); 6532205254eSKarl Rupp } else if (i+3<m) { 6542205254eSKarl 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); 6552205254eSKarl Rupp } else if (i+2<m) { 6562205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6572205254eSKarl Rupp } else if (i+1<m) { 6582205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6592205254eSKarl Rupp } else if (i<m) { 6602205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6612205254eSKarl Rupp } else { 6622205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6632205254eSKarl Rupp } 664496be53dSLois Curfman McInnes } 665b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 666606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 667496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 66860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 66977431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 670496be53dSLois Curfman McInnes } 671b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 672496be53dSLois Curfman McInnes } 673b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 674496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 67560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 676496be53dSLois Curfman McInnes if (a->j[j] >= i) { 677aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 67836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 67960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6806831982aSBarry Smith } 681496be53dSLois Curfman McInnes #else 68260e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 683496be53dSLois Curfman McInnes #endif 684496be53dSLois Curfman McInnes } 685496be53dSLois Curfman McInnes } 686b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 687496be53dSLois Curfman McInnes } 688d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 689fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 69097f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 69187828ca2SBarry Smith PetscScalar value; 69268f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 69368f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 69468f1ed48SBarry Smith 69568f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 69668f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 69768f1ed48SBarry Smith realonly = PETSC_FALSE; 69868f1ed48SBarry Smith break; 69968f1ed48SBarry Smith } 70068f1ed48SBarry Smith } 70168f1ed48SBarry Smith #endif 70202594712SBarry Smith 703d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 70402594712SBarry Smith for (i=0; i<m; i++) { 70502594712SBarry Smith jcnt = 0; 706d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 707e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 70802594712SBarry Smith value = a->a[cnt++]; 709e24b481bSBarry Smith jcnt++; 71002594712SBarry Smith } else { 71102594712SBarry Smith value = 0.0; 71202594712SBarry Smith } 713aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 71468f1ed48SBarry Smith if (realonly) { 71560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 71668f1ed48SBarry Smith } else { 71760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 71868f1ed48SBarry Smith } 71902594712SBarry Smith #else 72060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 72102594712SBarry Smith #endif 72202594712SBarry Smith } 723b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 72402594712SBarry Smith } 725d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7263c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 727150b93efSMatthew G. Knepley PetscInt fshift=1; 728d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7293c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 73019303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 7313c215bfdSMatthew Knepley #else 73219303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 7333c215bfdSMatthew Knepley #endif 734d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 7353c215bfdSMatthew Knepley for (i=0; i<m; i++) { 73660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 7373c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 738a9a0e077SKarl 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); 7393c215bfdSMatthew Knepley #else 740150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 7413c215bfdSMatthew Knepley #endif 7423c215bfdSMatthew Knepley } 7433c215bfdSMatthew Knepley } 744d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7453a40ed3dSBarry Smith } else { 746d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 747d5f3da31SBarry Smith if (A->factortype) { 74816cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 74916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 75016cd7e1dSShri Abhyankar /* L part */ 75160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 75216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 75316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 75460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 75516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7566712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 75716cd7e1dSShri Abhyankar } else { 75860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 75916cd7e1dSShri Abhyankar } 76016cd7e1dSShri Abhyankar #else 76160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 76216cd7e1dSShri Abhyankar #endif 76316cd7e1dSShri Abhyankar } 76416cd7e1dSShri Abhyankar /* diagonal */ 76516cd7e1dSShri Abhyankar j = a->diag[i]; 76616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 76716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 76860e0710aSBarry 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); 76916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7706712e2f1SBarry 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); 77116cd7e1dSShri Abhyankar } else { 77260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 77316cd7e1dSShri Abhyankar } 77416cd7e1dSShri Abhyankar #else 77560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 77616cd7e1dSShri Abhyankar #endif 77716cd7e1dSShri Abhyankar 77816cd7e1dSShri Abhyankar /* U part */ 77960e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 78016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 78116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 78260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 78316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 78422ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 78516cd7e1dSShri Abhyankar } else { 78660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 78716cd7e1dSShri Abhyankar } 78816cd7e1dSShri Abhyankar #else 78960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 79016cd7e1dSShri Abhyankar #endif 79116cd7e1dSShri Abhyankar } 79216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 79316cd7e1dSShri Abhyankar } 79416cd7e1dSShri Abhyankar } else { 79517ab2063SBarry Smith for (i=0; i<m; i++) { 79677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 79760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 798aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 79936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 80060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 80136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 80260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8033a40ed3dSBarry Smith } else { 80460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 80517ab2063SBarry Smith } 80617ab2063SBarry Smith #else 80760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 80817ab2063SBarry Smith #endif 80917ab2063SBarry Smith } 810b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 81117ab2063SBarry Smith } 81216cd7e1dSShri Abhyankar } 813d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 81417ab2063SBarry Smith } 815b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8163a40ed3dSBarry Smith PetscFunctionReturn(0); 817416022c9SBarry Smith } 818416022c9SBarry Smith 8199804daf3SBarry Smith #include <petscdraw.h> 820dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 821416022c9SBarry Smith { 822480ef9eaSBarry Smith Mat A = (Mat) Aa; 823416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 824dfbe8321SBarry Smith PetscErrorCode ierr; 825383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 826383922c3SLisandro Dalcin int color; 827b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 828b0a32e0cSBarry Smith PetscViewer viewer; 829f3ef73ceSBarry Smith PetscViewerFormat format; 830cddf8d76SBarry Smith 8313a40ed3dSBarry Smith PetscFunctionBegin; 832480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 833b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 834b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 835383922c3SLisandro Dalcin 836416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 8370513a670SBarry Smith 838fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 839383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8400513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 841b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 842416022c9SBarry Smith for (i=0; i<m; i++) { 843cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 844bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 845bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 84636db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 847b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 848cddf8d76SBarry Smith } 849cddf8d76SBarry Smith } 850b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 851cddf8d76SBarry Smith for (i=0; i<m; i++) { 852cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 853bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 854bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 855cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 856b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 857cddf8d76SBarry Smith } 858cddf8d76SBarry Smith } 859b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 860cddf8d76SBarry Smith for (i=0; i<m; i++) { 861cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 862bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 863bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 86436db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 865b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 866416022c9SBarry Smith } 867416022c9SBarry Smith } 868383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8690513a670SBarry Smith } else { 8700513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8710513a670SBarry Smith /* first determine max of all nonzero values */ 872b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 873383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 874b0a32e0cSBarry Smith PetscDraw popup; 8750513a670SBarry Smith 8760513a670SBarry Smith for (i=0; i<nz; i++) { 8770513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8780513a670SBarry Smith } 879383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 880b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 88145f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 882383922c3SLisandro Dalcin 883383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8840513a670SBarry Smith for (i=0; i<m; i++) { 885383922c3SLisandro Dalcin y_l = m - i - 1.0; 886383922c3SLisandro Dalcin y_r = y_l + 1.0; 887bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 888383922c3SLisandro Dalcin x_l = a->j[j]; 889383922c3SLisandro Dalcin x_r = x_l + 1.0; 890b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 891b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8920513a670SBarry Smith count++; 8930513a670SBarry Smith } 8940513a670SBarry Smith } 895383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8960513a670SBarry Smith } 897480ef9eaSBarry Smith PetscFunctionReturn(0); 898480ef9eaSBarry Smith } 899cddf8d76SBarry Smith 9009804daf3SBarry Smith #include <petscdraw.h> 901dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 902480ef9eaSBarry Smith { 903dfbe8321SBarry Smith PetscErrorCode ierr; 904b0a32e0cSBarry Smith PetscDraw draw; 90536db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 906ace3abfcSBarry Smith PetscBool isnull; 907480ef9eaSBarry Smith 908480ef9eaSBarry Smith PetscFunctionBegin; 909b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 910b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 911480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 912480ef9eaSBarry Smith 913d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 914480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 915b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 916832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 917b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 9180298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 919832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 9203a40ed3dSBarry Smith PetscFunctionReturn(0); 921416022c9SBarry Smith } 922416022c9SBarry Smith 923dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 924416022c9SBarry Smith { 925dfbe8321SBarry Smith PetscErrorCode ierr; 926ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 927416022c9SBarry Smith 9283a40ed3dSBarry Smith PetscFunctionBegin; 929251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 930251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 931251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 932c45a1595SBarry Smith if (iascii) { 9333a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 9340f5bd95cSBarry Smith } else if (isbinary) { 9353a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 9360f5bd95cSBarry Smith } else if (isdraw) { 9373a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 93811aeaf0aSBarry Smith } 9394108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 9403a40ed3dSBarry Smith PetscFunctionReturn(0); 94117ab2063SBarry Smith } 94219bcc07fSBarry Smith 943dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 94417ab2063SBarry Smith { 945416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9466849ba73SBarry Smith PetscErrorCode ierr; 94797f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 948d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 94954f21887SBarry Smith MatScalar *aa = a->a,*ap; 9503447b6efSHong Zhang PetscReal ratio = 0.6; 95117ab2063SBarry Smith 9523a40ed3dSBarry Smith PetscFunctionBegin; 9533a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 95417ab2063SBarry Smith 95543ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 95617ab2063SBarry Smith for (i=1; i<m; i++) { 957416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 95817ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 95994a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 96017ab2063SBarry Smith if (fshift) { 961bfeeae90SHong Zhang ip = aj + ai[i]; 962bfeeae90SHong Zhang ap = aa + ai[i]; 96317ab2063SBarry Smith N = ailen[i]; 96417ab2063SBarry Smith for (j=0; j<N; j++) { 96517ab2063SBarry Smith ip[j-fshift] = ip[j]; 966*876c6284SHong Zhang if (!A->structure_only) ap[j-fshift] = ap[j]; 96717ab2063SBarry Smith } 96817ab2063SBarry Smith } 96917ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 97017ab2063SBarry Smith } 97117ab2063SBarry Smith if (m) { 97217ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 97317ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 97417ab2063SBarry Smith } 9757b083b7cSBarry Smith 97617ab2063SBarry Smith /* reset ilen and imax for each row */ 9777b083b7cSBarry Smith a->nonzerorowcnt = 0; 97817ab2063SBarry Smith for (i=0; i<m; i++) { 97917ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 9807b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 98117ab2063SBarry Smith } 982bfeeae90SHong Zhang a->nz = ai[m]; 98365e19b50SBarry 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); 98417ab2063SBarry Smith 98509f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 986d0f46423SBarry 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); 987ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 988ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9892205254eSKarl Rupp 9908e58a170SBarry Smith A->info.mallocs += a->reallocs; 991dd5f02e7SSatish Balay a->reallocs = 0; 9926712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 99336db0b34SBarry Smith a->rmax = rmax; 9944e220ebcSLois Curfman McInnes 99511e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 9964108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 997acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9983a40ed3dSBarry Smith PetscFunctionReturn(0); 99917ab2063SBarry Smith } 100017ab2063SBarry Smith 100199cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 100299cafbc1SBarry Smith { 100399cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 100499cafbc1SBarry Smith PetscInt i,nz = a->nz; 100554f21887SBarry Smith MatScalar *aa = a->a; 1006acf2f550SJed Brown PetscErrorCode ierr; 100799cafbc1SBarry Smith 100899cafbc1SBarry Smith PetscFunctionBegin; 100999cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1010acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 101199cafbc1SBarry Smith PetscFunctionReturn(0); 101299cafbc1SBarry Smith } 101399cafbc1SBarry Smith 101499cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 101599cafbc1SBarry Smith { 101699cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 101799cafbc1SBarry Smith PetscInt i,nz = a->nz; 101854f21887SBarry Smith MatScalar *aa = a->a; 1019acf2f550SJed Brown PetscErrorCode ierr; 102099cafbc1SBarry Smith 102199cafbc1SBarry Smith PetscFunctionBegin; 102299cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1023acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 102499cafbc1SBarry Smith PetscFunctionReturn(0); 102599cafbc1SBarry Smith } 102699cafbc1SBarry Smith 1027dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 102817ab2063SBarry Smith { 1029416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1030dfbe8321SBarry Smith PetscErrorCode ierr; 10313a40ed3dSBarry Smith 10323a40ed3dSBarry Smith PetscFunctionBegin; 1033d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1034acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10353a40ed3dSBarry Smith PetscFunctionReturn(0); 103617ab2063SBarry Smith } 1037416022c9SBarry Smith 1038dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 103917ab2063SBarry Smith { 1040416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1041dfbe8321SBarry Smith PetscErrorCode ierr; 1042d5d45c9bSBarry Smith 10433a40ed3dSBarry Smith PetscFunctionBegin; 1044aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1045d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 104617ab2063SBarry Smith #endif 1047e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10486bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10496bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 105005b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1051d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 105205b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 105371f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 105405b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10556bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 105605b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10576bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1058cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10590b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1060a30b2313SHong Zhang 10614108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1062bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1063901853e0SKris Buschelman 1064dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1065bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1066bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1067bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1068bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1069bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1070bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1071af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1072af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1073af8000cdSHong Zhang #endif 107463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 107563c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 10763dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 107763c07aadSStefano Zampini #endif 1078b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1079bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1080bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1081bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1082bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10833a40ed3dSBarry Smith PetscFunctionReturn(0); 108417ab2063SBarry Smith } 108517ab2063SBarry Smith 1086ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 108717ab2063SBarry Smith { 1088416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10894846f1f5SKris Buschelman PetscErrorCode ierr; 10903a40ed3dSBarry Smith 10913a40ed3dSBarry Smith PetscFunctionBegin; 1092a65d3064SKris Buschelman switch (op) { 1093a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 10944e0d8c25SBarry Smith a->roworiented = flg; 1095a65d3064SKris Buschelman break; 1096a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1097a9817697SBarry Smith a->keepnonzeropattern = flg; 1098a65d3064SKris Buschelman break; 1099512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1100512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1101a65d3064SKris Buschelman break; 1102a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 11034e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1104a65d3064SKris Buschelman break; 1105a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 11064e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1107a65d3064SKris Buschelman break; 110828b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 110928b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 111028b2fa4aSMatthew Knepley break; 1111a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 11124e0d8c25SBarry Smith a->ignorezeroentries = flg; 11130df259c2SBarry Smith break; 11143d472b54SHong Zhang case MAT_SPD: 1115b1646e73SJed Brown case MAT_SYMMETRIC: 1116b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1117b1646e73SJed Brown case MAT_HERMITIAN: 1118b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1119957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 11205021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11215021d80fSJed Brown break; 11224e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1123a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1124a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1125290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1126a65d3064SKris Buschelman break; 1127b87ac2d8SJed Brown case MAT_USE_INODES: 1128b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1129b87ac2d8SJed Brown break; 1130c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1131c10200c1SHong Zhang A->submat_singleis = flg; 1132c10200c1SHong Zhang break; 1133a65d3064SKris Buschelman default: 1134e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1135a65d3064SKris Buschelman } 11364108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11373a40ed3dSBarry Smith PetscFunctionReturn(0); 113817ab2063SBarry Smith } 113917ab2063SBarry Smith 1140dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 114117ab2063SBarry Smith { 1142416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11436849ba73SBarry Smith PetscErrorCode ierr; 1144d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 114535e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 114617ab2063SBarry Smith 11473a40ed3dSBarry Smith PetscFunctionBegin; 1148d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1149e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 115035e7444dSHong Zhang 1151d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1152d3e70bfaSHong Zhang PetscInt *diag=a->diag; 115335e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11542c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 115535e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 115635e7444dSHong Zhang PetscFunctionReturn(0); 115735e7444dSHong Zhang } 115835e7444dSHong Zhang 11592dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11601ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 116135e7444dSHong Zhang for (i=0; i<n; i++) { 116235e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11632f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 116435e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 116535e7444dSHong Zhang if (aj[j] == i) { 116635e7444dSHong Zhang x[i] = aa[j]; 116717ab2063SBarry Smith break; 116817ab2063SBarry Smith } 116917ab2063SBarry Smith } 117017ab2063SBarry Smith } 11711ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11723a40ed3dSBarry Smith PetscFunctionReturn(0); 117317ab2063SBarry Smith } 117417ab2063SBarry Smith 1175c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1176dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 117717ab2063SBarry Smith { 1178416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1179d9ca1df4SBarry Smith PetscScalar *y; 1180d9ca1df4SBarry Smith const PetscScalar *x; 1181dfbe8321SBarry Smith PetscErrorCode ierr; 1182d0f46423SBarry Smith PetscInt m = A->rmap->n; 11835c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1184d9ca1df4SBarry Smith const MatScalar *v; 1185a77337e4SBarry Smith PetscScalar alpha; 1186d9ca1df4SBarry Smith PetscInt n,i,j; 1187d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 11883447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1189ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11905c897100SBarry Smith #endif 119117ab2063SBarry Smith 11923a40ed3dSBarry Smith PetscFunctionBegin; 11932e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1194d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 11951ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11965c897100SBarry Smith 11975c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1198bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 11995c897100SBarry Smith #else 12003447b6efSHong Zhang if (usecprow) { 12013447b6efSHong Zhang m = cprow.nrows; 12023447b6efSHong Zhang ii = cprow.i; 12037b2bb3b9SHong Zhang ridx = cprow.rindex; 12043447b6efSHong Zhang } else { 12053447b6efSHong Zhang ii = a->i; 12063447b6efSHong Zhang } 120717ab2063SBarry Smith for (i=0; i<m; i++) { 12083447b6efSHong Zhang idx = a->j + ii[i]; 12093447b6efSHong Zhang v = a->a + ii[i]; 12103447b6efSHong Zhang n = ii[i+1] - ii[i]; 12113447b6efSHong Zhang if (usecprow) { 12127b2bb3b9SHong Zhang alpha = x[ridx[i]]; 12133447b6efSHong Zhang } else { 121417ab2063SBarry Smith alpha = x[i]; 12153447b6efSHong Zhang } 121604fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 121717ab2063SBarry Smith } 12185c897100SBarry Smith #endif 1219dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1220d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12211ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12223a40ed3dSBarry Smith PetscFunctionReturn(0); 122317ab2063SBarry Smith } 122417ab2063SBarry Smith 1225dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12265c897100SBarry Smith { 1227dfbe8321SBarry Smith PetscErrorCode ierr; 12285c897100SBarry Smith 12295c897100SBarry Smith PetscFunctionBegin; 1230170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12315c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12325c897100SBarry Smith PetscFunctionReturn(0); 12335c897100SBarry Smith } 12345c897100SBarry Smith 1235c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 123678b84d54SShri Abhyankar 1237dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 123817ab2063SBarry Smith { 1239416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1240d9fead3dSBarry Smith PetscScalar *y; 124154f21887SBarry Smith const PetscScalar *x; 124254f21887SBarry Smith const MatScalar *aa; 1243dfbe8321SBarry Smith PetscErrorCode ierr; 1244003131ecSBarry Smith PetscInt m=A->rmap->n; 12450298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 12467b083b7cSBarry Smith PetscInt n,i; 1247362ced78SSatish Balay PetscScalar sum; 1248ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 124917ab2063SBarry Smith 1250b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 125197952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1252fee21e36SBarry Smith #endif 1253fee21e36SBarry Smith 12543a40ed3dSBarry Smith PetscFunctionBegin; 12553649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12561ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1257416022c9SBarry Smith ii = a->i; 12584eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 12594f390cb1SBarry Smith ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr); 126097952fefSHong Zhang m = a->compressedrow.nrows; 126197952fefSHong Zhang ii = a->compressedrow.i; 126297952fefSHong Zhang ridx = a->compressedrow.rindex; 126397952fefSHong Zhang for (i=0; i<m; i++) { 126497952fefSHong Zhang n = ii[i+1] - ii[i]; 126597952fefSHong Zhang aj = a->j + ii[i]; 126697952fefSHong Zhang aa = a->a + ii[i]; 126797952fefSHong Zhang sum = 0.0; 1268003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1269003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 127097952fefSHong Zhang y[*ridx++] = sum; 127197952fefSHong Zhang } 127297952fefSHong Zhang } else { /* do not use compressed row format */ 1273b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 12743d3eaba7SBarry Smith aj = a->j; 12753d3eaba7SBarry Smith aa = a->a; 1276b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1277b05257ddSBarry Smith #else 127817ab2063SBarry Smith for (i=0; i<m; i++) { 1279003131ecSBarry Smith n = ii[i+1] - ii[i]; 1280003131ecSBarry Smith aj = a->j + ii[i]; 1281003131ecSBarry Smith aa = a->a + ii[i]; 128217ab2063SBarry Smith sum = 0.0; 1283003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 128417ab2063SBarry Smith y[i] = sum; 128517ab2063SBarry Smith } 12868d195f9aSBarry Smith #endif 1287b05257ddSBarry Smith } 12887b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 12893649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12901ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12913a40ed3dSBarry Smith PetscFunctionReturn(0); 129217ab2063SBarry Smith } 129317ab2063SBarry Smith 1294b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1295b434eb95SMatthew G. Knepley { 1296b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1297b434eb95SMatthew G. Knepley PetscScalar *y; 1298b434eb95SMatthew G. Knepley const PetscScalar *x; 1299b434eb95SMatthew G. Knepley const MatScalar *aa; 1300b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1301b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1302b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1303b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1304b434eb95SMatthew G. Knepley PetscScalar sum; 1305b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1306b434eb95SMatthew G. Knepley 1307b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1308b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1309b434eb95SMatthew G. Knepley #endif 1310b434eb95SMatthew G. Knepley 1311b434eb95SMatthew G. Knepley PetscFunctionBegin; 1312b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1313b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1314b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1315b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1316b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1317b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1318b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1319b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1320b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1321b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1322b434eb95SMatthew G. Knepley sum = 0.0; 1323b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1324b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1325b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1326b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1327b434eb95SMatthew G. Knepley } 1328b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13293d3eaba7SBarry Smith ii = a->i; 1330b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1331b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1332b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1333b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1334b434eb95SMatthew G. Knepley sum = 0.0; 1335b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1336b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1337b434eb95SMatthew G. Knepley y[i] = sum; 1338b434eb95SMatthew G. Knepley } 1339b434eb95SMatthew G. Knepley } 1340b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1341b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1342b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1343b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1344b434eb95SMatthew G. Knepley } 1345b434eb95SMatthew G. Knepley 1346b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1347b434eb95SMatthew G. Knepley { 1348b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1349b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1350b434eb95SMatthew G. Knepley const PetscScalar *x; 1351b434eb95SMatthew G. Knepley const MatScalar *aa; 1352b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1353b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1354b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1355b434eb95SMatthew G. Knepley PetscScalar sum; 1356b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1357b434eb95SMatthew G. Knepley 1358b434eb95SMatthew G. Knepley PetscFunctionBegin; 1359b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1360d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1361b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1362b434eb95SMatthew G. Knepley if (zz != yy) { 1363b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1364b434eb95SMatthew G. Knepley } 1365b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1366b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1367b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1368b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1369b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1370b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1371b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1372b434eb95SMatthew G. Knepley sum = y[*ridx]; 1373b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1374b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1375b434eb95SMatthew G. Knepley } 1376b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13773d3eaba7SBarry Smith ii = a->i; 1378b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1379b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1380b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1381b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1382b434eb95SMatthew G. Knepley sum = y[i]; 1383b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1384b434eb95SMatthew G. Knepley z[i] = sum; 1385b434eb95SMatthew G. Knepley } 1386b434eb95SMatthew G. Knepley } 1387b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1388b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1389d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1390b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1391b434eb95SMatthew G. Knepley } 1392b434eb95SMatthew G. Knepley 1393c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1394dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 139517ab2063SBarry Smith { 1396416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1397f15663dcSBarry Smith PetscScalar *y,*z; 1398f15663dcSBarry Smith const PetscScalar *x; 139954f21887SBarry Smith const MatScalar *aa; 1400dfbe8321SBarry Smith PetscErrorCode ierr; 1401d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1402d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1403362ced78SSatish Balay PetscScalar sum; 1404ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 14059ea0dfa2SSatish Balay 14063a40ed3dSBarry Smith PetscFunctionBegin; 1407f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1408d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14094eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 14104eb6d288SHong Zhang if (zz != yy) { 14114eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 14124eb6d288SHong Zhang } 141397952fefSHong Zhang m = a->compressedrow.nrows; 141497952fefSHong Zhang ii = a->compressedrow.i; 141597952fefSHong Zhang ridx = a->compressedrow.rindex; 141697952fefSHong Zhang for (i=0; i<m; i++) { 141797952fefSHong Zhang n = ii[i+1] - ii[i]; 141897952fefSHong Zhang aj = a->j + ii[i]; 141997952fefSHong Zhang aa = a->a + ii[i]; 142097952fefSHong Zhang sum = y[*ridx]; 1421f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 142297952fefSHong Zhang z[*ridx++] = sum; 142397952fefSHong Zhang } 142497952fefSHong Zhang } else { /* do not use compressed row format */ 14253d3eaba7SBarry Smith ii = a->i; 1426f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 14273d3eaba7SBarry Smith aj = a->j; 14283d3eaba7SBarry Smith aa = a->a; 1429f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1430f15663dcSBarry Smith #else 143117ab2063SBarry Smith for (i=0; i<m; i++) { 1432f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1433f15663dcSBarry Smith aj = a->j + ii[i]; 1434f15663dcSBarry Smith aa = a->a + ii[i]; 143517ab2063SBarry Smith sum = y[i]; 1436f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 143717ab2063SBarry Smith z[i] = sum; 143817ab2063SBarry Smith } 143902ab625aSSatish Balay #endif 1440f15663dcSBarry Smith } 1441dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1442f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1443d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14448154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14456b375ea7SVictor Minden /* 1446918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1447918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1448918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14496b375ea7SVictor Minden */ 1450918e98c3SVictor Minden #endif 14513a40ed3dSBarry Smith PetscFunctionReturn(0); 145217ab2063SBarry Smith } 145317ab2063SBarry Smith 145417ab2063SBarry Smith /* 145517ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 145617ab2063SBarry Smith */ 1457dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 145817ab2063SBarry Smith { 1459416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14606849ba73SBarry Smith PetscErrorCode ierr; 1461d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 146217ab2063SBarry Smith 14633a40ed3dSBarry Smith PetscFunctionBegin; 146409f38230SBarry Smith if (!a->diag) { 1465785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 14663bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 146709f38230SBarry Smith } 1468d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 146909f38230SBarry Smith a->diag[i] = a->i[i+1]; 1470bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1471bfeeae90SHong Zhang if (a->j[j] == i) { 147209f38230SBarry Smith a->diag[i] = j; 147317ab2063SBarry Smith break; 147417ab2063SBarry Smith } 147517ab2063SBarry Smith } 147617ab2063SBarry Smith } 14773a40ed3dSBarry Smith PetscFunctionReturn(0); 147817ab2063SBarry Smith } 147917ab2063SBarry Smith 1480be5855fcSBarry Smith /* 1481be5855fcSBarry Smith Checks for missing diagonals 1482be5855fcSBarry Smith */ 1483ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1484be5855fcSBarry Smith { 1485be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14867734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1487be5855fcSBarry Smith 1488be5855fcSBarry Smith PetscFunctionBegin; 148909f38230SBarry Smith *missing = PETSC_FALSE; 14907734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 149109f38230SBarry Smith *missing = PETSC_TRUE; 149209f38230SBarry Smith if (d) *d = 0; 1493955c1f14SBarry Smith PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n"); 149409f38230SBarry Smith } else { 1495f1e2ffcdSBarry Smith diag = a->diag; 1496d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 14977734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 149809f38230SBarry Smith *missing = PETSC_TRUE; 149909f38230SBarry Smith if (d) *d = i; 1500955c1f14SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D\n",i); 1501358d2f5dSShri Abhyankar break; 150209f38230SBarry Smith } 1503be5855fcSBarry Smith } 1504be5855fcSBarry Smith } 1505be5855fcSBarry Smith PetscFunctionReturn(0); 1506be5855fcSBarry Smith } 1507be5855fcSBarry Smith 1508422a814eSBarry Smith /* 1509422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1510422a814eSBarry Smith */ 15117087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 151271f1c65dSBarry Smith { 151371f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 151471f1c65dSBarry Smith PetscErrorCode ierr; 1515d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 151654f21887SBarry Smith MatScalar *v = a->a; 151754f21887SBarry Smith PetscScalar *idiag,*mdiag; 151871f1c65dSBarry Smith 151971f1c65dSBarry Smith PetscFunctionBegin; 152071f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 152171f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 152271f1c65dSBarry Smith diag = a->diag; 152371f1c65dSBarry Smith if (!a->idiag) { 1524dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 15253bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 152671f1c65dSBarry Smith v = a->a; 152771f1c65dSBarry Smith } 152871f1c65dSBarry Smith mdiag = a->mdiag; 152971f1c65dSBarry Smith idiag = a->idiag; 153071f1c65dSBarry Smith 1531422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 153271f1c65dSBarry Smith for (i=0; i<m; i++) { 153371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1534899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1535899639b0SHong Zhang if (PetscRealPart(fshift)) { 1536899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 15377b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 15387b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 15397b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 15407b6c816cSBarry Smith } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1541899639b0SHong Zhang } 154271f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 154371f1c65dSBarry Smith } 154471f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 154571f1c65dSBarry Smith } else { 154671f1c65dSBarry Smith for (i=0; i<m; i++) { 154771f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 154871f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 154971f1c65dSBarry Smith } 1550dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 155171f1c65dSBarry Smith } 155271f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 155371f1c65dSBarry Smith PetscFunctionReturn(0); 155471f1c65dSBarry Smith } 155571f1c65dSBarry Smith 1556c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 155741f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 155817ab2063SBarry Smith { 1559416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1560e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 15613d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 156254f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1563dfbe8321SBarry Smith PetscErrorCode ierr; 15643d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 156597f1f81fSBarry Smith const PetscInt *idx,*diag; 156617ab2063SBarry Smith 15673a40ed3dSBarry Smith PetscFunctionBegin; 1568b965ef7fSBarry Smith its = its*lits; 156991723122SBarry Smith 157071f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 157171f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 157271f1c65dSBarry Smith a->fshift = fshift; 157371f1c65dSBarry Smith a->omega = omega; 1574ed480e8bSBarry Smith 157571f1c65dSBarry Smith diag = a->diag; 157671f1c65dSBarry Smith t = a->ssor_work; 1577ed480e8bSBarry Smith idiag = a->idiag; 157871f1c65dSBarry Smith mdiag = a->mdiag; 1579ed480e8bSBarry Smith 15801ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 15813649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1582ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 158317ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 158417ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1585ed480e8bSBarry Smith bs = b; 158617ab2063SBarry Smith for (i=0; i<m; i++) { 158771f1c65dSBarry Smith d = fshift + mdiag[i]; 1588416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1589ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1590ed480e8bSBarry Smith v = a->a + diag[i] + 1; 159117ab2063SBarry Smith sum = b[i]*d/omega; 1592003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 159317ab2063SBarry Smith x[i] = sum; 159417ab2063SBarry Smith } 15951ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 15963649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1597efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 15983a40ed3dSBarry Smith PetscFunctionReturn(0); 159917ab2063SBarry Smith } 1600c783ea89SBarry Smith 16012205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 16022205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 160317ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1604887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 160517ab2063SBarry Smith 160617ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 160717ab2063SBarry Smith 1608887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 160917ab2063SBarry Smith */ 161017ab2063SBarry Smith scale = (2.0/omega) - 1.0; 161117ab2063SBarry Smith 161217ab2063SBarry Smith /* x = (E + U)^{-1} b */ 161317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1614416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1615ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1616ed480e8bSBarry Smith v = a->a + diag[i] + 1; 161717ab2063SBarry Smith sum = b[i]; 1618e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1619ed480e8bSBarry Smith x[i] = sum*idiag[i]; 162017ab2063SBarry Smith } 162117ab2063SBarry Smith 162217ab2063SBarry Smith /* t = b - (2*E - D)x */ 1623416022c9SBarry Smith v = a->a; 16242205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 162517ab2063SBarry Smith 162617ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1627ed480e8bSBarry Smith ts = t; 1628416022c9SBarry Smith diag = a->diag; 162917ab2063SBarry Smith for (i=0; i<m; i++) { 1630416022c9SBarry Smith n = diag[i] - a->i[i]; 1631ed480e8bSBarry Smith idx = a->j + a->i[i]; 1632ed480e8bSBarry Smith v = a->a + a->i[i]; 163317ab2063SBarry Smith sum = t[i]; 1634003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1635ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1636733d66baSBarry Smith /* x = x + t */ 1637733d66baSBarry Smith x[i] += t[i]; 163817ab2063SBarry Smith } 163917ab2063SBarry Smith 1640dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16411ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16423649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16433a40ed3dSBarry Smith PetscFunctionReturn(0); 164417ab2063SBarry Smith } 164517ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 164617ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 164717ab2063SBarry Smith for (i=0; i<m; i++) { 1648416022c9SBarry Smith n = diag[i] - a->i[i]; 1649ed480e8bSBarry Smith idx = a->j + a->i[i]; 1650ed480e8bSBarry Smith v = a->a + a->i[i]; 165117ab2063SBarry Smith sum = b[i]; 1652e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16535c99c7daSBarry Smith t[i] = sum; 1654ed480e8bSBarry Smith x[i] = sum*idiag[i]; 165517ab2063SBarry Smith } 16565c99c7daSBarry Smith xb = t; 1657efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16583a40ed3dSBarry Smith } else xb = b; 165917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 166017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1661416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1662ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1663ed480e8bSBarry Smith v = a->a + diag[i] + 1; 166417ab2063SBarry Smith sum = xb[i]; 1665e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16665c99c7daSBarry Smith if (xb == b) { 1667ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16685c99c7daSBarry Smith } else { 1669b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 167017ab2063SBarry Smith } 16715c99c7daSBarry Smith } 1672b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 167317ab2063SBarry Smith } 167417ab2063SBarry Smith its--; 167517ab2063SBarry Smith } 167617ab2063SBarry Smith while (its--) { 167717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 167817ab2063SBarry Smith for (i=0; i<m; i++) { 1679b19a5dc2SMark Adams /* lower */ 1680b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1681ed480e8bSBarry Smith idx = a->j + a->i[i]; 1682ed480e8bSBarry Smith v = a->a + a->i[i]; 168317ab2063SBarry Smith sum = b[i]; 1684e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1685b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1686b19a5dc2SMark Adams /* upper */ 1687b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1688b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1689b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1690b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1691b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 169217ab2063SBarry Smith } 1693b19a5dc2SMark Adams xb = t; 16949f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1695b19a5dc2SMark Adams } else xb = b; 169617ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 169717ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1698b19a5dc2SMark Adams sum = xb[i]; 1699b19a5dc2SMark Adams if (xb == b) { 1700b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1701416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1702ed480e8bSBarry Smith idx = a->j + a->i[i]; 1703ed480e8bSBarry Smith v = a->a + a->i[i]; 1704e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1705ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1706b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1707b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1708b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1709b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1710b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1711b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 171217ab2063SBarry Smith } 1713b19a5dc2SMark Adams } 1714b19a5dc2SMark Adams if (xb == b) { 17159f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1716b19a5dc2SMark Adams } else { 1717b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1718b19a5dc2SMark Adams } 171917ab2063SBarry Smith } 172017ab2063SBarry Smith } 17211ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17223649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1723365a8a9eSBarry Smith PetscFunctionReturn(0); 172417ab2063SBarry Smith } 172517ab2063SBarry Smith 17262af78befSBarry Smith 1727dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 172817ab2063SBarry Smith { 1729416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17304e220ebcSLois Curfman McInnes 17313a40ed3dSBarry Smith PetscFunctionBegin; 17324e220ebcSLois Curfman McInnes info->block_size = 1.0; 17334e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17344e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17354e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17364e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17378e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17387adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1739d5f3da31SBarry Smith if (A->factortype) { 17404e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17414e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17424e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17434e220ebcSLois Curfman McInnes } else { 17444e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17454e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17464e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17474e220ebcSLois Curfman McInnes } 17483a40ed3dSBarry Smith PetscFunctionReturn(0); 174917ab2063SBarry Smith } 175017ab2063SBarry Smith 17512b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 175217ab2063SBarry Smith { 1753416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1754c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 17556849ba73SBarry Smith PetscErrorCode ierr; 175697b48c8fSBarry Smith const PetscScalar *xx; 175797b48c8fSBarry Smith PetscScalar *bb; 1758c7da8527SEric Chamberland PetscInt d = 0; 175917ab2063SBarry Smith 17603a40ed3dSBarry Smith PetscFunctionBegin; 176197b48c8fSBarry Smith if (x && b) { 176297b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 176397b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 176497b48c8fSBarry Smith for (i=0; i<N; i++) { 176597b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 176697b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 176797b48c8fSBarry Smith } 176897b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 176997b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 177097b48c8fSBarry Smith } 177197b48c8fSBarry Smith 1772a9817697SBarry Smith if (a->keepnonzeropattern) { 1773f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1774e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1775bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1776f1e2ffcdSBarry Smith } 1777f4df32b1SMatthew Knepley if (diag != 0.0) { 1778c7da8527SEric Chamberland for (i=0; i<N; i++) { 1779c7da8527SEric Chamberland d = rows[i]; 1780c7da8527SEric 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); 1781c7da8527SEric Chamberland } 1782f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1783f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1784f1e2ffcdSBarry Smith } 1785f1e2ffcdSBarry Smith } 1786f1e2ffcdSBarry Smith } else { 1787f4df32b1SMatthew Knepley if (diag != 0.0) { 178817ab2063SBarry Smith for (i=0; i<N; i++) { 1789e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 17907ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1791416022c9SBarry Smith a->ilen[rows[i]] = 1; 1792f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1793bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 17947ae801bdSBarry Smith } else { /* in case row was completely empty */ 1795f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 179617ab2063SBarry Smith } 179717ab2063SBarry Smith } 17983a40ed3dSBarry Smith } else { 179917ab2063SBarry Smith for (i=0; i<N; i++) { 1800e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1801416022c9SBarry Smith a->ilen[rows[i]] = 0; 180217ab2063SBarry Smith } 180317ab2063SBarry Smith } 1804e56f5c9eSBarry Smith A->nonzerostate++; 1805f1e2ffcdSBarry Smith } 180643a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18073a40ed3dSBarry Smith PetscFunctionReturn(0); 180817ab2063SBarry Smith } 180917ab2063SBarry Smith 18106e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 18116e169961SBarry Smith { 18126e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18136e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18146e169961SBarry Smith PetscErrorCode ierr; 18152b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18166e169961SBarry Smith const PetscScalar *xx; 18176e169961SBarry Smith PetscScalar *bb; 18186e169961SBarry Smith 18196e169961SBarry Smith PetscFunctionBegin; 18206e169961SBarry Smith if (x && b) { 18216e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18226e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18232b40b63fSBarry Smith vecs = PETSC_TRUE; 18246e169961SBarry Smith } 18251795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 18266e169961SBarry Smith for (i=0; i<N; i++) { 18276e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18286e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18292205254eSKarl Rupp 18306e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18316e169961SBarry Smith } 18326e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18336e169961SBarry Smith if (!zeroed[i]) { 18346e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18356e169961SBarry Smith if (zeroed[a->j[j]]) { 18362b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18376e169961SBarry Smith a->a[j] = 0.0; 18386e169961SBarry Smith } 18396e169961SBarry Smith } 18402b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18416e169961SBarry Smith } 18426e169961SBarry Smith if (x && b) { 18436e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18446e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18456e169961SBarry Smith } 18466e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18476e169961SBarry Smith if (diag != 0.0) { 18486e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18491d5a398dSstefano_zampini if (missing) { 18501d5a398dSstefano_zampini if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18511d5a398dSstefano_zampini else { 18521d5a398dSstefano_zampini for (i=0; i<N; i++) { 18531d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 18541d5a398dSstefano_zampini } 18551d5a398dSstefano_zampini } 18561d5a398dSstefano_zampini } else { 18576e169961SBarry Smith for (i=0; i<N; i++) { 18586e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18596e169961SBarry Smith } 18606e169961SBarry Smith } 18611d5a398dSstefano_zampini } 18626e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18636e169961SBarry Smith PetscFunctionReturn(0); 18646e169961SBarry Smith } 18656e169961SBarry Smith 1866a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 186717ab2063SBarry Smith { 1868416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 186997f1f81fSBarry Smith PetscInt *itmp; 187017ab2063SBarry Smith 18713a40ed3dSBarry Smith PetscFunctionBegin; 1872e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 187317ab2063SBarry Smith 1874416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1875bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 187617ab2063SBarry Smith if (idx) { 1877bfeeae90SHong Zhang itmp = a->j + a->i[row]; 187826fbe8dcSKarl Rupp if (*nz) *idx = itmp; 187917ab2063SBarry Smith else *idx = 0; 188017ab2063SBarry Smith } 18813a40ed3dSBarry Smith PetscFunctionReturn(0); 188217ab2063SBarry Smith } 188317ab2063SBarry Smith 1884bfeeae90SHong Zhang /* remove this function? */ 1885a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 188617ab2063SBarry Smith { 18873a40ed3dSBarry Smith PetscFunctionBegin; 18883a40ed3dSBarry Smith PetscFunctionReturn(0); 188917ab2063SBarry Smith } 189017ab2063SBarry Smith 1891dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 189217ab2063SBarry Smith { 1893416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 189454f21887SBarry Smith MatScalar *v = a->a; 189536db0b34SBarry Smith PetscReal sum = 0.0; 18966849ba73SBarry Smith PetscErrorCode ierr; 189797f1f81fSBarry Smith PetscInt i,j; 189817ab2063SBarry Smith 18993a40ed3dSBarry Smith PetscFunctionBegin; 190017ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1901570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1902570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 1903570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 1904570b7f6dSBarry Smith #else 1905416022c9SBarry Smith for (i=0; i<a->nz; i++) { 190636db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 190717ab2063SBarry Smith } 19088f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1909570b7f6dSBarry Smith #endif 191051f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 19113a40ed3dSBarry Smith } else if (type == NORM_1) { 191236db0b34SBarry Smith PetscReal *tmp; 191397f1f81fSBarry Smith PetscInt *jj = a->j; 19141795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 1915064f8208SBarry Smith *nrm = 0.0; 1916416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1917bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 191817ab2063SBarry Smith } 1919d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1920064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 192117ab2063SBarry Smith } 1922606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 192351f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 19243a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1925064f8208SBarry Smith *nrm = 0.0; 1926d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1927bfeeae90SHong Zhang v = a->a + a->i[j]; 192817ab2063SBarry Smith sum = 0.0; 1929416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1930cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 193117ab2063SBarry Smith } 1932064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 193317ab2063SBarry Smith } 193451f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 1935f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 19363a40ed3dSBarry Smith PetscFunctionReturn(0); 193717ab2063SBarry Smith } 193817ab2063SBarry Smith 19394e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 19404e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 19414e938277SHong Zhang { 19424e938277SHong Zhang PetscErrorCode ierr; 19434e938277SHong Zhang PetscInt i,j,anzj; 19444e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 19454e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 19464e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 19474e938277SHong Zhang 19484e938277SHong Zhang PetscFunctionBegin; 19494e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 1950854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 1951785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 1952785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 19534e938277SHong Zhang 19544e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 19554e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 195626fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 19574e938277SHong Zhang /* Form ati for csr format of A^T. */ 195826fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 19594e938277SHong Zhang 19604e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 19614e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 19624e938277SHong Zhang 19634e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 19644e938277SHong Zhang for (i=0;i<am;i++) { 19654e938277SHong Zhang anzj = ai[i+1] - ai[i]; 19664e938277SHong Zhang for (j=0;j<anzj;j++) { 19674e938277SHong Zhang atj[atfill[*aj]] = i; 19684e938277SHong Zhang atfill[*aj++] += 1; 19694e938277SHong Zhang } 19704e938277SHong Zhang } 19714e938277SHong Zhang 19724e938277SHong Zhang /* Clean up temporary space and complete requests. */ 19734e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 1974ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 197533d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1976a2f3521dSMark F. Adams 19774e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 19784e938277SHong Zhang b->free_a = PETSC_FALSE; 19794e938277SHong Zhang b->free_ij = PETSC_TRUE; 19804e938277SHong Zhang b->nonew = 0; 19814e938277SHong Zhang PetscFunctionReturn(0); 19824e938277SHong Zhang } 19834e938277SHong Zhang 1984fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 198517ab2063SBarry Smith { 1986416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1987416022c9SBarry Smith Mat C; 19886849ba73SBarry Smith PetscErrorCode ierr; 1989d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 199054f21887SBarry Smith MatScalar *array = a->a; 199117ab2063SBarry Smith 19923a40ed3dSBarry Smith PetscFunctionBegin; 1993cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1994fc4dec0aSBarry Smith 1995cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1996854ce69bSBarry Smith ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr); 1997bfeeae90SHong Zhang 1998bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1999ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2000d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 200133d57670SJed Brown ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 20027adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2003ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2004606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2005a541d17aSBarry Smith } else { 2006a541d17aSBarry Smith C = *B; 2007a541d17aSBarry Smith } 2008a541d17aSBarry Smith 200917ab2063SBarry Smith for (i=0; i<m; i++) { 201017ab2063SBarry Smith len = ai[i+1]-ai[i]; 201187d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2012b9b97703SBarry Smith array += len; 2013b9b97703SBarry Smith aj += len; 201417ab2063SBarry Smith } 20156d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20166d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 201717ab2063SBarry Smith 2018cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 2019416022c9SBarry Smith *B = C; 202017ab2063SBarry Smith } else { 202128be2f97SBarry Smith ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 202217ab2063SBarry Smith } 20233a40ed3dSBarry Smith PetscFunctionReturn(0); 202417ab2063SBarry Smith } 202517ab2063SBarry Smith 20267087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2027cd0d46ebSvictorle { 20283d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 202954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 203054f21887SBarry Smith MatScalar *va,*vb; 20316849ba73SBarry Smith PetscErrorCode ierr; 203297f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2033cd0d46ebSvictorle 2034cd0d46ebSvictorle PetscFunctionBegin; 2035cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2036cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20375485867bSBarry Smith if (ma!=nb || na!=mb) { 20385485867bSBarry Smith *f = PETSC_FALSE; 20395485867bSBarry Smith PetscFunctionReturn(0); 20405485867bSBarry Smith } 2041cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2042cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2043cd0d46ebSvictorle va = aij->a; vb = bij->a; 2044785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2045785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2046cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2047cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2048cd0d46ebSvictorle 2049cd0d46ebSvictorle *f = PETSC_TRUE; 2050cd0d46ebSvictorle for (i=0; i<ma; i++) { 2051cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 205297f1f81fSBarry Smith PetscInt idc,idr; 20535485867bSBarry Smith PetscScalar vc,vr; 2054cd0d46ebSvictorle /* column/row index/value */ 20555485867bSBarry Smith idc = adx[aptr[i]]; 20565485867bSBarry Smith idr = bdx[bptr[idc]]; 20575485867bSBarry Smith vc = va[aptr[i]]; 20585485867bSBarry Smith vr = vb[bptr[idc]]; 20595485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20605485867bSBarry Smith *f = PETSC_FALSE; 20615485867bSBarry Smith goto done; 2062cd0d46ebSvictorle } else { 20635485867bSBarry Smith aptr[i]++; 20645485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2065cd0d46ebSvictorle } 2066cd0d46ebSvictorle } 2067cd0d46ebSvictorle } 2068cd0d46ebSvictorle done: 2069cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20703aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2071cd0d46ebSvictorle PetscFunctionReturn(0); 2072cd0d46ebSvictorle } 2073cd0d46ebSvictorle 20747087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 20751cbb95d3SBarry Smith { 20763d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 207754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 207854f21887SBarry Smith MatScalar *va,*vb; 20791cbb95d3SBarry Smith PetscErrorCode ierr; 20801cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 20811cbb95d3SBarry Smith 20821cbb95d3SBarry Smith PetscFunctionBegin; 20831cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 20841cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20851cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 20861cbb95d3SBarry Smith *f = PETSC_FALSE; 20871cbb95d3SBarry Smith PetscFunctionReturn(0); 20881cbb95d3SBarry Smith } 20891cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 20901cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 20911cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2092785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2093785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 20941cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 20951cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 20961cbb95d3SBarry Smith 20971cbb95d3SBarry Smith *f = PETSC_TRUE; 20981cbb95d3SBarry Smith for (i=0; i<ma; i++) { 20991cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 21001cbb95d3SBarry Smith PetscInt idc,idr; 21011cbb95d3SBarry Smith PetscScalar vc,vr; 21021cbb95d3SBarry Smith /* column/row index/value */ 21031cbb95d3SBarry Smith idc = adx[aptr[i]]; 21041cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 21051cbb95d3SBarry Smith vc = va[aptr[i]]; 21061cbb95d3SBarry Smith vr = vb[bptr[idc]]; 21071cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 21081cbb95d3SBarry Smith *f = PETSC_FALSE; 21091cbb95d3SBarry Smith goto done; 21101cbb95d3SBarry Smith } else { 21111cbb95d3SBarry Smith aptr[i]++; 21121cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 21131cbb95d3SBarry Smith } 21141cbb95d3SBarry Smith } 21151cbb95d3SBarry Smith } 21161cbb95d3SBarry Smith done: 21171cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 21181cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 21191cbb95d3SBarry Smith PetscFunctionReturn(0); 21201cbb95d3SBarry Smith } 21211cbb95d3SBarry Smith 2122ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21239e29f15eSvictorle { 2124dfbe8321SBarry Smith PetscErrorCode ierr; 21256e111a19SKarl Rupp 21269e29f15eSvictorle PetscFunctionBegin; 21275485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21289e29f15eSvictorle PetscFunctionReturn(0); 21299e29f15eSvictorle } 21309e29f15eSvictorle 2131ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21321cbb95d3SBarry Smith { 21331cbb95d3SBarry Smith PetscErrorCode ierr; 21346e111a19SKarl Rupp 21351cbb95d3SBarry Smith PetscFunctionBegin; 21361cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21371cbb95d3SBarry Smith PetscFunctionReturn(0); 21381cbb95d3SBarry Smith } 21391cbb95d3SBarry Smith 2140dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 214117ab2063SBarry Smith { 2142416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 214354f21887SBarry Smith PetscScalar *l,*r,x; 214454f21887SBarry Smith MatScalar *v; 2145dfbe8321SBarry Smith PetscErrorCode ierr; 2146d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 214717ab2063SBarry Smith 21483a40ed3dSBarry Smith PetscFunctionBegin; 214917ab2063SBarry Smith if (ll) { 21503ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21513ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2152e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2153e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21541ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2155416022c9SBarry Smith v = a->a; 215617ab2063SBarry Smith for (i=0; i<m; i++) { 215717ab2063SBarry Smith x = l[i]; 2158416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 21592205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 216017ab2063SBarry Smith } 21611ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2162efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 216317ab2063SBarry Smith } 216417ab2063SBarry Smith if (rr) { 2165e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2166e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21671ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2168416022c9SBarry Smith v = a->a; jj = a->j; 21692205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 21701ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2171efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 217217ab2063SBarry Smith } 2173acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 21743a40ed3dSBarry Smith PetscFunctionReturn(0); 217517ab2063SBarry Smith } 217617ab2063SBarry Smith 21777dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 217817ab2063SBarry Smith { 2179db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 21806849ba73SBarry Smith PetscErrorCode ierr; 2181d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 218297f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 21835d0c19d7SBarry Smith const PetscInt *irow,*icol; 21845d0c19d7SBarry Smith PetscInt nrows,ncols; 218597f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 218654f21887SBarry Smith MatScalar *a_new,*mat_a; 2187416022c9SBarry Smith Mat C; 2188cdc6f3adSToby Isaac PetscBool stride; 218917ab2063SBarry Smith 21903a40ed3dSBarry Smith PetscFunctionBegin; 219199141d43SSatish Balay 219217ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2193b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2194b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 219517ab2063SBarry Smith 2196251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2197ff718158SBarry Smith if (stride) { 2198ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2199ff718158SBarry Smith } else { 2200ff718158SBarry Smith first = 0; 2201ff718158SBarry Smith step = 0; 2202ff718158SBarry Smith } 2203fee21e36SBarry Smith if (stride && step == 1) { 220402834360SBarry Smith /* special case of contiguous rows */ 2205dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 220602834360SBarry Smith /* loop over new rows determining lens and starting points */ 220702834360SBarry Smith for (i=0; i<nrows; i++) { 2208bfeeae90SHong Zhang kstart = ai[irow[i]]; 2209a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2210a91a9bebSLisandro Dalcin starts[i] = kstart; 221102834360SBarry Smith for (k=kstart; k<kend; k++) { 2212bfeeae90SHong Zhang if (aj[k] >= first) { 221302834360SBarry Smith starts[i] = k; 221402834360SBarry Smith break; 221502834360SBarry Smith } 221602834360SBarry Smith } 2217a2744918SBarry Smith sum = 0; 221802834360SBarry Smith while (k < kend) { 2219bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2220a2744918SBarry Smith sum++; 222102834360SBarry Smith } 2222a2744918SBarry Smith lens[i] = sum; 222302834360SBarry Smith } 222402834360SBarry Smith /* create submatrix */ 2225cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 222697f1f81fSBarry Smith PetscInt n_cols,n_rows; 222708480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2228e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2229d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 223008480c60SBarry Smith C = *B; 22313a40ed3dSBarry Smith } else { 22323bef6203SJed Brown PetscInt rbs,cbs; 2233ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2234f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22353bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22363bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22373bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22387adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2239ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 224008480c60SBarry Smith } 2241db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2242db02288aSLois Curfman McInnes 224302834360SBarry Smith /* loop over rows inserting into submatrix */ 2244db02288aSLois Curfman McInnes a_new = c->a; 2245db02288aSLois Curfman McInnes j_new = c->j; 2246db02288aSLois Curfman McInnes i_new = c->i; 2247bfeeae90SHong Zhang 224802834360SBarry Smith for (i=0; i<nrows; i++) { 2249a2744918SBarry Smith ii = starts[i]; 2250a2744918SBarry Smith lensi = lens[i]; 2251a2744918SBarry Smith for (k=0; k<lensi; k++) { 2252a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 225302834360SBarry Smith } 225487828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2255a2744918SBarry Smith a_new += lensi; 2256a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2257a2744918SBarry Smith c->ilen[i] = lensi; 225802834360SBarry Smith } 22590e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22603a40ed3dSBarry Smith } else { 226102834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22621795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2263854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 22644dcab191SBarry Smith for (i=0; i<ncols; i++) { 22654dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 22664dcab191SBarry 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); 22674dcab191SBarry Smith #endif 22684dcab191SBarry Smith smap[icol[i]] = i+1; 22694dcab191SBarry Smith } 22704dcab191SBarry Smith 227102834360SBarry Smith /* determine lens of each row */ 227202834360SBarry Smith for (i=0; i<nrows; i++) { 2273bfeeae90SHong Zhang kstart = ai[irow[i]]; 227402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 227502834360SBarry Smith lens[i] = 0; 227602834360SBarry Smith for (k=kstart; k<kend; k++) { 2277bfeeae90SHong Zhang if (smap[aj[k]]) { 227802834360SBarry Smith lens[i]++; 227902834360SBarry Smith } 228002834360SBarry Smith } 228102834360SBarry Smith } 228217ab2063SBarry Smith /* Create and fill new matrix */ 2283a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2284ace3abfcSBarry Smith PetscBool equal; 22850f5bd95cSBarry Smith 228699141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2287e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2288d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2289f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2290d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 229108480c60SBarry Smith C = *B; 22923a40ed3dSBarry Smith } else { 22933bef6203SJed Brown PetscInt rbs,cbs; 2294ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2295f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22963bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22973bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22983bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22997adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2300ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 230108480c60SBarry Smith } 230299141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 230317ab2063SBarry Smith for (i=0; i<nrows; i++) { 230499141d43SSatish Balay row = irow[i]; 2305bfeeae90SHong Zhang kstart = ai[row]; 230699141d43SSatish Balay kend = kstart + a->ilen[row]; 2307bfeeae90SHong Zhang mat_i = c->i[i]; 230899141d43SSatish Balay mat_j = c->j + mat_i; 230999141d43SSatish Balay mat_a = c->a + mat_i; 231099141d43SSatish Balay mat_ilen = c->ilen + i; 231117ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2312bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2313ed480e8bSBarry Smith *mat_j++ = tcol - 1; 231499141d43SSatish Balay *mat_a++ = a->a[k]; 231599141d43SSatish Balay (*mat_ilen)++; 231699141d43SSatish Balay 231717ab2063SBarry Smith } 231817ab2063SBarry Smith } 231917ab2063SBarry Smith } 232002834360SBarry Smith /* Free work space */ 232102834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2322606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2323606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2324cdc6f3adSToby Isaac /* sort */ 2325cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2326cdc6f3adSToby Isaac PetscInt ilen; 2327cdc6f3adSToby Isaac 2328cdc6f3adSToby Isaac mat_i = c->i[i]; 2329cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2330cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2331cdc6f3adSToby Isaac ilen = c->ilen[i]; 2332390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2333cdc6f3adSToby Isaac } 233402834360SBarry Smith } 23356d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23366d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 233717ab2063SBarry Smith 233817ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2339416022c9SBarry Smith *B = C; 23403a40ed3dSBarry Smith PetscFunctionReturn(0); 234117ab2063SBarry Smith } 234217ab2063SBarry Smith 2343fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 234482d44351SHong Zhang { 234582d44351SHong Zhang PetscErrorCode ierr; 234682d44351SHong Zhang Mat B; 234782d44351SHong Zhang 234882d44351SHong Zhang PetscFunctionBegin; 2349c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 235082d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 235182d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 235233d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 235382d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 235482d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 235582d44351SHong Zhang *subMat = B; 2356c2d650bdSHong Zhang } else { 2357c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2358c2d650bdSHong Zhang } 235982d44351SHong Zhang PetscFunctionReturn(0); 236082d44351SHong Zhang } 236182d44351SHong Zhang 23629a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2363a871dcd8SBarry Smith { 236463b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2365dfbe8321SBarry Smith PetscErrorCode ierr; 236663b91edcSBarry Smith Mat outA; 2367ace3abfcSBarry Smith PetscBool row_identity,col_identity; 236863b91edcSBarry Smith 23693a40ed3dSBarry Smith PetscFunctionBegin; 2370e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23711df811f5SHong Zhang 2372b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2373b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2374a871dcd8SBarry Smith 237563b91edcSBarry Smith outA = inA; 2376d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2377f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2378f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 23792205254eSKarl Rupp 2380c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 23816bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 23822205254eSKarl Rupp 2383c3122656SLisandro Dalcin a->row = row; 23842205254eSKarl Rupp 2385c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 23866bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 23872205254eSKarl Rupp 2388c3122656SLisandro Dalcin a->col = col; 238963b91edcSBarry Smith 239036db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 23916bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 23924c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 23933bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2394f0ec6fceSSatish Balay 239594a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2396854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 23973bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 239894a9d846SBarry Smith } 239963b91edcSBarry Smith 2400f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2401137fb511SHong Zhang if (row_identity && col_identity) { 2402ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2403137fb511SHong Zhang } else { 2404719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2405137fb511SHong Zhang } 24063a40ed3dSBarry Smith PetscFunctionReturn(0); 2407a871dcd8SBarry Smith } 2408a871dcd8SBarry Smith 2409f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2410f0b747eeSBarry Smith { 2411f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2412f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2413efee365bSSatish Balay PetscErrorCode ierr; 2414c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 24153a40ed3dSBarry Smith 24163a40ed3dSBarry Smith PetscFunctionBegin; 2417c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 24188b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2419efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2420acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 24213a40ed3dSBarry Smith PetscFunctionReturn(0); 2422f0b747eeSBarry Smith } 2423f0b747eeSBarry Smith 24245c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj) 242516b64355SHong Zhang { 242616b64355SHong Zhang PetscErrorCode ierr; 242716b64355SHong Zhang PetscInt i; 242816b64355SHong Zhang 242916b64355SHong Zhang PetscFunctionBegin; 243016b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 243116b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 243216b64355SHong Zhang 243316b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 243416b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 243516b64355SHong Zhang } 243616b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 243716b64355SHong Zhang 243816b64355SHong Zhang if (submatj->rbuf1) { 243916b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 244016b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 244116b64355SHong Zhang } 244216b64355SHong Zhang 244316b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 244416b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 244516b64355SHong Zhang } 244616b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 244716b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 244816b64355SHong Zhang } 244916b64355SHong Zhang 245016b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 245116b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 245216b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 245316b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 245416b64355SHong Zhang #else 245516b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 245616b64355SHong Zhang #endif 245716b64355SHong Zhang 245816b64355SHong Zhang if (!submatj->allcolumns) { 245916b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 246016b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 246116b64355SHong Zhang #else 246216b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 246316b64355SHong Zhang #endif 246416b64355SHong Zhang } 246516b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 246616b64355SHong Zhang 246716b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 246816b64355SHong Zhang PetscFunctionReturn(0); 246916b64355SHong Zhang } 247016b64355SHong Zhang 247116b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C) 247216b64355SHong Zhang { 247316b64355SHong Zhang PetscErrorCode ierr; 247416b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 24755c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 247616b64355SHong Zhang 247716b64355SHong Zhang PetscFunctionBegin; 247816b64355SHong Zhang ierr = submatj->destroy(C);CHKERRQ(ierr); 2479e69d178cSHong Zhang ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr); 248016b64355SHong Zhang PetscFunctionReturn(0); 248116b64355SHong Zhang } 248216b64355SHong Zhang 24837dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2484cddf8d76SBarry Smith { 2485dfbe8321SBarry Smith PetscErrorCode ierr; 248697f1f81fSBarry Smith PetscInt i; 2487cddf8d76SBarry Smith 24883a40ed3dSBarry Smith PetscFunctionBegin; 2489cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2490df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2491cddf8d76SBarry Smith } 2492cddf8d76SBarry Smith 2493cddf8d76SBarry Smith for (i=0; i<n; i++) { 24947dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2495cddf8d76SBarry Smith } 24963a40ed3dSBarry Smith PetscFunctionReturn(0); 2497cddf8d76SBarry Smith } 2498cddf8d76SBarry Smith 249997f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 25004dcbc457SBarry Smith { 2501e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25026849ba73SBarry Smith PetscErrorCode ierr; 25035d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 25045d0c19d7SBarry Smith const PetscInt *idx; 250597f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2506f1af5d2fSBarry Smith PetscBT table; 2507bbd702dbSSatish Balay 25083a40ed3dSBarry Smith PetscFunctionBegin; 2509d0f46423SBarry Smith m = A->rmap->n; 2510e4d965acSSatish Balay ai = a->i; 2511bfeeae90SHong Zhang aj = a->j; 25128a047759SSatish Balay 2513e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 251406763907SSatish Balay 2515854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 251653b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 251706763907SSatish Balay 2518e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2519b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2520e4d965acSSatish Balay isz = 0; 25216831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2522e4d965acSSatish Balay 2523e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25244dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2525b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2526e4d965acSSatish Balay 2527dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2528e4d965acSSatish Balay for (j=0; j<n; ++j) { 25292205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25304dcbc457SBarry Smith } 253106763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25326bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2533e4d965acSSatish Balay 253404a348a9SBarry Smith k = 0; 253504a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 253604a348a9SBarry Smith n = isz; 253706763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2538e4d965acSSatish Balay row = nidx[k]; 2539e4d965acSSatish Balay start = ai[row]; 2540e4d965acSSatish Balay end = ai[row+1]; 254104a348a9SBarry Smith for (l = start; l<end; l++) { 2542efb16452SHong Zhang val = aj[l]; 25432205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2544e4d965acSSatish Balay } 2545e4d965acSSatish Balay } 2546e4d965acSSatish Balay } 254770b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2548e4d965acSSatish Balay } 254994bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2550606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 25513a40ed3dSBarry Smith PetscFunctionReturn(0); 25524dcbc457SBarry Smith } 255317ab2063SBarry Smith 25540513a670SBarry Smith /* -------------------------------------------------------------- */ 2555dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 25560513a670SBarry Smith { 25570513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25586849ba73SBarry Smith PetscErrorCode ierr; 25593b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 25605d0c19d7SBarry Smith const PetscInt *row,*col; 25615d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 256256cd22aeSBarry Smith IS icolp,irowp; 25630298fd71SBarry Smith PetscInt *cwork = NULL; 25640298fd71SBarry Smith PetscScalar *vwork = NULL; 25650513a670SBarry Smith 25663a40ed3dSBarry Smith PetscFunctionBegin; 25674c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 256856cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 25694c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 257056cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 25710513a670SBarry Smith 25720513a670SBarry Smith /* determine lengths of permuted rows */ 2573854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 25742205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2575ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2576f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 257733d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 25787adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2579ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2580606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 25810513a670SBarry Smith 2582785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 25830513a670SBarry Smith for (i=0; i<m; i++) { 258432ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25852205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2586cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 258732ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25880513a670SBarry Smith } 2589606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 25902205254eSKarl Rupp 25913c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 25922205254eSKarl Rupp 25930513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25940513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 259556cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 259656cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 25976bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 25986bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 25993a40ed3dSBarry Smith PetscFunctionReturn(0); 26000513a670SBarry Smith } 26010513a670SBarry Smith 2602dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2603cb5b572fSBarry Smith { 2604dfbe8321SBarry Smith PetscErrorCode ierr; 2605cb5b572fSBarry Smith 2606cb5b572fSBarry Smith PetscFunctionBegin; 260733f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 260833f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2609be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2610be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2611be6bf707SBarry Smith 2612700c5bfcSBarry 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"); 2613d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2614cb5b572fSBarry Smith } else { 2615cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2616cb5b572fSBarry Smith } 2617cb5b572fSBarry Smith PetscFunctionReturn(0); 2618cb5b572fSBarry Smith } 2619cb5b572fSBarry Smith 26204994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2621273d9f13SBarry Smith { 2622dfbe8321SBarry Smith PetscErrorCode ierr; 2623273d9f13SBarry Smith 2624273d9f13SBarry Smith PetscFunctionBegin; 2625ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2626273d9f13SBarry Smith PetscFunctionReturn(0); 2627273d9f13SBarry Smith } 2628273d9f13SBarry Smith 26298c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 26306c0721eeSBarry Smith { 26316c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26326e111a19SKarl Rupp 26336c0721eeSBarry Smith PetscFunctionBegin; 26346c0721eeSBarry Smith *array = a->a; 26356c0721eeSBarry Smith PetscFunctionReturn(0); 26366c0721eeSBarry Smith } 26376c0721eeSBarry Smith 26388c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 26396c0721eeSBarry Smith { 26406c0721eeSBarry Smith PetscFunctionBegin; 26416c0721eeSBarry Smith PetscFunctionReturn(0); 26426c0721eeSBarry Smith } 2643273d9f13SBarry Smith 26448229c054SShri Abhyankar /* 26458229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26468229c054SShri Abhyankar have different nonzero structure. 26478229c054SShri Abhyankar */ 2648b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2649ec7775f6SShri Abhyankar { 2650b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2651ec7775f6SShri Abhyankar 2652ec7775f6SShri Abhyankar PetscFunctionBegin; 2653ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2654ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2655b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2656b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2657b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 26588af7cee1SJed Brown nnz[i] = 0; 26598af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2660b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2661b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 26628af7cee1SJed Brown nnz[i]++; 26638af7cee1SJed Brown } 26648af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2665ec7775f6SShri Abhyankar } 2666ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2667ec7775f6SShri Abhyankar } 2668ec7775f6SShri Abhyankar 2669b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2670b264fe52SHong Zhang { 2671b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2672b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2673b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2674b264fe52SHong Zhang PetscErrorCode ierr; 2675b264fe52SHong Zhang 2676b264fe52SHong Zhang PetscFunctionBegin; 2677b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2678b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2679b264fe52SHong Zhang PetscFunctionReturn(0); 2680b264fe52SHong Zhang } 2681b264fe52SHong Zhang 2682f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2683ac90fabeSBarry Smith { 2684dfbe8321SBarry Smith PetscErrorCode ierr; 2685ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2686c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2687ac90fabeSBarry Smith 2688ac90fabeSBarry Smith PetscFunctionBegin; 2689c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2690ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2691f4df32b1SMatthew Knepley PetscScalar alpha = a; 26928b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2693acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2694a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2695ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2696ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2697ac90fabeSBarry Smith } else { 26988229c054SShri Abhyankar Mat B; 26998229c054SShri Abhyankar PetscInt *nnz; 2700785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2701ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2702bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 27034aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 270433d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2705176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 27068229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2707ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2708ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 270928be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 27108229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2711ac90fabeSBarry Smith } 2712ac90fabeSBarry Smith PetscFunctionReturn(0); 2713ac90fabeSBarry Smith } 2714ac90fabeSBarry Smith 27157087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2716354c94deSBarry Smith { 2717354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2718354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2719354c94deSBarry Smith PetscInt i,nz; 2720354c94deSBarry Smith PetscScalar *a; 2721354c94deSBarry Smith 2722354c94deSBarry Smith PetscFunctionBegin; 2723354c94deSBarry Smith nz = aij->nz; 2724354c94deSBarry Smith a = aij->a; 27252205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2726354c94deSBarry Smith #else 2727354c94deSBarry Smith PetscFunctionBegin; 2728354c94deSBarry Smith #endif 2729354c94deSBarry Smith PetscFunctionReturn(0); 2730354c94deSBarry Smith } 2731354c94deSBarry Smith 2732985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2733e34fafa9SBarry Smith { 2734e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2735e34fafa9SBarry Smith PetscErrorCode ierr; 2736d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2737e34fafa9SBarry Smith PetscReal atmp; 2738985db425SBarry Smith PetscScalar *x; 2739e34fafa9SBarry Smith MatScalar *aa; 2740e34fafa9SBarry Smith 2741e34fafa9SBarry Smith PetscFunctionBegin; 2742e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2743e34fafa9SBarry Smith aa = a->a; 2744e34fafa9SBarry Smith ai = a->i; 2745e34fafa9SBarry Smith aj = a->j; 2746e34fafa9SBarry Smith 2747985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2748e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2749e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2750e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2751e34fafa9SBarry Smith for (i=0; i<m; i++) { 2752e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 27539189402eSHong Zhang x[i] = 0.0; 2754e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2755985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2756985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2757985db425SBarry Smith aa++; aj++; 2758985db425SBarry Smith } 2759985db425SBarry Smith } 2760985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2761985db425SBarry Smith PetscFunctionReturn(0); 2762985db425SBarry Smith } 2763985db425SBarry Smith 2764985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2765985db425SBarry Smith { 2766985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2767985db425SBarry Smith PetscErrorCode ierr; 2768d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2769985db425SBarry Smith PetscScalar *x; 2770985db425SBarry Smith MatScalar *aa; 2771985db425SBarry Smith 2772985db425SBarry Smith PetscFunctionBegin; 2773e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2774985db425SBarry Smith aa = a->a; 2775985db425SBarry Smith ai = a->i; 2776985db425SBarry Smith aj = a->j; 2777985db425SBarry Smith 2778985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2779985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2780985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2781e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2782985db425SBarry Smith for (i=0; i<m; i++) { 2783985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2784d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2785985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2786985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2787985db425SBarry Smith x[i] = 0.0; 2788985db425SBarry Smith if (idx) { 2789985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2790985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2791985db425SBarry Smith if (aj[j] > j) { 2792985db425SBarry Smith idx[i] = j; 2793985db425SBarry Smith break; 2794985db425SBarry Smith } 2795985db425SBarry Smith } 2796985db425SBarry Smith } 2797985db425SBarry Smith } 2798985db425SBarry Smith for (j=0; j<ncols; j++) { 2799985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2800985db425SBarry Smith aa++; aj++; 2801985db425SBarry Smith } 2802985db425SBarry Smith } 2803985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2804985db425SBarry Smith PetscFunctionReturn(0); 2805985db425SBarry Smith } 2806985db425SBarry Smith 2807c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2808c87e5d42SMatthew Knepley { 2809c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2810c87e5d42SMatthew Knepley PetscErrorCode ierr; 2811c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2812c87e5d42SMatthew Knepley PetscReal atmp; 2813c87e5d42SMatthew Knepley PetscScalar *x; 2814c87e5d42SMatthew Knepley MatScalar *aa; 2815c87e5d42SMatthew Knepley 2816c87e5d42SMatthew Knepley PetscFunctionBegin; 2817e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2818c87e5d42SMatthew Knepley aa = a->a; 2819c87e5d42SMatthew Knepley ai = a->i; 2820c87e5d42SMatthew Knepley aj = a->j; 2821c87e5d42SMatthew Knepley 2822c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2823c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2824c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 282560e0710aSBarry 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); 2826c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2827c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2828289a08f5SMatthew Knepley if (ncols) { 2829289a08f5SMatthew Knepley /* Get first nonzero */ 2830289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 2831289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 28322205254eSKarl Rupp if (atmp > 1.0e-12) { 28332205254eSKarl Rupp x[i] = atmp; 28342205254eSKarl Rupp if (idx) idx[i] = aj[j]; 28352205254eSKarl Rupp break; 28362205254eSKarl Rupp } 2837289a08f5SMatthew Knepley } 283812431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2839289a08f5SMatthew Knepley } else { 2840289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2841289a08f5SMatthew Knepley } 2842c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 2843c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2844289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2845c87e5d42SMatthew Knepley aa++; aj++; 2846c87e5d42SMatthew Knepley } 2847c87e5d42SMatthew Knepley } 2848c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2849c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2850c87e5d42SMatthew Knepley } 2851c87e5d42SMatthew Knepley 2852985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2853985db425SBarry Smith { 2854985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2855985db425SBarry Smith PetscErrorCode ierr; 2856d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 2857d9ca1df4SBarry Smith const PetscInt *ai,*aj; 2858985db425SBarry Smith PetscScalar *x; 2859d9ca1df4SBarry Smith const MatScalar *aa; 2860985db425SBarry Smith 2861985db425SBarry Smith PetscFunctionBegin; 2862e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2863985db425SBarry Smith aa = a->a; 2864985db425SBarry Smith ai = a->i; 2865985db425SBarry Smith aj = a->j; 2866985db425SBarry Smith 2867985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2868985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2869985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2870e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2871985db425SBarry Smith for (i=0; i<m; i++) { 2872985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2873d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2874985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2875985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2876985db425SBarry Smith x[i] = 0.0; 2877985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2878985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2879985db425SBarry Smith for (j=0; j<ncols; j++) { 2880985db425SBarry Smith if (aj[j] > j) { 2881985db425SBarry Smith idx[i] = j; 2882985db425SBarry Smith break; 2883985db425SBarry Smith } 2884985db425SBarry Smith } 2885985db425SBarry Smith } 2886985db425SBarry Smith } 2887985db425SBarry Smith for (j=0; j<ncols; j++) { 2888985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2889985db425SBarry Smith aa++; aj++; 2890e34fafa9SBarry Smith } 2891e34fafa9SBarry Smith } 2892e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2893e34fafa9SBarry Smith PetscFunctionReturn(0); 2894e34fafa9SBarry Smith } 2895bbead8a2SBarry Smith 2896bbead8a2SBarry Smith #include <petscblaslapack.h> 2897af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h> 2898bbead8a2SBarry Smith 2899713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2900bbead8a2SBarry Smith { 2901bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2902bbead8a2SBarry Smith PetscErrorCode ierr; 290333d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2904bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2905bbead8a2SBarry Smith PetscReal shift = 0.0; 29061a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 2907bbead8a2SBarry Smith 2908bbead8a2SBarry Smith PetscFunctionBegin; 2909a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 29104a0d0026SBarry Smith if (a->ibdiagvalid) { 29114a0d0026SBarry Smith if (values) *values = a->ibdiag; 29124a0d0026SBarry Smith PetscFunctionReturn(0); 29134a0d0026SBarry Smith } 2914bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2915bbead8a2SBarry Smith if (!a->ibdiag) { 2916785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 29173bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2918bbead8a2SBarry Smith } 2919bbead8a2SBarry Smith diag = a->ibdiag; 2920bbead8a2SBarry Smith if (values) *values = a->ibdiag; 2921bbead8a2SBarry Smith /* factor and invert each block */ 2922bbead8a2SBarry Smith switch (bs) { 2923bbead8a2SBarry Smith case 1: 2924bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2925bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 2926ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 2927ec1892c8SHong Zhang if (allowzeropivot) { 29287b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 29297b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 29307b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 29317b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 29327b6c816cSBarry 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); 2933ec1892c8SHong Zhang } 2934bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 2935bbead8a2SBarry Smith } 2936bbead8a2SBarry Smith break; 2937bbead8a2SBarry Smith case 2: 2938bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2939bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 2940bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 2941a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29427b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 294396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 2944bbead8a2SBarry Smith diag += 4; 2945bbead8a2SBarry Smith } 2946bbead8a2SBarry Smith break; 2947bbead8a2SBarry Smith case 3: 2948bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2949bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 2950bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 2951a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29527b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 295396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 2954bbead8a2SBarry Smith diag += 9; 2955bbead8a2SBarry Smith } 2956bbead8a2SBarry Smith break; 2957bbead8a2SBarry Smith case 4: 2958bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2959bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 2960bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 2961a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29627b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 296396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 2964bbead8a2SBarry Smith diag += 16; 2965bbead8a2SBarry Smith } 2966bbead8a2SBarry Smith break; 2967bbead8a2SBarry Smith case 5: 2968bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2969bbead8a2SBarry 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; 2970bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 2971a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29727b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 297396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 2974bbead8a2SBarry Smith diag += 25; 2975bbead8a2SBarry Smith } 2976bbead8a2SBarry Smith break; 2977bbead8a2SBarry Smith case 6: 2978bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2979bbead8a2SBarry 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; 2980bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 2981a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29827b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 298396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 2984bbead8a2SBarry Smith diag += 36; 2985bbead8a2SBarry Smith } 2986bbead8a2SBarry Smith break; 2987bbead8a2SBarry Smith case 7: 2988bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2989bbead8a2SBarry 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; 2990bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 2991a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29927b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 299396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 2994bbead8a2SBarry Smith diag += 49; 2995bbead8a2SBarry Smith } 2996bbead8a2SBarry Smith break; 2997bbead8a2SBarry Smith default: 2998dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 2999bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3000bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3001bbead8a2SBarry Smith IJ[j] = bs*i + j; 3002bbead8a2SBarry Smith } 3003bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 30045f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 30057b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 300696b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3007bbead8a2SBarry Smith diag += bs2; 3008bbead8a2SBarry Smith } 3009bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3010bbead8a2SBarry Smith } 3011bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3012bbead8a2SBarry Smith PetscFunctionReturn(0); 3013bbead8a2SBarry Smith } 3014bbead8a2SBarry Smith 301573a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 301673a71a0fSBarry Smith { 301773a71a0fSBarry Smith PetscErrorCode ierr; 301873a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 301973a71a0fSBarry Smith PetscScalar a; 302073a71a0fSBarry Smith PetscInt m,n,i,j,col; 302173a71a0fSBarry Smith 302273a71a0fSBarry Smith PetscFunctionBegin; 302373a71a0fSBarry Smith if (!x->assembled) { 302473a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 302573a71a0fSBarry Smith for (i=0; i<m; i++) { 302673a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 302773a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 302873a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 302973a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 303073a71a0fSBarry Smith } 303173a71a0fSBarry Smith } 303273a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 303373a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 303473a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 303573a71a0fSBarry Smith PetscFunctionReturn(0); 303673a71a0fSBarry Smith } 303773a71a0fSBarry Smith 30387d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a) 30397d68702bSBarry Smith { 30407d68702bSBarry Smith PetscErrorCode ierr; 30417d68702bSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)Y->data; 30427d68702bSBarry Smith 30437d68702bSBarry Smith PetscFunctionBegin; 30446f33a894SBarry Smith if (!Y->preallocated || !aij->nz) { 30457d68702bSBarry Smith ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr); 30467d68702bSBarry Smith } 30477d68702bSBarry Smith ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 30487d68702bSBarry Smith PetscFunctionReturn(0); 30497d68702bSBarry Smith } 30507d68702bSBarry Smith 3051682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 30520a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3053cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3054cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3055cb5b572fSBarry Smith MatMult_SeqAIJ, 305697304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 30577c922b88SBarry Smith MatMultTranspose_SeqAIJ, 30587c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3059db4efbfdSBarry Smith 0, 3060db4efbfdSBarry Smith 0, 3061db4efbfdSBarry Smith 0, 3062db4efbfdSBarry Smith /* 10*/ 0, 3063cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3064cb5b572fSBarry Smith 0, 306541f059aeSBarry Smith MatSOR_SeqAIJ, 306617ab2063SBarry Smith MatTranspose_SeqAIJ, 306797304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3068cb5b572fSBarry Smith MatEqual_SeqAIJ, 3069cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3070cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3071cb5b572fSBarry Smith MatNorm_SeqAIJ, 307297304618SKris Buschelman /* 20*/ 0, 3073cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3074cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3075cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3076d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3077db4efbfdSBarry Smith 0, 3078db4efbfdSBarry Smith 0, 3079db4efbfdSBarry Smith 0, 3080db4efbfdSBarry Smith 0, 30814994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3082db4efbfdSBarry Smith 0, 3083db4efbfdSBarry Smith 0, 30848c778c55SBarry Smith 0, 30858c778c55SBarry Smith 0, 3086d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3087cb5b572fSBarry Smith 0, 3088cb5b572fSBarry Smith 0, 3089cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3090cb5b572fSBarry Smith 0, 3091d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 30927dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3093cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3094cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3095cb5b572fSBarry Smith MatCopy_SeqAIJ, 3096d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3097cb5b572fSBarry Smith MatScale_SeqAIJ, 30987d68702bSBarry Smith MatShift_SeqAIJ, 309979299369SBarry Smith MatDiagonalSet_SeqAIJ, 31006e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 310173a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 31023b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 31033b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 31043b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3105a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 310693dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3107b9617806SBarry Smith 0, 31080513a670SBarry Smith 0, 3109cda55fadSBarry Smith MatPermute_SeqAIJ, 3110cda55fadSBarry Smith 0, 3111d519adbfSMatthew Knepley /* 59*/ 0, 3112b9b97703SBarry Smith MatDestroy_SeqAIJ, 3113b9b97703SBarry Smith MatView_SeqAIJ, 3114357abbc8SBarry Smith 0, 3115321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3116321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3117321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3118ee4f033dSBarry Smith 0, 3119ee4f033dSBarry Smith 0, 3120ee4f033dSBarry Smith 0, 3121d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3122c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3123ee4f033dSBarry Smith 0, 3124dcf5cc72SBarry Smith 0, 31252c93a97aSBarry Smith 0, 31262c93a97aSBarry Smith /* 74*/ 0, 31273acb8795SBarry Smith MatFDColoringApply_AIJ, 312897304618SKris Buschelman 0, 312997304618SKris Buschelman 0, 313097304618SKris Buschelman 0, 31316ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 313297304618SKris Buschelman 0, 313397304618SKris Buschelman 0, 313497304618SKris Buschelman 0, 3135bc011b1eSHong Zhang MatLoad_SeqAIJ, 3136d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31371cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31386284ec50SHong Zhang 0, 31396284ec50SHong Zhang 0, 3140bc011b1eSHong Zhang 0, 3141d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 314226be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 314326be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 314465e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 31454a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 314665e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 31476fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 31486fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 31496fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 31502121bac1SHong Zhang 0, 31512121bac1SHong Zhang /* 99*/ 0, 3152609c6c4dSKris Buschelman 0, 3153609c6c4dSKris Buschelman 0, 315487d4246cSBarry Smith MatConjugate_SeqAIJ, 315587d4246cSBarry Smith 0, 3156d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 315799cafbc1SBarry Smith MatRealPart_SeqAIJ, 3158f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3159f5edf698SHong Zhang 0, 31602bebee5dSHong Zhang 0, 3161cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3162985db425SBarry Smith 0, 31632af78befSBarry Smith MatGetRowMin_SeqAIJ, 31642af78befSBarry Smith 0, 3165599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3166d519adbfSMatthew Knepley /*114*/ 0, 3167599ef60dSHong Zhang 0, 31683c2a7987SHong Zhang 0, 3169fe97e370SBarry Smith 0, 3170fbdbba38SShri Abhyankar 0, 3171fbdbba38SShri Abhyankar /*119*/ 0, 3172fbdbba38SShri Abhyankar 0, 3173fbdbba38SShri Abhyankar 0, 317482d44351SHong Zhang 0, 3175b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 31760716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3177bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 317837868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 317937868618SMatthew G Knepley 0, 318037868618SMatthew G Knepley 0, 31815df89d91SHong Zhang /*129*/ 0, 318275648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 318375648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 318475648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3185b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3186b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 31872b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 31882b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 31892b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 31903964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 31913964eb88SJed Brown /*139*/0, 3192f9426fe0SMark Adams 0, 31931919a2e2SJed Brown 0, 31943a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 31959c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 31969c8f2541SHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ 31979e29f15eSvictorle }; 319817ab2063SBarry Smith 31997087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3200bef8e0ddSBarry Smith { 3201bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 320297f1f81fSBarry Smith PetscInt i,nz,n; 3203bef8e0ddSBarry Smith 3204bef8e0ddSBarry Smith PetscFunctionBegin; 3205bef8e0ddSBarry Smith nz = aij->maxnz; 3206d0f46423SBarry Smith n = mat->rmap->n; 3207bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3208bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3209bef8e0ddSBarry Smith } 3210bef8e0ddSBarry Smith aij->nz = nz; 3211bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3212bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3213bef8e0ddSBarry Smith } 3214bef8e0ddSBarry Smith PetscFunctionReturn(0); 3215bef8e0ddSBarry Smith } 3216bef8e0ddSBarry Smith 3217bef8e0ddSBarry Smith /*@ 3218bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3219bef8e0ddSBarry Smith in the matrix. 3220bef8e0ddSBarry Smith 3221bef8e0ddSBarry Smith Input Parameters: 3222bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3223bef8e0ddSBarry Smith - indices - the column indices 3224bef8e0ddSBarry Smith 322515091d37SBarry Smith Level: advanced 322615091d37SBarry Smith 3227bef8e0ddSBarry Smith Notes: 3228bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3229bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3230bef8e0ddSBarry Smith of the MatSetValues() operation. 3231bef8e0ddSBarry Smith 3232bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3233d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3234bef8e0ddSBarry Smith 3235bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3236bef8e0ddSBarry Smith 3237b9617806SBarry Smith The indices should start with zero, not one. 3238b9617806SBarry Smith 3239bef8e0ddSBarry Smith @*/ 32407087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3241bef8e0ddSBarry Smith { 32424ac538c5SBarry Smith PetscErrorCode ierr; 3243bef8e0ddSBarry Smith 3244bef8e0ddSBarry Smith PetscFunctionBegin; 32450700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 32464482741eSBarry Smith PetscValidPointer(indices,2); 32474ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3248bef8e0ddSBarry Smith PetscFunctionReturn(0); 3249bef8e0ddSBarry Smith } 3250bef8e0ddSBarry Smith 3251be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3252be6bf707SBarry Smith 32537087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3254be6bf707SBarry Smith { 3255be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 32566849ba73SBarry Smith PetscErrorCode ierr; 3257d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3258be6bf707SBarry Smith 3259be6bf707SBarry Smith PetscFunctionBegin; 3260169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3261be6bf707SBarry Smith 3262be6bf707SBarry Smith /* allocate space for values if not already there */ 3263be6bf707SBarry Smith if (!aij->saved_values) { 3264854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 32653bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3266be6bf707SBarry Smith } 3267be6bf707SBarry Smith 3268be6bf707SBarry Smith /* copy values over */ 326987828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3270be6bf707SBarry Smith PetscFunctionReturn(0); 3271be6bf707SBarry Smith } 3272be6bf707SBarry Smith 3273be6bf707SBarry Smith /*@ 3274be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3275be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3276be6bf707SBarry Smith nonlinear portion. 3277be6bf707SBarry Smith 3278be6bf707SBarry Smith Collect on Mat 3279be6bf707SBarry Smith 3280be6bf707SBarry Smith Input Parameters: 32810e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3282be6bf707SBarry Smith 328315091d37SBarry Smith Level: advanced 328415091d37SBarry Smith 3285be6bf707SBarry Smith Common Usage, with SNESSolve(): 3286be6bf707SBarry Smith $ Create Jacobian matrix 3287be6bf707SBarry Smith $ Set linear terms into matrix 3288be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3289be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3290be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3291512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3292be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3293be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3294be6bf707SBarry Smith $ In your Jacobian routine 3295be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3296be6bf707SBarry Smith $ Set nonlinear terms in matrix 3297be6bf707SBarry Smith 3298be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3299be6bf707SBarry Smith $ // build linear portion of Jacobian 3300512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3301be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3302be6bf707SBarry Smith $ loop over nonlinear iterations 3303be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3304be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3305be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3306be6bf707SBarry Smith $ Solve linear system with Jacobian 3307be6bf707SBarry Smith $ endloop 3308be6bf707SBarry Smith 3309be6bf707SBarry Smith Notes: 3310be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3311512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3312be6bf707SBarry Smith calling this routine. 3313be6bf707SBarry Smith 33140c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33150c468ba9SBarry Smith and does not allocated additional space. 33160c468ba9SBarry Smith 3317be6bf707SBarry Smith .seealso: MatRetrieveValues() 3318be6bf707SBarry Smith 3319be6bf707SBarry Smith @*/ 33207087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3321be6bf707SBarry Smith { 33224ac538c5SBarry Smith PetscErrorCode ierr; 3323be6bf707SBarry Smith 3324be6bf707SBarry Smith PetscFunctionBegin; 33250700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3326e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3327e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33284ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3329be6bf707SBarry Smith PetscFunctionReturn(0); 3330be6bf707SBarry Smith } 3331be6bf707SBarry Smith 33327087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3333be6bf707SBarry Smith { 3334be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33356849ba73SBarry Smith PetscErrorCode ierr; 3336d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3337be6bf707SBarry Smith 3338be6bf707SBarry Smith PetscFunctionBegin; 3339169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3340f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3341be6bf707SBarry Smith /* copy values over */ 334287828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3343be6bf707SBarry Smith PetscFunctionReturn(0); 3344be6bf707SBarry Smith } 3345be6bf707SBarry Smith 3346be6bf707SBarry Smith /*@ 3347be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3348be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3349be6bf707SBarry Smith nonlinear portion. 3350be6bf707SBarry Smith 3351be6bf707SBarry Smith Collect on Mat 3352be6bf707SBarry Smith 3353be6bf707SBarry Smith Input Parameters: 3354386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3355be6bf707SBarry Smith 335615091d37SBarry Smith Level: advanced 335715091d37SBarry Smith 3358be6bf707SBarry Smith .seealso: MatStoreValues() 3359be6bf707SBarry Smith 3360be6bf707SBarry Smith @*/ 33617087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3362be6bf707SBarry Smith { 33634ac538c5SBarry Smith PetscErrorCode ierr; 3364be6bf707SBarry Smith 3365be6bf707SBarry Smith PetscFunctionBegin; 33660700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3367e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3368e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33694ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3370be6bf707SBarry Smith PetscFunctionReturn(0); 3371be6bf707SBarry Smith } 3372be6bf707SBarry Smith 3373f83d6046SBarry Smith 3374be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 337517ab2063SBarry Smith /*@C 3376682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 33770d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 33786e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 337951c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 33802bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 338117ab2063SBarry Smith 3382db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3383db81eaa0SLois Curfman McInnes 338417ab2063SBarry Smith Input Parameters: 3385db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 338617ab2063SBarry Smith . m - number of rows 338717ab2063SBarry Smith . n - number of columns 338817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 338951c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 33900298fd71SBarry Smith (possibly different for each row) or NULL 339117ab2063SBarry Smith 339217ab2063SBarry Smith Output Parameter: 3393416022c9SBarry Smith . A - the matrix 339417ab2063SBarry Smith 3395175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3396ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3397175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3398175b88e8SBarry Smith 3399b259b22eSLois Curfman McInnes Notes: 340049a6f317SBarry Smith If nnz is given then nz is ignored 340149a6f317SBarry Smith 340217ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 340317ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 34040002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 340544cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 340617ab2063SBarry Smith 340717ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34080298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 34093d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 34106da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 341117ab2063SBarry Smith 3412682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 34134fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3414682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34156c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34166c7ebb05SLois Curfman McInnes 34176c7ebb05SLois Curfman McInnes Options Database Keys: 3418698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34199db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 342017ab2063SBarry Smith 3421027ccd11SLois Curfman McInnes Level: intermediate 3422027ccd11SLois Curfman McInnes 342369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 342436db0b34SBarry Smith 342517ab2063SBarry Smith @*/ 34267087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 342717ab2063SBarry Smith { 3428dfbe8321SBarry Smith PetscErrorCode ierr; 34296945ee14SBarry Smith 34303a40ed3dSBarry Smith PetscFunctionBegin; 3431f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3432117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3433c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3434d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3435273d9f13SBarry Smith PetscFunctionReturn(0); 3436273d9f13SBarry Smith } 3437273d9f13SBarry Smith 3438273d9f13SBarry Smith /*@C 3439273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3440273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3441273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3442273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3443273d9f13SBarry Smith 3444273d9f13SBarry Smith Collective on MPI_Comm 3445273d9f13SBarry Smith 3446273d9f13SBarry Smith Input Parameters: 34471c4f3114SJed Brown + B - The matrix 3448273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3449273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34500298fd71SBarry Smith (possibly different for each row) or NULL 3451273d9f13SBarry Smith 3452273d9f13SBarry Smith Notes: 345349a6f317SBarry Smith If nnz is given then nz is ignored 345449a6f317SBarry Smith 3455273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3456273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3457273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3458273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3459273d9f13SBarry Smith 3460273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34610298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3462273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3463273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3464273d9f13SBarry Smith 3465aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3466aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3467aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3468aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3469aa95bbe8SBarry Smith 3470a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3471a96a251dSBarry Smith entries or columns indices 3472a96a251dSBarry Smith 3473273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3474273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3475273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3476273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3477273d9f13SBarry Smith 3478273d9f13SBarry Smith Options Database Keys: 3479698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3480698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3481273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3482273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3483273d9f13SBarry Smith the user still MUST index entries starting at 0! 3484273d9f13SBarry Smith 3485273d9f13SBarry Smith Level: intermediate 3486273d9f13SBarry Smith 348769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3488273d9f13SBarry Smith 3489273d9f13SBarry Smith @*/ 34907087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3491273d9f13SBarry Smith { 34924ac538c5SBarry Smith PetscErrorCode ierr; 3493a23d5eceSKris Buschelman 3494a23d5eceSKris Buschelman PetscFunctionBegin; 34956ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 34966ba663aaSJed Brown PetscValidType(B,1); 34974ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3498a23d5eceSKris Buschelman PetscFunctionReturn(0); 3499a23d5eceSKris Buschelman } 3500a23d5eceSKris Buschelman 35017087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3502a23d5eceSKris Buschelman { 3503273d9f13SBarry Smith Mat_SeqAIJ *b; 35042576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 35056849ba73SBarry Smith PetscErrorCode ierr; 350697f1f81fSBarry Smith PetscInt i; 3507273d9f13SBarry Smith 3508273d9f13SBarry Smith PetscFunctionBegin; 35092576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3510a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3511c461c341SBarry Smith skipallocation = PETSC_TRUE; 3512c461c341SBarry Smith nz = 0; 3513c461c341SBarry Smith } 3514c461c341SBarry Smith 351526283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 351626283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3517899cda47SBarry Smith 3518435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 351960e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3520b73539f3SBarry Smith if (nnz) { 3521d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 352260e0710aSBarry 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]); 352360e0710aSBarry 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); 3524b73539f3SBarry Smith } 3525b73539f3SBarry Smith } 3526b73539f3SBarry Smith 3527273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35282205254eSKarl Rupp 3529273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3530273d9f13SBarry Smith 3531ab93d7beSBarry Smith if (!skipallocation) { 35322ee49352SLisandro Dalcin if (!b->imax) { 3533dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 35343bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 35352ee49352SLisandro Dalcin } 3536273d9f13SBarry Smith if (!nnz) { 3537435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3538c62bd62aSJed Brown else if (nz < 0) nz = 1; 3539d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3540d0f46423SBarry Smith nz = nz*B->rmap->n; 3541273d9f13SBarry Smith } else { 3542273d9f13SBarry Smith nz = 0; 3543d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3544273d9f13SBarry Smith } 3545ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 35462205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3547ab93d7beSBarry Smith 3548273d9f13SBarry Smith /* allocate the matrix space */ 354953dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 35502ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3551dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 35523bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3553bfeeae90SHong Zhang b->i[0] = 0; 3554d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 35555da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 35565da197adSKris Buschelman } 3557273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3558e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3559e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3560c461c341SBarry Smith } else { 3561e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3562e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3563c461c341SBarry Smith } 3564273d9f13SBarry Smith 3565273d9f13SBarry Smith b->nz = 0; 3566273d9f13SBarry Smith b->maxnz = nz; 3567273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 35682205254eSKarl Rupp if (realalloc) { 35692205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 35702205254eSKarl Rupp } 3571cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3572cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3573273d9f13SBarry Smith PetscFunctionReturn(0); 3574273d9f13SBarry Smith } 3575273d9f13SBarry Smith 357658d36128SBarry Smith /*@ 3577a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3578a1661176SMatthew Knepley 3579a1661176SMatthew Knepley Input Parameters: 3580a1661176SMatthew Knepley + B - the matrix 3581a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3582a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3583a1661176SMatthew Knepley - v - optional values in the matrix 3584a1661176SMatthew Knepley 3585a1661176SMatthew Knepley Level: developer 3586a1661176SMatthew Knepley 358758d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 358858d36128SBarry Smith 3589a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3590a1661176SMatthew Knepley 3591a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3592a1661176SMatthew Knepley @*/ 3593a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3594a1661176SMatthew Knepley { 3595a1661176SMatthew Knepley PetscErrorCode ierr; 3596a1661176SMatthew Knepley 3597a1661176SMatthew Knepley PetscFunctionBegin; 35980700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35996ba663aaSJed Brown PetscValidType(B,1); 36004ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3601a1661176SMatthew Knepley PetscFunctionReturn(0); 3602a1661176SMatthew Knepley } 3603a1661176SMatthew Knepley 36047087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3605a1661176SMatthew Knepley { 3606a1661176SMatthew Knepley PetscInt i; 3607a1661176SMatthew Knepley PetscInt m,n; 3608a1661176SMatthew Knepley PetscInt nz; 3609a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3610a1661176SMatthew Knepley PetscScalar *values; 3611a1661176SMatthew Knepley PetscErrorCode ierr; 3612a1661176SMatthew Knepley 3613a1661176SMatthew Knepley PetscFunctionBegin; 361465e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3615779a8d59SSatish Balay 3616779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3617779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3618779a8d59SSatish Balay 3619779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3620854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 3621a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3622b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3623a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 362465e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3625a1661176SMatthew Knepley nnz[i] = nz; 3626a1661176SMatthew Knepley } 3627a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3628a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3629a1661176SMatthew Knepley 3630a1661176SMatthew Knepley if (v) { 3631a1661176SMatthew Knepley values = (PetscScalar*) v; 3632a1661176SMatthew Knepley } else { 36331795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3634a1661176SMatthew Knepley } 3635a1661176SMatthew Knepley 3636a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3637b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3638b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3639a1661176SMatthew Knepley } 3640a1661176SMatthew Knepley 3641a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3642a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3643a1661176SMatthew Knepley 3644a1661176SMatthew Knepley if (!v) { 3645a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3646a1661176SMatthew Knepley } 36477827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3648a1661176SMatthew Knepley PetscFunctionReturn(0); 3649a1661176SMatthew Knepley } 3650a1661176SMatthew Knepley 3651c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3652af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 3653170fe5c8SBarry Smith 3654170fe5c8SBarry Smith /* 3655170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3656170fe5c8SBarry Smith 3657170fe5c8SBarry Smith n p p 3658170fe5c8SBarry Smith ( ) ( ) ( ) 3659170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3660170fe5c8SBarry Smith ( ) ( ) ( ) 3661170fe5c8SBarry Smith 3662170fe5c8SBarry Smith */ 3663170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3664170fe5c8SBarry Smith { 3665170fe5c8SBarry Smith PetscErrorCode ierr; 3666170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3667170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3668170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 36691de00fd4SBarry Smith PetscInt i,n,m,q,p; 3670170fe5c8SBarry Smith const PetscInt *ii,*idx; 3671170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3672170fe5c8SBarry Smith PetscScalar *c,*c_q; 3673170fe5c8SBarry Smith 3674170fe5c8SBarry Smith PetscFunctionBegin; 3675d0f46423SBarry Smith m = A->rmap->n; 3676d0f46423SBarry Smith n = A->cmap->n; 3677d0f46423SBarry Smith p = B->cmap->n; 3678170fe5c8SBarry Smith a = sub_a->v; 3679170fe5c8SBarry Smith b = sub_b->a; 3680170fe5c8SBarry Smith c = sub_c->v; 3681170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3682170fe5c8SBarry Smith 3683170fe5c8SBarry Smith ii = sub_b->i; 3684170fe5c8SBarry Smith idx = sub_b->j; 3685170fe5c8SBarry Smith for (i=0; i<n; i++) { 3686170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3687170fe5c8SBarry Smith while (q-->0) { 3688170fe5c8SBarry Smith c_q = c + m*(*idx); 3689170fe5c8SBarry Smith a_q = a + m*i; 3690854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3691170fe5c8SBarry Smith idx++; 3692170fe5c8SBarry Smith b++; 3693170fe5c8SBarry Smith } 3694170fe5c8SBarry Smith } 3695170fe5c8SBarry Smith PetscFunctionReturn(0); 3696170fe5c8SBarry Smith } 3697170fe5c8SBarry Smith 3698170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3699170fe5c8SBarry Smith { 3700170fe5c8SBarry Smith PetscErrorCode ierr; 3701d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3702170fe5c8SBarry Smith Mat Cmat; 3703170fe5c8SBarry Smith 3704170fe5c8SBarry Smith PetscFunctionBegin; 370560e0710aSBarry 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); 3706ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3707170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 370833d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 3709170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 37100298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3711d73949e8SHong Zhang 3712d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 37132205254eSKarl Rupp 3714170fe5c8SBarry Smith *C = Cmat; 3715170fe5c8SBarry Smith PetscFunctionReturn(0); 3716170fe5c8SBarry Smith } 3717170fe5c8SBarry Smith 3718170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3719150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3720170fe5c8SBarry Smith { 3721170fe5c8SBarry Smith PetscErrorCode ierr; 3722170fe5c8SBarry Smith 3723170fe5c8SBarry Smith PetscFunctionBegin; 3724170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 37253ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3726170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 37273ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3728170fe5c8SBarry Smith } 37293ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3730170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 37313ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3732170fe5c8SBarry Smith PetscFunctionReturn(0); 3733170fe5c8SBarry Smith } 3734170fe5c8SBarry Smith 3735170fe5c8SBarry Smith 37360bad9183SKris Buschelman /*MC 3737fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 37380bad9183SKris Buschelman based on compressed sparse row format. 37390bad9183SKris Buschelman 37400bad9183SKris Buschelman Options Database Keys: 37410bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 37420bad9183SKris Buschelman 37430bad9183SKris Buschelman Level: beginner 37440bad9183SKris Buschelman 3745f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 37460bad9183SKris Buschelman M*/ 37470bad9183SKris Buschelman 3748ccd284c7SBarry Smith /*MC 3749ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3750ccd284c7SBarry Smith 3751ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3752ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 3753ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 3754ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3755ccd284c7SBarry Smith the above preallocation routines for simplicity. 3756ccd284c7SBarry Smith 3757ccd284c7SBarry Smith Options Database Keys: 3758ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 3759ccd284c7SBarry Smith 3760ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 3761ccd284c7SBarry Smith enough exist. 3762ccd284c7SBarry Smith 3763ccd284c7SBarry Smith Level: beginner 3764ccd284c7SBarry Smith 3765ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 3766ccd284c7SBarry Smith M*/ 3767ccd284c7SBarry Smith 3768ccd284c7SBarry Smith /*MC 3769ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 3770ccd284c7SBarry Smith 3771ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 3772ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 3773ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 3774ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3775ccd284c7SBarry Smith the above preallocation routines for simplicity. 3776ccd284c7SBarry Smith 3777ccd284c7SBarry Smith Options Database Keys: 3778ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 3779ccd284c7SBarry Smith 3780ccd284c7SBarry Smith Level: beginner 3781ccd284c7SBarry Smith 3782ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 3783ccd284c7SBarry Smith M*/ 3784ccd284c7SBarry Smith 3785cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 3786af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3787cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 3788af8000cdSHong Zhang #endif 378963c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 379063c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 37913dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 379263c07aadSStefano Zampini #endif 3793cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 379442c9c57cSBarry Smith 3795b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 379629b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 379729b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3798b3866ffcSBarry Smith #endif 379917667f90SBarry Smith 3800c0c8ee5eSDmitry Karpeev 38018c778c55SBarry Smith /*@C 38028397e458SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored 38038c778c55SBarry Smith 38048c778c55SBarry Smith Not Collective 38058c778c55SBarry Smith 38068c778c55SBarry Smith Input Parameter: 3807579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38088c778c55SBarry Smith 38098c778c55SBarry Smith Output Parameter: 38108c778c55SBarry Smith . array - pointer to the data 38118c778c55SBarry Smith 38128c778c55SBarry Smith Level: intermediate 38138c778c55SBarry Smith 3814774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 38158c778c55SBarry Smith @*/ 38168c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 38178c778c55SBarry Smith { 38188c778c55SBarry Smith PetscErrorCode ierr; 38198c778c55SBarry Smith 38208c778c55SBarry Smith PetscFunctionBegin; 38218c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38228c778c55SBarry Smith PetscFunctionReturn(0); 38238c778c55SBarry Smith } 38248c778c55SBarry Smith 382521e72a00SBarry Smith /*@C 382621e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 382721e72a00SBarry Smith 382821e72a00SBarry Smith Not Collective 382921e72a00SBarry Smith 383021e72a00SBarry Smith Input Parameter: 3831579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 383221e72a00SBarry Smith 383321e72a00SBarry Smith Output Parameter: 383421e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 383521e72a00SBarry Smith 383621e72a00SBarry Smith Level: intermediate 383721e72a00SBarry Smith 383821e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 383921e72a00SBarry Smith @*/ 384021e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 384121e72a00SBarry Smith { 384221e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 384321e72a00SBarry Smith 384421e72a00SBarry Smith PetscFunctionBegin; 384521e72a00SBarry Smith *nz = aij->rmax; 384621e72a00SBarry Smith PetscFunctionReturn(0); 384721e72a00SBarry Smith } 384821e72a00SBarry Smith 38498c778c55SBarry Smith /*@C 3850579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 38518c778c55SBarry Smith 38528c778c55SBarry Smith Not Collective 38538c778c55SBarry Smith 38548c778c55SBarry Smith Input Parameters: 3855579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38568c778c55SBarry Smith . array - pointer to the data 38578c778c55SBarry Smith 38588c778c55SBarry Smith Level: intermediate 38598c778c55SBarry Smith 3860774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 38618c778c55SBarry Smith @*/ 38628c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 38638c778c55SBarry Smith { 38648c778c55SBarry Smith PetscErrorCode ierr; 38658c778c55SBarry Smith 38668c778c55SBarry Smith PetscFunctionBegin; 38678c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38688c778c55SBarry Smith PetscFunctionReturn(0); 38698c778c55SBarry Smith } 38708c778c55SBarry Smith 38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 3872273d9f13SBarry Smith { 3873273d9f13SBarry Smith Mat_SeqAIJ *b; 3874dfbe8321SBarry Smith PetscErrorCode ierr; 387538baddfdSBarry Smith PetscMPIInt size; 3876273d9f13SBarry Smith 3877273d9f13SBarry Smith PetscFunctionBegin; 3878ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 3879e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3880273d9f13SBarry Smith 3881b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 38822205254eSKarl Rupp 3883b0a32e0cSBarry Smith B->data = (void*)b; 38842205254eSKarl Rupp 3885549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 38862205254eSKarl Rupp 3887416022c9SBarry Smith b->row = 0; 3888416022c9SBarry Smith b->col = 0; 388982bf6240SBarry Smith b->icol = 0; 3890b810aeb4SBarry Smith b->reallocs = 0; 389136db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3892f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3893416022c9SBarry Smith b->nonew = 0; 3894416022c9SBarry Smith b->diag = 0; 3895416022c9SBarry Smith b->solve_work = 0; 38962a1b7f2aSHong Zhang B->spptr = 0; 3897be6bf707SBarry Smith b->saved_values = 0; 3898d7f994e1SBarry Smith b->idiag = 0; 389971f1c65dSBarry Smith b->mdiag = 0; 390071f1c65dSBarry Smith b->ssor_work = 0; 390171f1c65dSBarry Smith b->omega = 1.0; 390271f1c65dSBarry Smith b->fshift = 0.0; 390371f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3904bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3905a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 390617ab2063SBarry Smith 390735d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3908bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 3909bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 39108c778c55SBarry Smith 3911b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3912bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3913bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3914b3866ffcSBarry Smith #endif 391517f1a0eaSHong Zhang 3916bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3917bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3918bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3921bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3922bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3923af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3924af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 3925af8000cdSHong Zhang #endif 392663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 392763c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 39283dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 392963c07aadSStefano Zampini #endif 3930b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 3931bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3932bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3933bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3934bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3935bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3936bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3937bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3938bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 39394108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 394017667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 39413a40ed3dSBarry Smith PetscFunctionReturn(0); 394217ab2063SBarry Smith } 394317ab2063SBarry Smith 3944b24902e0SBarry Smith /* 3945b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3946b24902e0SBarry Smith */ 3947ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 394817ab2063SBarry Smith { 3949416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 39506849ba73SBarry Smith PetscErrorCode ierr; 3951d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 395217ab2063SBarry Smith 39533a40ed3dSBarry Smith PetscFunctionBegin; 3954273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3955273d9f13SBarry Smith 3956d5f3da31SBarry Smith C->factortype = A->factortype; 3957416022c9SBarry Smith c->row = 0; 3958416022c9SBarry Smith c->col = 0; 395982bf6240SBarry Smith c->icol = 0; 39606ad4291fSHong Zhang c->reallocs = 0; 396117ab2063SBarry Smith 39626ad4291fSHong Zhang C->assembled = PETSC_TRUE; 396317ab2063SBarry Smith 3964aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3965aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3966eec197d1SBarry Smith 3967dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 39683bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 396917ab2063SBarry Smith for (i=0; i<m; i++) { 3970416022c9SBarry Smith c->imax[i] = a->imax[i]; 3971416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 397217ab2063SBarry Smith } 397317ab2063SBarry Smith 397417ab2063SBarry Smith /* allocate the matrix space */ 3975f77e22a1SHong Zhang if (mallocmatspace) { 3976dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 39773bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 39782205254eSKarl Rupp 3979f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 39802205254eSKarl Rupp 398197f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 398217ab2063SBarry Smith if (m > 0) { 398397f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3984be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3985bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3986be6bf707SBarry Smith } else { 3987bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 398817ab2063SBarry Smith } 398908480c60SBarry Smith } 3990f77e22a1SHong Zhang } 399117ab2063SBarry Smith 39926ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3993416022c9SBarry Smith c->roworiented = a->roworiented; 3994416022c9SBarry Smith c->nonew = a->nonew; 3995416022c9SBarry Smith if (a->diag) { 3996854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 39973bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 399817ab2063SBarry Smith for (i=0; i<m; i++) { 3999416022c9SBarry Smith c->diag[i] = a->diag[i]; 400017ab2063SBarry Smith } 40013a40ed3dSBarry Smith } else c->diag = 0; 40022205254eSKarl Rupp 40036ad4291fSHong Zhang c->solve_work = 0; 40046ad4291fSHong Zhang c->saved_values = 0; 40056ad4291fSHong Zhang c->idiag = 0; 400671f1c65dSBarry Smith c->ssor_work = 0; 4007a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4008e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4009e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 40106ad4291fSHong Zhang 4011893ad86cSHong Zhang c->rmax = a->rmax; 4012416022c9SBarry Smith c->nz = a->nz; 40138ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4014273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4015754ec7b1SSatish Balay 40166ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 40176ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4018cd6b891eSBarry Smith if (a->compressedrow.use) { 40196ad4291fSHong Zhang i = a->compressedrow.nrows; 4020dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 40216ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 40226ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 402327ea64f8SHong Zhang } else { 402427ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 40250298fd71SBarry Smith c->compressedrow.i = NULL; 40260298fd71SBarry Smith c->compressedrow.rindex = NULL; 40276ad4291fSHong Zhang } 4028ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4029e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 40304846f1f5SKris Buschelman 40312205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4032140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 40333a40ed3dSBarry Smith PetscFunctionReturn(0); 403417ab2063SBarry Smith } 403517ab2063SBarry Smith 4036b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4037b24902e0SBarry Smith { 4038b24902e0SBarry Smith PetscErrorCode ierr; 4039b24902e0SBarry Smith 4040b24902e0SBarry Smith PetscFunctionBegin; 4041ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 40424b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4043cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 404433d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4045cfd3f464SBarry Smith } 4046a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4047f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4048b24902e0SBarry Smith PetscFunctionReturn(0); 4049b24902e0SBarry Smith } 4050b24902e0SBarry Smith 4051112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4052fbdbba38SShri Abhyankar { 4053fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4054fbdbba38SShri Abhyankar PetscErrorCode ierr; 4055fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4056fbdbba38SShri Abhyankar int fd; 4057fbdbba38SShri Abhyankar PetscMPIInt size; 4058fbdbba38SShri Abhyankar MPI_Comm comm; 40593059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4060fbdbba38SShri Abhyankar 4061fbdbba38SShri Abhyankar PetscFunctionBegin; 4062c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 4063c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4064fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4065fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4066fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4067bbead8a2SBarry Smith 40680298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 40690298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4070bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 40713059b6faSBarry Smith if (bs < 0) bs = 1; 40723059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4073bbead8a2SBarry Smith 4074fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4075fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4076fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4077fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4078fbdbba38SShri Abhyankar 4079bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4080fbdbba38SShri Abhyankar 4081fbdbba38SShri Abhyankar /* read in row lengths */ 4082785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4083fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4084fbdbba38SShri Abhyankar 4085fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4086fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 408760e0710aSBarry 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); 4088fbdbba38SShri Abhyankar 4089fbdbba38SShri Abhyankar /* set global size if not set already*/ 4090f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4091fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4092aabbc4fbSShri Abhyankar } else { 40939d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4094fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 40954c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 40964c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 40974c5b953cSHong Zhang } 409860e0710aSBarry 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); 4099aabbc4fbSShri Abhyankar } 4100fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4101fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4102fbdbba38SShri Abhyankar 4103fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4104fbdbba38SShri Abhyankar 4105fbdbba38SShri Abhyankar /* read in nonzero values */ 4106fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4107fbdbba38SShri Abhyankar 4108fbdbba38SShri Abhyankar /* set matrix "i" values */ 4109fbdbba38SShri Abhyankar a->i[0] = 0; 4110fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4111fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4112fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4113fbdbba38SShri Abhyankar } 4114fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4115fbdbba38SShri Abhyankar 4116fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4117fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4118fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4119fbdbba38SShri Abhyankar } 4120fbdbba38SShri Abhyankar 4121ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 41227264ac53SSatish Balay { 41237264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4124dfbe8321SBarry Smith PetscErrorCode ierr; 4125eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4126eeffb40dSHong Zhang PetscInt k; 4127eeffb40dSHong Zhang #endif 41287264ac53SSatish Balay 41293a40ed3dSBarry Smith PetscFunctionBegin; 4130bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4131d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4132ca44d042SBarry Smith *flg = PETSC_FALSE; 4133ca44d042SBarry Smith PetscFunctionReturn(0); 4134bcd2baecSBarry Smith } 41357264ac53SSatish Balay 41367264ac53SSatish Balay /* if the a->i are the same */ 4137d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4138abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 41397264ac53SSatish Balay 41407264ac53SSatish Balay /* if a->j are the same */ 414197f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4142abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4143bcd2baecSBarry Smith 4144bcd2baecSBarry Smith /* if a->a are the same */ 4145eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4146eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4147eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4148eeffb40dSHong Zhang *flg = PETSC_FALSE; 41493a40ed3dSBarry Smith PetscFunctionReturn(0); 4150eeffb40dSHong Zhang } 4151eeffb40dSHong Zhang } 4152eeffb40dSHong Zhang #else 4153eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4154eeffb40dSHong Zhang #endif 4155eeffb40dSHong Zhang PetscFunctionReturn(0); 41567264ac53SSatish Balay } 415736db0b34SBarry Smith 415805869f15SSatish Balay /*@ 415936db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 416036db0b34SBarry Smith provided by the user. 416136db0b34SBarry Smith 4162c75a6043SHong Zhang Collective on MPI_Comm 416336db0b34SBarry Smith 416436db0b34SBarry Smith Input Parameters: 416536db0b34SBarry Smith + comm - must be an MPI communicator of size 1 416636db0b34SBarry Smith . m - number of rows 416736db0b34SBarry Smith . n - number of columns 416836db0b34SBarry Smith . i - row indices 416936db0b34SBarry Smith . j - column indices 417036db0b34SBarry Smith - a - matrix values 417136db0b34SBarry Smith 417236db0b34SBarry Smith Output Parameter: 417336db0b34SBarry Smith . mat - the matrix 417436db0b34SBarry Smith 417536db0b34SBarry Smith Level: intermediate 417636db0b34SBarry Smith 417736db0b34SBarry Smith Notes: 41780551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4179292fb18eSBarry Smith once the matrix is destroyed and not before 418036db0b34SBarry Smith 418136db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 418236db0b34SBarry Smith 4183bfeeae90SHong Zhang The i and j indices are 0 based 418436db0b34SBarry Smith 4185a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4186a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 41878eef79e4SBarry Smith as shown 4188a4552177SSatish Balay 41898eef79e4SBarry Smith $ 1 0 0 41908eef79e4SBarry Smith $ 2 0 3 41918eef79e4SBarry Smith $ 4 5 6 41928eef79e4SBarry Smith $ 41938eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 41948eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 41958eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4196a4552177SSatish Balay 41979985e31cSBarry Smith 419869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 419936db0b34SBarry Smith 420036db0b34SBarry Smith @*/ 4201c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 420236db0b34SBarry Smith { 4203dfbe8321SBarry Smith PetscErrorCode ierr; 4204cbcfb4deSHong Zhang PetscInt ii; 420536db0b34SBarry Smith Mat_SeqAIJ *aij; 4206cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4207cbcfb4deSHong Zhang PetscInt jj; 4208cbcfb4deSHong Zhang #endif 420936db0b34SBarry Smith 421036db0b34SBarry Smith PetscFunctionBegin; 421141096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4212f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4213f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4214a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4215ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4216ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4217ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4218dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4219ab93d7beSBarry Smith 422036db0b34SBarry Smith aij->i = i; 422136db0b34SBarry Smith aij->j = j; 422236db0b34SBarry Smith aij->a = a; 422336db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 422436db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4225e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4226e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 422736db0b34SBarry Smith 422836db0b34SBarry Smith for (ii=0; ii<m; ii++) { 422936db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 42302515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 423160e0710aSBarry 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]); 42329985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4233e32f2f54SBarry 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); 4234e32f2f54SBarry 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); 42359985e31cSBarry Smith } 423636db0b34SBarry Smith #endif 423736db0b34SBarry Smith } 42382515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 423936db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 424060e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 424160e0710aSBarry 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]); 424236db0b34SBarry Smith } 424336db0b34SBarry Smith #endif 424436db0b34SBarry Smith 4245b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4246b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 424736db0b34SBarry Smith PetscFunctionReturn(0); 424836db0b34SBarry Smith } 424980ef6e79SMatthew G Knepley /*@C 4250d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 42518a0b0e6bSVictor Minden provided by the user. 42528a0b0e6bSVictor Minden 42538a0b0e6bSVictor Minden Collective on MPI_Comm 42548a0b0e6bSVictor Minden 42558a0b0e6bSVictor Minden Input Parameters: 42568a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 42578a0b0e6bSVictor Minden . m - number of rows 42588a0b0e6bSVictor Minden . n - number of columns 42598a0b0e6bSVictor Minden . i - row indices 42608a0b0e6bSVictor Minden . j - column indices 42611230e6d1SVictor Minden . a - matrix values 42621230e6d1SVictor Minden . nz - number of nonzeros 42631230e6d1SVictor Minden - idx - 0 or 1 based 42648a0b0e6bSVictor Minden 42658a0b0e6bSVictor Minden Output Parameter: 42668a0b0e6bSVictor Minden . mat - the matrix 42678a0b0e6bSVictor Minden 42688a0b0e6bSVictor Minden Level: intermediate 42698a0b0e6bSVictor Minden 42708a0b0e6bSVictor Minden Notes: 42718a0b0e6bSVictor Minden The i and j indices are 0 based 42728a0b0e6bSVictor Minden 42738a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 42748a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 42758a0b0e6bSVictor Minden as shown: 42768a0b0e6bSVictor Minden 42778a0b0e6bSVictor Minden 1 0 0 42788a0b0e6bSVictor Minden 2 0 3 42798a0b0e6bSVictor Minden 4 5 6 42808a0b0e6bSVictor Minden 42818a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 42828a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 42838a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 42848a0b0e6bSVictor Minden 42858a0b0e6bSVictor Minden 428669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 42878a0b0e6bSVictor Minden 42888a0b0e6bSVictor Minden @*/ 4289c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 42908a0b0e6bSVictor Minden { 42918a0b0e6bSVictor Minden PetscErrorCode ierr; 4292d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 42938a0b0e6bSVictor Minden 42948a0b0e6bSVictor Minden 42958a0b0e6bSVictor Minden PetscFunctionBegin; 42961795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 42971230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4298c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 42991230e6d1SVictor Minden } 43008a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 43018a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 43028a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 43031230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 43041230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 43051230e6d1SVictor Minden if (idx) { 43061230e6d1SVictor Minden row = i[ii] - 1; 43071230e6d1SVictor Minden col = j[ii] - 1; 43081230e6d1SVictor Minden } else { 43091230e6d1SVictor Minden row = i[ii]; 43101230e6d1SVictor Minden col = j[ii]; 43118a0b0e6bSVictor Minden } 43121230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 43138a0b0e6bSVictor Minden } 43148a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43158a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4316d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 43178a0b0e6bSVictor Minden PetscFunctionReturn(0); 43188a0b0e6bSVictor Minden } 431936db0b34SBarry Smith 4320acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4321acf2f550SJed Brown { 4322acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4323acf2f550SJed Brown PetscErrorCode ierr; 4324acf2f550SJed Brown 4325acf2f550SJed Brown PetscFunctionBegin; 4326acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4327acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 43282205254eSKarl Rupp 4329acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4330acf2f550SJed Brown PetscFunctionReturn(0); 4331acf2f550SJed Brown } 4332acf2f550SJed Brown 43339c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 43349c8f2541SHong Zhang { 43359c8f2541SHong Zhang PetscErrorCode ierr; 43368761c3d6SHong Zhang PetscMPIInt size; 43379c8f2541SHong Zhang 43389c8f2541SHong Zhang PetscFunctionBegin; 43398761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 43408761c3d6SHong Zhang if (size == 1 && scall == MAT_REUSE_MATRIX) { 43418761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 43428761c3d6SHong Zhang } else { 43439c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 43448761c3d6SHong Zhang } 43459c8f2541SHong Zhang PetscFunctionReturn(0); 43469c8f2541SHong Zhang } 43479c8f2541SHong Zhang 434881824310SBarry Smith /* 434953dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 435053dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 435153dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 435253dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 435353dd7562SDmitry Karpeev */ 435453dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 435553dd7562SDmitry Karpeev { 435653dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 435753dd7562SDmitry Karpeev PetscErrorCode ierr; 435853dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 435953dd7562SDmitry Karpeev PetscBool seqaij; 436053dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 436153dd7562SDmitry Karpeev PetscScalar v; 436253dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 436353dd7562SDmitry Karpeev 436453dd7562SDmitry Karpeev PetscFunctionBegin; 436553dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 436653dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 436753dd7562SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 436853dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 436953dd7562SDmitry Karpeev if (rowemb) { 437053dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 437153dd7562SDmitry 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); 437253dd7562SDmitry Karpeev } else { 43736c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 437453dd7562SDmitry Karpeev } 437553dd7562SDmitry Karpeev if (colemb) { 437653dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 437753dd7562SDmitry 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); 437853dd7562SDmitry Karpeev } else { 437953dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 438053dd7562SDmitry Karpeev } 438153dd7562SDmitry Karpeev 438253dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 438353dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 438453dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 438553dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 438653dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 438753dd7562SDmitry Karpeev } 438853dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 438953dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 439053dd7562SDmitry Karpeev } 439153dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 439253dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 439353dd7562SDmitry Karpeev } 439453dd7562SDmitry Karpeev count = 0; 439553dd7562SDmitry Karpeev rowindices = NULL; 439653dd7562SDmitry Karpeev colindices = NULL; 439753dd7562SDmitry Karpeev if (rowemb) { 439853dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 439953dd7562SDmitry Karpeev } 440053dd7562SDmitry Karpeev if (colemb) { 440153dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 440253dd7562SDmitry Karpeev } 440353dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 440453dd7562SDmitry Karpeev PetscInt row; 440553dd7562SDmitry Karpeev row = i; 440653dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 440753dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 440853dd7562SDmitry Karpeev PetscInt col; 440953dd7562SDmitry Karpeev col = Baij->j[count]; 441053dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 441153dd7562SDmitry Karpeev v = Baij->a[count]; 441253dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 441353dd7562SDmitry Karpeev ++count; 441453dd7562SDmitry Karpeev } 441553dd7562SDmitry Karpeev } 441653dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 441753dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 441853dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 441953dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 442053dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 442153dd7562SDmitry Karpeev PetscFunctionReturn(0); 442253dd7562SDmitry Karpeev } 442353dd7562SDmitry Karpeev 442453dd7562SDmitry Karpeev 442553dd7562SDmitry Karpeev /* 442681824310SBarry Smith Special version for direct calls from Fortran 442781824310SBarry Smith */ 4428af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 442981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 443081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 443181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 443281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 443381824310SBarry Smith #endif 443481824310SBarry Smith 443581824310SBarry Smith /* Change these macros so can be used in void function */ 443681824310SBarry Smith #undef CHKERRQ 4437ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 443881824310SBarry Smith #undef SETERRQ2 4439e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 44404994cf47SJed Brown #undef SETERRQ3 44414994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 444281824310SBarry Smith 44438cc058d9SJed 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) 444481824310SBarry Smith { 444581824310SBarry Smith Mat A = *AA; 444681824310SBarry Smith PetscInt m = *mm, n = *nn; 444781824310SBarry Smith InsertMode is = *isis; 444881824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 444981824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 445081824310SBarry Smith PetscInt *imax,*ai,*ailen; 445181824310SBarry Smith PetscErrorCode ierr; 445281824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 445354f21887SBarry Smith MatScalar *ap,value,*aa; 4454ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4455ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 445681824310SBarry Smith 445781824310SBarry Smith PetscFunctionBegin; 44584994cf47SJed Brown MatCheckPreallocated(A,1); 445981824310SBarry Smith imax = a->imax; 446081824310SBarry Smith ai = a->i; 446181824310SBarry Smith ailen = a->ilen; 446281824310SBarry Smith aj = a->j; 446381824310SBarry Smith aa = a->a; 446481824310SBarry Smith 446581824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 446681824310SBarry Smith row = im[k]; 446781824310SBarry Smith if (row < 0) continue; 446881824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4469ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 447081824310SBarry Smith #endif 447181824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 447281824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 447381824310SBarry Smith low = 0; 447481824310SBarry Smith high = nrow; 447581824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 447681824310SBarry Smith if (in[l] < 0) continue; 447781824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4478ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 447981824310SBarry Smith #endif 448081824310SBarry Smith col = in[l]; 44812205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 44822205254eSKarl Rupp else value = v[k + l*m]; 44832205254eSKarl Rupp 448481824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 448581824310SBarry Smith 44862205254eSKarl Rupp if (col <= lastcol) low = 0; 44872205254eSKarl Rupp else high = nrow; 448881824310SBarry Smith lastcol = col; 448981824310SBarry Smith while (high-low > 5) { 449081824310SBarry Smith t = (low+high)/2; 449181824310SBarry Smith if (rp[t] > col) high = t; 449281824310SBarry Smith else low = t; 449381824310SBarry Smith } 449481824310SBarry Smith for (i=low; i<high; i++) { 449581824310SBarry Smith if (rp[i] > col) break; 449681824310SBarry Smith if (rp[i] == col) { 449781824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 449881824310SBarry Smith else ap[i] = value; 449981824310SBarry Smith goto noinsert; 450081824310SBarry Smith } 450181824310SBarry Smith } 450281824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 450381824310SBarry Smith if (nonew == 1) goto noinsert; 4504ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4505fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 450681824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 450781824310SBarry Smith /* shift up all the later entries in this row */ 450881824310SBarry Smith for (ii=N; ii>=i; ii--) { 450981824310SBarry Smith rp[ii+1] = rp[ii]; 451081824310SBarry Smith ap[ii+1] = ap[ii]; 451181824310SBarry Smith } 451281824310SBarry Smith rp[i] = col; 451381824310SBarry Smith ap[i] = value; 4514e56f5c9eSBarry Smith A->nonzerostate++; 451581824310SBarry Smith noinsert:; 451681824310SBarry Smith low = i + 1; 451781824310SBarry Smith } 451881824310SBarry Smith ailen[row] = nrow; 451981824310SBarry Smith } 452081824310SBarry Smith PetscFunctionReturnVoid(); 452181824310SBarry Smith } 45229f7953f8SBarry Smith 4523