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 418bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 41917ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 420416022c9SBarry Smith low = 0; 421c71e6ed7SBarry Smith high = nrow; 42217ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4235ef9f2a5SBarry Smith if (in[l] < 0) continue; 4242515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 425e32f2f54SBarry 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); 4263b2fbd54SBarry Smith #endif 427bfeeae90SHong Zhang col = in[l]; 4284b0e389bSBarry Smith if (roworiented) { 4295ef9f2a5SBarry Smith value = v[l + k*n]; 430bef8e0ddSBarry Smith } else { 4314b0e389bSBarry Smith value = v[k + l*m]; 4324b0e389bSBarry Smith } 43333b2b78bSBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue; 43436db0b34SBarry Smith 4352205254eSKarl Rupp if (col <= lastcol) low = 0; 4362205254eSKarl Rupp else high = nrow; 437e2ee6c50SBarry Smith lastcol = col; 438416022c9SBarry Smith while (high-low > 5) { 439416022c9SBarry Smith t = (low+high)/2; 440416022c9SBarry Smith if (rp[t] > col) high = t; 441416022c9SBarry Smith else low = t; 44217ab2063SBarry Smith } 443416022c9SBarry Smith for (i=low; i<high; i++) { 44417ab2063SBarry Smith if (rp[i] > col) break; 44517ab2063SBarry Smith if (rp[i] == col) { 446416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 44717ab2063SBarry Smith else ap[i] = value; 448e44c0bd4SBarry Smith low = i + 1; 44917ab2063SBarry Smith goto noinsert; 45017ab2063SBarry Smith } 45117ab2063SBarry Smith } 452abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 453c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 454e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 455fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 456c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 457416022c9SBarry Smith /* shift up all the later entries in this row */ 458416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 45917ab2063SBarry Smith rp[ii+1] = rp[ii]; 46017ab2063SBarry Smith ap[ii+1] = ap[ii]; 46117ab2063SBarry Smith } 46217ab2063SBarry Smith rp[i] = col; 46317ab2063SBarry Smith ap[i] = value; 464416022c9SBarry Smith low = i + 1; 465e56f5c9eSBarry Smith A->nonzerostate++; 466e44c0bd4SBarry Smith noinsert:; 46717ab2063SBarry Smith } 46817ab2063SBarry Smith ailen[row] = nrow; 46917ab2063SBarry Smith } 4703a40ed3dSBarry Smith PetscFunctionReturn(0); 47117ab2063SBarry Smith } 47217ab2063SBarry Smith 47381824310SBarry Smith 474a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4757eb43aa7SLois Curfman McInnes { 4767eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 47797f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 47897f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 47954f21887SBarry Smith MatScalar *ap,*aa = a->a; 4807eb43aa7SLois Curfman McInnes 4813a40ed3dSBarry Smith PetscFunctionBegin; 4827eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 4837eb43aa7SLois Curfman McInnes row = im[k]; 484e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 485e32f2f54SBarry 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); 486bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 4877eb43aa7SLois Curfman McInnes nrow = ailen[row]; 4887eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 489e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 490e32f2f54SBarry 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); 491bfeeae90SHong Zhang col = in[l]; 4927eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 4937eb43aa7SLois Curfman McInnes while (high-low > 5) { 4947eb43aa7SLois Curfman McInnes t = (low+high)/2; 4957eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 4967eb43aa7SLois Curfman McInnes else low = t; 4977eb43aa7SLois Curfman McInnes } 4987eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 4997eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5007eb43aa7SLois Curfman McInnes if (rp[i] == col) { 501b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5027eb43aa7SLois Curfman McInnes goto finished; 5037eb43aa7SLois Curfman McInnes } 5047eb43aa7SLois Curfman McInnes } 50597e567efSBarry Smith *v++ = 0.0; 5067eb43aa7SLois Curfman McInnes finished:; 5077eb43aa7SLois Curfman McInnes } 5087eb43aa7SLois Curfman McInnes } 5093a40ed3dSBarry Smith PetscFunctionReturn(0); 5107eb43aa7SLois Curfman McInnes } 5117eb43aa7SLois Curfman McInnes 51217ab2063SBarry Smith 513dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 51417ab2063SBarry Smith { 515416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5166849ba73SBarry Smith PetscErrorCode ierr; 5176f69ff64SBarry Smith PetscInt i,*col_lens; 5186f69ff64SBarry Smith int fd; 519b37d52dbSMark F. Adams FILE *file; 52017ab2063SBarry Smith 5213a40ed3dSBarry Smith PetscFunctionBegin; 522b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 523854ce69bSBarry Smith ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr); 5242205254eSKarl Rupp 5250700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 526d0f46423SBarry Smith col_lens[1] = A->rmap->n; 527d0f46423SBarry Smith col_lens[2] = A->cmap->n; 528416022c9SBarry Smith col_lens[3] = a->nz; 529416022c9SBarry Smith 530416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 531d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 532416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 53317ab2063SBarry Smith } 534d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 535606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 536416022c9SBarry Smith 537416022c9SBarry Smith /* store column indices (zero start index) */ 5386f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 539416022c9SBarry Smith 540416022c9SBarry Smith /* store nonzero values */ 5416f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 542b37d52dbSMark F. Adams 543b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 544b37d52dbSMark F. Adams if (file) { 54533d57670SJed Brown fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs)); 546b37d52dbSMark F. Adams } 5473a40ed3dSBarry Smith PetscFunctionReturn(0); 54817ab2063SBarry Smith } 549416022c9SBarry Smith 55009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 551cd155464SBarry Smith 552dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 553416022c9SBarry Smith { 554416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 555dfbe8321SBarry Smith PetscErrorCode ierr; 55660e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 557e060cb09SBarry Smith const char *name; 558f3ef73ceSBarry Smith PetscViewerFormat format; 55917ab2063SBarry Smith 5603a40ed3dSBarry Smith PetscFunctionBegin; 561b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 56271c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 56397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 56460e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 565c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 566d00d2cf4SBarry Smith nofinalvalue = 1; 567d00d2cf4SBarry Smith } 568d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 569d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 57077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 571fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 572fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 573fbfe6fa7SJed Brown #else 57477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 575fbfe6fa7SJed Brown #endif 576b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 57717ab2063SBarry Smith 57817ab2063SBarry Smith for (i=0; i<m; i++) { 57960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 580aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 581a9bf72d8SJed 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); 58217ab2063SBarry Smith #else 58360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 58417ab2063SBarry Smith #endif 58517ab2063SBarry Smith } 58617ab2063SBarry Smith } 587d00d2cf4SBarry Smith if (nofinalvalue) { 588c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 589c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 590c337ccceSJed Brown #else 591d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 592c337ccceSJed Brown #endif 593d00d2cf4SBarry Smith } 594317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 595fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 596d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 59768369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 598cd155464SBarry Smith PetscFunctionReturn(0); 599fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 600d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 60144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 60277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 60360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 604aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 60536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 60660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 60736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 60860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 60936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 61060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6116831982aSBarry Smith } 61244cd7ae7SLois Curfman McInnes #else 61360e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 61444cd7ae7SLois Curfman McInnes #endif 61544cd7ae7SLois Curfman McInnes } 616b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 61744cd7ae7SLois Curfman McInnes } 618d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 619fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 62097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 621d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 622854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 623496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 624496be53dSLois Curfman McInnes sptr[i] = nzd+1; 62560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 626496be53dSLois Curfman McInnes if (a->j[j] >= i) { 627aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 62836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 629496be53dSLois Curfman McInnes #else 630496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 631496be53dSLois Curfman McInnes #endif 632496be53dSLois Curfman McInnes } 633496be53dSLois Curfman McInnes } 634496be53dSLois Curfman McInnes } 6352e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 63677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 6372e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 6382205254eSKarl Rupp if (i+4<m) { 6392205254eSKarl 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); 6402205254eSKarl Rupp } else if (i+3<m) { 6412205254eSKarl 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); 6422205254eSKarl Rupp } else if (i+2<m) { 6432205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6442205254eSKarl Rupp } else if (i+1<m) { 6452205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6462205254eSKarl Rupp } else if (i<m) { 6472205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6482205254eSKarl Rupp } else { 6492205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6502205254eSKarl Rupp } 651496be53dSLois Curfman McInnes } 652b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 653606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 654496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 65560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 65677431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 657496be53dSLois Curfman McInnes } 658b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 659496be53dSLois Curfman McInnes } 660b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 661496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 66260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 663496be53dSLois Curfman McInnes if (a->j[j] >= i) { 664aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 66536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 66660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6676831982aSBarry Smith } 668496be53dSLois Curfman McInnes #else 66960e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 670496be53dSLois Curfman McInnes #endif 671496be53dSLois Curfman McInnes } 672496be53dSLois Curfman McInnes } 673b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 674496be53dSLois Curfman McInnes } 675d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 676fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 67797f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 67887828ca2SBarry Smith PetscScalar value; 67968f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 68068f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 68168f1ed48SBarry Smith 68268f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 68368f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 68468f1ed48SBarry Smith realonly = PETSC_FALSE; 68568f1ed48SBarry Smith break; 68668f1ed48SBarry Smith } 68768f1ed48SBarry Smith } 68868f1ed48SBarry Smith #endif 68902594712SBarry Smith 690d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 69102594712SBarry Smith for (i=0; i<m; i++) { 69202594712SBarry Smith jcnt = 0; 693d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 694e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 69502594712SBarry Smith value = a->a[cnt++]; 696e24b481bSBarry Smith jcnt++; 69702594712SBarry Smith } else { 69802594712SBarry Smith value = 0.0; 69902594712SBarry Smith } 700aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70168f1ed48SBarry Smith if (realonly) { 70260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 70368f1ed48SBarry Smith } else { 70460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 70568f1ed48SBarry Smith } 70602594712SBarry Smith #else 70760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 70802594712SBarry Smith #endif 70902594712SBarry Smith } 710b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 71102594712SBarry Smith } 712d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7133c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 714150b93efSMatthew G. Knepley PetscInt fshift=1; 715d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7163c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 71719303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 7183c215bfdSMatthew Knepley #else 71919303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 7203c215bfdSMatthew Knepley #endif 721d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 7223c215bfdSMatthew Knepley for (i=0; i<m; i++) { 72360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 7243c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 725a9a0e077SKarl 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); 7263c215bfdSMatthew Knepley #else 727150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 7283c215bfdSMatthew Knepley #endif 7293c215bfdSMatthew Knepley } 7303c215bfdSMatthew Knepley } 731d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7323a40ed3dSBarry Smith } else { 733d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 734d5f3da31SBarry Smith if (A->factortype) { 73516cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 73616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 73716cd7e1dSShri Abhyankar /* L part */ 73860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 73916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 74016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 74160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 74216cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7436712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 74416cd7e1dSShri Abhyankar } else { 74560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 74616cd7e1dSShri Abhyankar } 74716cd7e1dSShri Abhyankar #else 74860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 74916cd7e1dSShri Abhyankar #endif 75016cd7e1dSShri Abhyankar } 75116cd7e1dSShri Abhyankar /* diagonal */ 75216cd7e1dSShri Abhyankar j = a->diag[i]; 75316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 75416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 75560e0710aSBarry 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); 75616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7576712e2f1SBarry 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); 75816cd7e1dSShri Abhyankar } else { 75960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 76016cd7e1dSShri Abhyankar } 76116cd7e1dSShri Abhyankar #else 76260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 76316cd7e1dSShri Abhyankar #endif 76416cd7e1dSShri Abhyankar 76516cd7e1dSShri Abhyankar /* U part */ 76660e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 76716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 76816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 76960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 77016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 77122ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 77216cd7e1dSShri Abhyankar } else { 77360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 77416cd7e1dSShri Abhyankar } 77516cd7e1dSShri Abhyankar #else 77660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 77716cd7e1dSShri Abhyankar #endif 77816cd7e1dSShri Abhyankar } 77916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 78016cd7e1dSShri Abhyankar } 78116cd7e1dSShri Abhyankar } else { 78217ab2063SBarry Smith for (i=0; i<m; i++) { 78377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 78460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 785aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 78636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 78760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 78836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 78960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7903a40ed3dSBarry Smith } else { 79160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 79217ab2063SBarry Smith } 79317ab2063SBarry Smith #else 79460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 79517ab2063SBarry Smith #endif 79617ab2063SBarry Smith } 797b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 79817ab2063SBarry Smith } 79916cd7e1dSShri Abhyankar } 800d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 80117ab2063SBarry Smith } 802b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8033a40ed3dSBarry Smith PetscFunctionReturn(0); 804416022c9SBarry Smith } 805416022c9SBarry Smith 8069804daf3SBarry Smith #include <petscdraw.h> 807dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 808416022c9SBarry Smith { 809480ef9eaSBarry Smith Mat A = (Mat) Aa; 810416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 811dfbe8321SBarry Smith PetscErrorCode ierr; 812383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 813383922c3SLisandro Dalcin int color; 814b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 815b0a32e0cSBarry Smith PetscViewer viewer; 816f3ef73ceSBarry Smith PetscViewerFormat format; 817cddf8d76SBarry Smith 8183a40ed3dSBarry Smith PetscFunctionBegin; 819480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 820b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 821b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 822383922c3SLisandro Dalcin 823416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 8240513a670SBarry Smith 825fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 826383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8270513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 828b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 829416022c9SBarry Smith for (i=0; i<m; i++) { 830cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 831bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 832bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 83336db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 834b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 835cddf8d76SBarry Smith } 836cddf8d76SBarry Smith } 837b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 838cddf8d76SBarry Smith for (i=0; i<m; i++) { 839cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 840bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 841bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 842cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 843b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 844cddf8d76SBarry Smith } 845cddf8d76SBarry Smith } 846b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 847cddf8d76SBarry Smith for (i=0; i<m; i++) { 848cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 849bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 850bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 85136db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 852b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 853416022c9SBarry Smith } 854416022c9SBarry Smith } 855383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8560513a670SBarry Smith } else { 8570513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8580513a670SBarry Smith /* first determine max of all nonzero values */ 859b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 860383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 861b0a32e0cSBarry Smith PetscDraw popup; 8620513a670SBarry Smith 8630513a670SBarry Smith for (i=0; i<nz; i++) { 8640513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8650513a670SBarry Smith } 866383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 867b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 86845f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 869383922c3SLisandro Dalcin 870383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8710513a670SBarry Smith for (i=0; i<m; i++) { 872383922c3SLisandro Dalcin y_l = m - i - 1.0; 873383922c3SLisandro Dalcin y_r = y_l + 1.0; 874bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 875383922c3SLisandro Dalcin x_l = a->j[j]; 876383922c3SLisandro Dalcin x_r = x_l + 1.0; 877b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 878b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8790513a670SBarry Smith count++; 8800513a670SBarry Smith } 8810513a670SBarry Smith } 882383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8830513a670SBarry Smith } 884480ef9eaSBarry Smith PetscFunctionReturn(0); 885480ef9eaSBarry Smith } 886cddf8d76SBarry Smith 8879804daf3SBarry Smith #include <petscdraw.h> 888dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 889480ef9eaSBarry Smith { 890dfbe8321SBarry Smith PetscErrorCode ierr; 891b0a32e0cSBarry Smith PetscDraw draw; 89236db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 893ace3abfcSBarry Smith PetscBool isnull; 894480ef9eaSBarry Smith 895480ef9eaSBarry Smith PetscFunctionBegin; 896b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 897b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 898480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 899480ef9eaSBarry Smith 900d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 901480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 902b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 903832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 904b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 9050298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 906832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 9073a40ed3dSBarry Smith PetscFunctionReturn(0); 908416022c9SBarry Smith } 909416022c9SBarry Smith 910dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 911416022c9SBarry Smith { 912dfbe8321SBarry Smith PetscErrorCode ierr; 913ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 914416022c9SBarry Smith 9153a40ed3dSBarry Smith PetscFunctionBegin; 916251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 917251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 918251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 919c45a1595SBarry Smith if (iascii) { 9203a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 9210f5bd95cSBarry Smith } else if (isbinary) { 9223a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 9230f5bd95cSBarry Smith } else if (isdraw) { 9243a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 92511aeaf0aSBarry Smith } 9264108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 9273a40ed3dSBarry Smith PetscFunctionReturn(0); 92817ab2063SBarry Smith } 92919bcc07fSBarry Smith 930dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 93117ab2063SBarry Smith { 932416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9336849ba73SBarry Smith PetscErrorCode ierr; 93497f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 935d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 93654f21887SBarry Smith MatScalar *aa = a->a,*ap; 9373447b6efSHong Zhang PetscReal ratio = 0.6; 93817ab2063SBarry Smith 9393a40ed3dSBarry Smith PetscFunctionBegin; 9403a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 94117ab2063SBarry Smith 94243ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 94317ab2063SBarry Smith for (i=1; i<m; i++) { 944416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 94517ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 94694a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 94717ab2063SBarry Smith if (fshift) { 948bfeeae90SHong Zhang ip = aj + ai[i]; 949bfeeae90SHong Zhang ap = aa + ai[i]; 95017ab2063SBarry Smith N = ailen[i]; 95117ab2063SBarry Smith for (j=0; j<N; j++) { 95217ab2063SBarry Smith ip[j-fshift] = ip[j]; 95317ab2063SBarry Smith ap[j-fshift] = ap[j]; 95417ab2063SBarry Smith } 95517ab2063SBarry Smith } 95617ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 95717ab2063SBarry Smith } 95817ab2063SBarry Smith if (m) { 95917ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 96017ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 96117ab2063SBarry Smith } 9627b083b7cSBarry Smith 96317ab2063SBarry Smith /* reset ilen and imax for each row */ 9647b083b7cSBarry Smith a->nonzerorowcnt = 0; 96517ab2063SBarry Smith for (i=0; i<m; i++) { 96617ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 9677b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 96817ab2063SBarry Smith } 969bfeeae90SHong Zhang a->nz = ai[m]; 97065e19b50SBarry 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); 97117ab2063SBarry Smith 97209f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 973d0f46423SBarry 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); 974ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 975ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9762205254eSKarl Rupp 9778e58a170SBarry Smith A->info.mallocs += a->reallocs; 978dd5f02e7SSatish Balay a->reallocs = 0; 9796712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 98036db0b34SBarry Smith a->rmax = rmax; 9814e220ebcSLois Curfman McInnes 98211e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 9834108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 984acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9853a40ed3dSBarry Smith PetscFunctionReturn(0); 98617ab2063SBarry Smith } 98717ab2063SBarry Smith 98899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 98999cafbc1SBarry Smith { 99099cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 99199cafbc1SBarry Smith PetscInt i,nz = a->nz; 99254f21887SBarry Smith MatScalar *aa = a->a; 993acf2f550SJed Brown PetscErrorCode ierr; 99499cafbc1SBarry Smith 99599cafbc1SBarry Smith PetscFunctionBegin; 99699cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 997acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 99899cafbc1SBarry Smith PetscFunctionReturn(0); 99999cafbc1SBarry Smith } 100099cafbc1SBarry Smith 100199cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_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] = PetscImaginaryPart(aa[i]); 1010acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 101199cafbc1SBarry Smith PetscFunctionReturn(0); 101299cafbc1SBarry Smith } 101399cafbc1SBarry Smith 1014dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 101517ab2063SBarry Smith { 1016416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1017dfbe8321SBarry Smith PetscErrorCode ierr; 10183a40ed3dSBarry Smith 10193a40ed3dSBarry Smith PetscFunctionBegin; 1020d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1021acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10223a40ed3dSBarry Smith PetscFunctionReturn(0); 102317ab2063SBarry Smith } 1024416022c9SBarry Smith 1025dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 102617ab2063SBarry Smith { 1027416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1028dfbe8321SBarry Smith PetscErrorCode ierr; 1029d5d45c9bSBarry Smith 10303a40ed3dSBarry Smith PetscFunctionBegin; 1031aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1032d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 103317ab2063SBarry Smith #endif 1034e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10356bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10366bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 103705b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1038d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 103905b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 104071f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 104105b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10426bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 104305b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10446bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1045cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10460b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1047a30b2313SHong Zhang 10484108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1049bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1050901853e0SKris Buschelman 1051dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1052bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1053bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1055bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1058af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1059af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1060af8000cdSHong Zhang #endif 106163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 106263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 10633dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 106463c07aadSStefano Zampini #endif 1065b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1066bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1067bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1068bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1069bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10703a40ed3dSBarry Smith PetscFunctionReturn(0); 107117ab2063SBarry Smith } 107217ab2063SBarry Smith 1073ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 107417ab2063SBarry Smith { 1075416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10764846f1f5SKris Buschelman PetscErrorCode ierr; 10773a40ed3dSBarry Smith 10783a40ed3dSBarry Smith PetscFunctionBegin; 1079a65d3064SKris Buschelman switch (op) { 1080a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 10814e0d8c25SBarry Smith a->roworiented = flg; 1082a65d3064SKris Buschelman break; 1083a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1084a9817697SBarry Smith a->keepnonzeropattern = flg; 1085a65d3064SKris Buschelman break; 1086512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1087512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1088a65d3064SKris Buschelman break; 1089a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 10904e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1091a65d3064SKris Buschelman break; 1092a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 10934e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1094a65d3064SKris Buschelman break; 109528b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 109628b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 109728b2fa4aSMatthew Knepley break; 1098a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 10994e0d8c25SBarry Smith a->ignorezeroentries = flg; 11000df259c2SBarry Smith break; 11013d472b54SHong Zhang case MAT_SPD: 1102b1646e73SJed Brown case MAT_SYMMETRIC: 1103b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1104b1646e73SJed Brown case MAT_HERMITIAN: 1105b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 11065021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11075021d80fSJed Brown break; 11084e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1109a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1110a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1111290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1112a65d3064SKris Buschelman break; 1113b87ac2d8SJed Brown case MAT_USE_INODES: 1114b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1115b87ac2d8SJed Brown break; 1116c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1117c10200c1SHong Zhang A->submat_singleis = flg; 1118c10200c1SHong Zhang break; 1119a65d3064SKris Buschelman default: 1120e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1121a65d3064SKris Buschelman } 11224108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11233a40ed3dSBarry Smith PetscFunctionReturn(0); 112417ab2063SBarry Smith } 112517ab2063SBarry Smith 1126dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 112717ab2063SBarry Smith { 1128416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11296849ba73SBarry Smith PetscErrorCode ierr; 1130d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 113135e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 113217ab2063SBarry Smith 11333a40ed3dSBarry Smith PetscFunctionBegin; 1134d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1135e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 113635e7444dSHong Zhang 1137d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1138d3e70bfaSHong Zhang PetscInt *diag=a->diag; 113935e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11402c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 114135e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 114235e7444dSHong Zhang PetscFunctionReturn(0); 114335e7444dSHong Zhang } 114435e7444dSHong Zhang 11452dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11461ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 114735e7444dSHong Zhang for (i=0; i<n; i++) { 114835e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11492f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 115035e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 115135e7444dSHong Zhang if (aj[j] == i) { 115235e7444dSHong Zhang x[i] = aa[j]; 115317ab2063SBarry Smith break; 115417ab2063SBarry Smith } 115517ab2063SBarry Smith } 115617ab2063SBarry Smith } 11571ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11583a40ed3dSBarry Smith PetscFunctionReturn(0); 115917ab2063SBarry Smith } 116017ab2063SBarry Smith 1161c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1162dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 116317ab2063SBarry Smith { 1164416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1165d9ca1df4SBarry Smith PetscScalar *y; 1166d9ca1df4SBarry Smith const PetscScalar *x; 1167dfbe8321SBarry Smith PetscErrorCode ierr; 1168d0f46423SBarry Smith PetscInt m = A->rmap->n; 11695c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1170d9ca1df4SBarry Smith const MatScalar *v; 1171a77337e4SBarry Smith PetscScalar alpha; 1172d9ca1df4SBarry Smith PetscInt n,i,j; 1173d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 11743447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1175ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11765c897100SBarry Smith #endif 117717ab2063SBarry Smith 11783a40ed3dSBarry Smith PetscFunctionBegin; 11792e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1180d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 11811ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11825c897100SBarry Smith 11835c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1184bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 11855c897100SBarry Smith #else 11863447b6efSHong Zhang if (usecprow) { 11873447b6efSHong Zhang m = cprow.nrows; 11883447b6efSHong Zhang ii = cprow.i; 11897b2bb3b9SHong Zhang ridx = cprow.rindex; 11903447b6efSHong Zhang } else { 11913447b6efSHong Zhang ii = a->i; 11923447b6efSHong Zhang } 119317ab2063SBarry Smith for (i=0; i<m; i++) { 11943447b6efSHong Zhang idx = a->j + ii[i]; 11953447b6efSHong Zhang v = a->a + ii[i]; 11963447b6efSHong Zhang n = ii[i+1] - ii[i]; 11973447b6efSHong Zhang if (usecprow) { 11987b2bb3b9SHong Zhang alpha = x[ridx[i]]; 11993447b6efSHong Zhang } else { 120017ab2063SBarry Smith alpha = x[i]; 12013447b6efSHong Zhang } 120204fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 120317ab2063SBarry Smith } 12045c897100SBarry Smith #endif 1205dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1206d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12071ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12083a40ed3dSBarry Smith PetscFunctionReturn(0); 120917ab2063SBarry Smith } 121017ab2063SBarry Smith 1211dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12125c897100SBarry Smith { 1213dfbe8321SBarry Smith PetscErrorCode ierr; 12145c897100SBarry Smith 12155c897100SBarry Smith PetscFunctionBegin; 1216170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12175c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12185c897100SBarry Smith PetscFunctionReturn(0); 12195c897100SBarry Smith } 12205c897100SBarry Smith 1221c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 122278b84d54SShri Abhyankar 1223dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 122417ab2063SBarry Smith { 1225416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1226d9fead3dSBarry Smith PetscScalar *y; 122754f21887SBarry Smith const PetscScalar *x; 122854f21887SBarry Smith const MatScalar *aa; 1229dfbe8321SBarry Smith PetscErrorCode ierr; 1230003131ecSBarry Smith PetscInt m=A->rmap->n; 12310298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 12327b083b7cSBarry Smith PetscInt n,i; 1233362ced78SSatish Balay PetscScalar sum; 1234ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 123517ab2063SBarry Smith 1236b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 123797952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1238fee21e36SBarry Smith #endif 1239fee21e36SBarry Smith 12403a40ed3dSBarry Smith PetscFunctionBegin; 12413649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12421ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1243416022c9SBarry Smith ii = a->i; 12444eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 12454f390cb1SBarry Smith ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr); 124697952fefSHong Zhang m = a->compressedrow.nrows; 124797952fefSHong Zhang ii = a->compressedrow.i; 124897952fefSHong Zhang ridx = a->compressedrow.rindex; 124997952fefSHong Zhang for (i=0; i<m; i++) { 125097952fefSHong Zhang n = ii[i+1] - ii[i]; 125197952fefSHong Zhang aj = a->j + ii[i]; 125297952fefSHong Zhang aa = a->a + ii[i]; 125397952fefSHong Zhang sum = 0.0; 1254003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1255003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 125697952fefSHong Zhang y[*ridx++] = sum; 125797952fefSHong Zhang } 125897952fefSHong Zhang } else { /* do not use compressed row format */ 1259b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 12603d3eaba7SBarry Smith aj = a->j; 12613d3eaba7SBarry Smith aa = a->a; 1262b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1263b05257ddSBarry Smith #else 126417ab2063SBarry Smith for (i=0; i<m; i++) { 1265003131ecSBarry Smith n = ii[i+1] - ii[i]; 1266003131ecSBarry Smith aj = a->j + ii[i]; 1267003131ecSBarry Smith aa = a->a + ii[i]; 126817ab2063SBarry Smith sum = 0.0; 1269003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 127017ab2063SBarry Smith y[i] = sum; 127117ab2063SBarry Smith } 12728d195f9aSBarry Smith #endif 1273b05257ddSBarry Smith } 12747b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 12753649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12761ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12773a40ed3dSBarry Smith PetscFunctionReturn(0); 127817ab2063SBarry Smith } 127917ab2063SBarry Smith 1280b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1281b434eb95SMatthew G. Knepley { 1282b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1283b434eb95SMatthew G. Knepley PetscScalar *y; 1284b434eb95SMatthew G. Knepley const PetscScalar *x; 1285b434eb95SMatthew G. Knepley const MatScalar *aa; 1286b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1287b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1288b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1289b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1290b434eb95SMatthew G. Knepley PetscScalar sum; 1291b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1292b434eb95SMatthew G. Knepley 1293b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1294b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1295b434eb95SMatthew G. Knepley #endif 1296b434eb95SMatthew G. Knepley 1297b434eb95SMatthew G. Knepley PetscFunctionBegin; 1298b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1299b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1300b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1301b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1302b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1303b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1304b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1305b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1306b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1307b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1308b434eb95SMatthew G. Knepley sum = 0.0; 1309b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1310b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1311b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1312b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1313b434eb95SMatthew G. Knepley } 1314b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13153d3eaba7SBarry Smith ii = a->i; 1316b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1317b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1318b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1319b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1320b434eb95SMatthew G. Knepley sum = 0.0; 1321b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1322b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1323b434eb95SMatthew G. Knepley y[i] = sum; 1324b434eb95SMatthew G. Knepley } 1325b434eb95SMatthew G. Knepley } 1326b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1327b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1328b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1329b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1330b434eb95SMatthew G. Knepley } 1331b434eb95SMatthew G. Knepley 1332b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1333b434eb95SMatthew G. Knepley { 1334b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1335b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1336b434eb95SMatthew G. Knepley const PetscScalar *x; 1337b434eb95SMatthew G. Knepley const MatScalar *aa; 1338b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1339b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1340b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1341b434eb95SMatthew G. Knepley PetscScalar sum; 1342b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1343b434eb95SMatthew G. Knepley 1344b434eb95SMatthew G. Knepley PetscFunctionBegin; 1345b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1346d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1347b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1348b434eb95SMatthew G. Knepley if (zz != yy) { 1349b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1350b434eb95SMatthew G. Knepley } 1351b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1352b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1353b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1354b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1355b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1356b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1357b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1358b434eb95SMatthew G. Knepley sum = y[*ridx]; 1359b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1360b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1361b434eb95SMatthew G. Knepley } 1362b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13633d3eaba7SBarry Smith ii = a->i; 1364b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1365b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1366b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1367b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1368b434eb95SMatthew G. Knepley sum = y[i]; 1369b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1370b434eb95SMatthew G. Knepley z[i] = sum; 1371b434eb95SMatthew G. Knepley } 1372b434eb95SMatthew G. Knepley } 1373b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1374b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1375d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1376b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1377b434eb95SMatthew G. Knepley } 1378b434eb95SMatthew G. Knepley 1379c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1380dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 138117ab2063SBarry Smith { 1382416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1383f15663dcSBarry Smith PetscScalar *y,*z; 1384f15663dcSBarry Smith const PetscScalar *x; 138554f21887SBarry Smith const MatScalar *aa; 1386dfbe8321SBarry Smith PetscErrorCode ierr; 1387d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1388d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1389362ced78SSatish Balay PetscScalar sum; 1390ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 13919ea0dfa2SSatish Balay 13923a40ed3dSBarry Smith PetscFunctionBegin; 1393f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1394d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 13954eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 13964eb6d288SHong Zhang if (zz != yy) { 13974eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 13984eb6d288SHong Zhang } 139997952fefSHong Zhang m = a->compressedrow.nrows; 140097952fefSHong Zhang ii = a->compressedrow.i; 140197952fefSHong Zhang ridx = a->compressedrow.rindex; 140297952fefSHong Zhang for (i=0; i<m; i++) { 140397952fefSHong Zhang n = ii[i+1] - ii[i]; 140497952fefSHong Zhang aj = a->j + ii[i]; 140597952fefSHong Zhang aa = a->a + ii[i]; 140697952fefSHong Zhang sum = y[*ridx]; 1407f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 140897952fefSHong Zhang z[*ridx++] = sum; 140997952fefSHong Zhang } 141097952fefSHong Zhang } else { /* do not use compressed row format */ 14113d3eaba7SBarry Smith ii = a->i; 1412f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 14133d3eaba7SBarry Smith aj = a->j; 14143d3eaba7SBarry Smith aa = a->a; 1415f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1416f15663dcSBarry Smith #else 141717ab2063SBarry Smith for (i=0; i<m; i++) { 1418f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1419f15663dcSBarry Smith aj = a->j + ii[i]; 1420f15663dcSBarry Smith aa = a->a + ii[i]; 142117ab2063SBarry Smith sum = y[i]; 1422f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 142317ab2063SBarry Smith z[i] = sum; 142417ab2063SBarry Smith } 142502ab625aSSatish Balay #endif 1426f15663dcSBarry Smith } 1427dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1428f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1429d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14308154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14316b375ea7SVictor Minden /* 1432918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1433918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1434918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14356b375ea7SVictor Minden */ 1436918e98c3SVictor Minden #endif 14373a40ed3dSBarry Smith PetscFunctionReturn(0); 143817ab2063SBarry Smith } 143917ab2063SBarry Smith 144017ab2063SBarry Smith /* 144117ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 144217ab2063SBarry Smith */ 1443dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 144417ab2063SBarry Smith { 1445416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14466849ba73SBarry Smith PetscErrorCode ierr; 1447d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 144817ab2063SBarry Smith 14493a40ed3dSBarry Smith PetscFunctionBegin; 145009f38230SBarry Smith if (!a->diag) { 1451785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 14523bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 145309f38230SBarry Smith } 1454d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 145509f38230SBarry Smith a->diag[i] = a->i[i+1]; 1456bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1457bfeeae90SHong Zhang if (a->j[j] == i) { 145809f38230SBarry Smith a->diag[i] = j; 145917ab2063SBarry Smith break; 146017ab2063SBarry Smith } 146117ab2063SBarry Smith } 146217ab2063SBarry Smith } 14633a40ed3dSBarry Smith PetscFunctionReturn(0); 146417ab2063SBarry Smith } 146517ab2063SBarry Smith 1466be5855fcSBarry Smith /* 1467be5855fcSBarry Smith Checks for missing diagonals 1468be5855fcSBarry Smith */ 1469ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1470be5855fcSBarry Smith { 1471be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14727734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1473be5855fcSBarry Smith 1474be5855fcSBarry Smith PetscFunctionBegin; 147509f38230SBarry Smith *missing = PETSC_FALSE; 14767734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 147709f38230SBarry Smith *missing = PETSC_TRUE; 147809f38230SBarry Smith if (d) *d = 0; 1479955c1f14SBarry Smith PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n"); 148009f38230SBarry Smith } else { 1481f1e2ffcdSBarry Smith diag = a->diag; 1482d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 14837734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 148409f38230SBarry Smith *missing = PETSC_TRUE; 148509f38230SBarry Smith if (d) *d = i; 1486955c1f14SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D\n",i); 1487358d2f5dSShri Abhyankar break; 148809f38230SBarry Smith } 1489be5855fcSBarry Smith } 1490be5855fcSBarry Smith } 1491be5855fcSBarry Smith PetscFunctionReturn(0); 1492be5855fcSBarry Smith } 1493be5855fcSBarry Smith 1494422a814eSBarry Smith /* 1495422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1496422a814eSBarry Smith */ 14977087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 149871f1c65dSBarry Smith { 149971f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 150071f1c65dSBarry Smith PetscErrorCode ierr; 1501d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 150254f21887SBarry Smith MatScalar *v = a->a; 150354f21887SBarry Smith PetscScalar *idiag,*mdiag; 150471f1c65dSBarry Smith 150571f1c65dSBarry Smith PetscFunctionBegin; 150671f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 150771f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 150871f1c65dSBarry Smith diag = a->diag; 150971f1c65dSBarry Smith if (!a->idiag) { 1510dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 15113bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 151271f1c65dSBarry Smith v = a->a; 151371f1c65dSBarry Smith } 151471f1c65dSBarry Smith mdiag = a->mdiag; 151571f1c65dSBarry Smith idiag = a->idiag; 151671f1c65dSBarry Smith 1517422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 151871f1c65dSBarry Smith for (i=0; i<m; i++) { 151971f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1520899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1521899639b0SHong Zhang if (PetscRealPart(fshift)) { 1522899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 15237b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 15247b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 15257b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 15267b6c816cSBarry Smith } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1527899639b0SHong Zhang } 152871f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 152971f1c65dSBarry Smith } 153071f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 153171f1c65dSBarry Smith } else { 153271f1c65dSBarry Smith for (i=0; i<m; i++) { 153371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 153471f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 153571f1c65dSBarry Smith } 1536dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 153771f1c65dSBarry Smith } 153871f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 153971f1c65dSBarry Smith PetscFunctionReturn(0); 154071f1c65dSBarry Smith } 154171f1c65dSBarry Smith 1542c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 154341f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 154417ab2063SBarry Smith { 1545416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1546e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 15473d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 154854f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1549dfbe8321SBarry Smith PetscErrorCode ierr; 15503d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 155197f1f81fSBarry Smith const PetscInt *idx,*diag; 155217ab2063SBarry Smith 15533a40ed3dSBarry Smith PetscFunctionBegin; 1554b965ef7fSBarry Smith its = its*lits; 155591723122SBarry Smith 155671f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 155771f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 155871f1c65dSBarry Smith a->fshift = fshift; 155971f1c65dSBarry Smith a->omega = omega; 1560ed480e8bSBarry Smith 156171f1c65dSBarry Smith diag = a->diag; 156271f1c65dSBarry Smith t = a->ssor_work; 1563ed480e8bSBarry Smith idiag = a->idiag; 156471f1c65dSBarry Smith mdiag = a->mdiag; 1565ed480e8bSBarry Smith 15661ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 15673649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1568ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 156917ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 157017ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1571ed480e8bSBarry Smith bs = b; 157217ab2063SBarry Smith for (i=0; i<m; i++) { 157371f1c65dSBarry Smith d = fshift + mdiag[i]; 1574416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1575ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1576ed480e8bSBarry Smith v = a->a + diag[i] + 1; 157717ab2063SBarry Smith sum = b[i]*d/omega; 1578003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 157917ab2063SBarry Smith x[i] = sum; 158017ab2063SBarry Smith } 15811ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 15823649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1583efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 15843a40ed3dSBarry Smith PetscFunctionReturn(0); 158517ab2063SBarry Smith } 1586c783ea89SBarry Smith 15872205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 15882205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 158917ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1590887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 159117ab2063SBarry Smith 159217ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 159317ab2063SBarry Smith 1594887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 159517ab2063SBarry Smith */ 159617ab2063SBarry Smith scale = (2.0/omega) - 1.0; 159717ab2063SBarry Smith 159817ab2063SBarry Smith /* x = (E + U)^{-1} b */ 159917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1600416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1601ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1602ed480e8bSBarry Smith v = a->a + diag[i] + 1; 160317ab2063SBarry Smith sum = b[i]; 1604e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1605ed480e8bSBarry Smith x[i] = sum*idiag[i]; 160617ab2063SBarry Smith } 160717ab2063SBarry Smith 160817ab2063SBarry Smith /* t = b - (2*E - D)x */ 1609416022c9SBarry Smith v = a->a; 16102205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 161117ab2063SBarry Smith 161217ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1613ed480e8bSBarry Smith ts = t; 1614416022c9SBarry Smith diag = a->diag; 161517ab2063SBarry Smith for (i=0; i<m; i++) { 1616416022c9SBarry Smith n = diag[i] - a->i[i]; 1617ed480e8bSBarry Smith idx = a->j + a->i[i]; 1618ed480e8bSBarry Smith v = a->a + a->i[i]; 161917ab2063SBarry Smith sum = t[i]; 1620003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1621ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1622733d66baSBarry Smith /* x = x + t */ 1623733d66baSBarry Smith x[i] += t[i]; 162417ab2063SBarry Smith } 162517ab2063SBarry Smith 1626dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16271ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16283649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16293a40ed3dSBarry Smith PetscFunctionReturn(0); 163017ab2063SBarry Smith } 163117ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 163217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 163317ab2063SBarry Smith for (i=0; i<m; i++) { 1634416022c9SBarry Smith n = diag[i] - a->i[i]; 1635ed480e8bSBarry Smith idx = a->j + a->i[i]; 1636ed480e8bSBarry Smith v = a->a + a->i[i]; 163717ab2063SBarry Smith sum = b[i]; 1638e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16395c99c7daSBarry Smith t[i] = sum; 1640ed480e8bSBarry Smith x[i] = sum*idiag[i]; 164117ab2063SBarry Smith } 16425c99c7daSBarry Smith xb = t; 1643efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16443a40ed3dSBarry Smith } else xb = b; 164517ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 164617ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1647416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1648ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1649ed480e8bSBarry Smith v = a->a + diag[i] + 1; 165017ab2063SBarry Smith sum = xb[i]; 1651e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16525c99c7daSBarry Smith if (xb == b) { 1653ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16545c99c7daSBarry Smith } else { 1655b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 165617ab2063SBarry Smith } 16575c99c7daSBarry Smith } 1658b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 165917ab2063SBarry Smith } 166017ab2063SBarry Smith its--; 166117ab2063SBarry Smith } 166217ab2063SBarry Smith while (its--) { 166317ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 166417ab2063SBarry Smith for (i=0; i<m; i++) { 1665b19a5dc2SMark Adams /* lower */ 1666b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1667ed480e8bSBarry Smith idx = a->j + a->i[i]; 1668ed480e8bSBarry Smith v = a->a + a->i[i]; 166917ab2063SBarry Smith sum = b[i]; 1670e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1671b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1672b19a5dc2SMark Adams /* upper */ 1673b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1674b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1675b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1676b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1677b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 167817ab2063SBarry Smith } 1679b19a5dc2SMark Adams xb = t; 16809f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1681b19a5dc2SMark Adams } else xb = b; 168217ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 168317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1684b19a5dc2SMark Adams sum = xb[i]; 1685b19a5dc2SMark Adams if (xb == b) { 1686b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1687416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1688ed480e8bSBarry Smith idx = a->j + a->i[i]; 1689ed480e8bSBarry Smith v = a->a + a->i[i]; 1690e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1691ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1692b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1693b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1694b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1695b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1696b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1697b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 169817ab2063SBarry Smith } 1699b19a5dc2SMark Adams } 1700b19a5dc2SMark Adams if (xb == b) { 17019f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1702b19a5dc2SMark Adams } else { 1703b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1704b19a5dc2SMark Adams } 170517ab2063SBarry Smith } 170617ab2063SBarry Smith } 17071ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17083649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1709365a8a9eSBarry Smith PetscFunctionReturn(0); 171017ab2063SBarry Smith } 171117ab2063SBarry Smith 17122af78befSBarry Smith 1713dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 171417ab2063SBarry Smith { 1715416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17164e220ebcSLois Curfman McInnes 17173a40ed3dSBarry Smith PetscFunctionBegin; 17184e220ebcSLois Curfman McInnes info->block_size = 1.0; 17194e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17204e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17214e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17224e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17238e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17247adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1725d5f3da31SBarry Smith if (A->factortype) { 17264e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17274e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17284e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17294e220ebcSLois Curfman McInnes } else { 17304e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17314e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17324e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17334e220ebcSLois Curfman McInnes } 17343a40ed3dSBarry Smith PetscFunctionReturn(0); 173517ab2063SBarry Smith } 173617ab2063SBarry Smith 17372b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 173817ab2063SBarry Smith { 1739416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1740c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 17416849ba73SBarry Smith PetscErrorCode ierr; 174297b48c8fSBarry Smith const PetscScalar *xx; 174397b48c8fSBarry Smith PetscScalar *bb; 1744c7da8527SEric Chamberland PetscInt d = 0; 174517ab2063SBarry Smith 17463a40ed3dSBarry Smith PetscFunctionBegin; 174797b48c8fSBarry Smith if (x && b) { 174897b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 174997b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 175097b48c8fSBarry Smith for (i=0; i<N; i++) { 175197b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 175297b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 175397b48c8fSBarry Smith } 175497b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 175597b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 175697b48c8fSBarry Smith } 175797b48c8fSBarry Smith 1758a9817697SBarry Smith if (a->keepnonzeropattern) { 1759f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1760e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1761bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1762f1e2ffcdSBarry Smith } 1763f4df32b1SMatthew Knepley if (diag != 0.0) { 1764c7da8527SEric Chamberland for (i=0; i<N; i++) { 1765c7da8527SEric Chamberland d = rows[i]; 1766c7da8527SEric 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); 1767c7da8527SEric Chamberland } 1768f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1769f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1770f1e2ffcdSBarry Smith } 1771f1e2ffcdSBarry Smith } 1772f1e2ffcdSBarry Smith } else { 1773f4df32b1SMatthew Knepley if (diag != 0.0) { 177417ab2063SBarry Smith for (i=0; i<N; i++) { 1775e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 17767ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1777416022c9SBarry Smith a->ilen[rows[i]] = 1; 1778f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1779bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 17807ae801bdSBarry Smith } else { /* in case row was completely empty */ 1781f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 178217ab2063SBarry Smith } 178317ab2063SBarry Smith } 17843a40ed3dSBarry Smith } else { 178517ab2063SBarry Smith for (i=0; i<N; i++) { 1786e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1787416022c9SBarry Smith a->ilen[rows[i]] = 0; 178817ab2063SBarry Smith } 178917ab2063SBarry Smith } 1790e56f5c9eSBarry Smith A->nonzerostate++; 1791f1e2ffcdSBarry Smith } 179243a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17933a40ed3dSBarry Smith PetscFunctionReturn(0); 179417ab2063SBarry Smith } 179517ab2063SBarry Smith 17966e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 17976e169961SBarry Smith { 17986e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17996e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18006e169961SBarry Smith PetscErrorCode ierr; 18012b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18026e169961SBarry Smith const PetscScalar *xx; 18036e169961SBarry Smith PetscScalar *bb; 18046e169961SBarry Smith 18056e169961SBarry Smith PetscFunctionBegin; 18066e169961SBarry Smith if (x && b) { 18076e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18086e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18092b40b63fSBarry Smith vecs = PETSC_TRUE; 18106e169961SBarry Smith } 18111795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 18126e169961SBarry Smith for (i=0; i<N; i++) { 18136e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18146e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18152205254eSKarl Rupp 18166e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18176e169961SBarry Smith } 18186e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18196e169961SBarry Smith if (!zeroed[i]) { 18206e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18216e169961SBarry Smith if (zeroed[a->j[j]]) { 18222b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18236e169961SBarry Smith a->a[j] = 0.0; 18246e169961SBarry Smith } 18256e169961SBarry Smith } 18262b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18276e169961SBarry Smith } 18286e169961SBarry Smith if (x && b) { 18296e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18306e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18316e169961SBarry Smith } 18326e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18336e169961SBarry Smith if (diag != 0.0) { 18346e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18351d5a398dSstefano_zampini if (missing) { 18361d5a398dSstefano_zampini if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18371d5a398dSstefano_zampini else { 18381d5a398dSstefano_zampini for (i=0; i<N; i++) { 18391d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 18401d5a398dSstefano_zampini } 18411d5a398dSstefano_zampini } 18421d5a398dSstefano_zampini } else { 18436e169961SBarry Smith for (i=0; i<N; i++) { 18446e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18456e169961SBarry Smith } 18466e169961SBarry Smith } 18471d5a398dSstefano_zampini } 18486e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18496e169961SBarry Smith PetscFunctionReturn(0); 18506e169961SBarry Smith } 18516e169961SBarry Smith 1852a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 185317ab2063SBarry Smith { 1854416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 185597f1f81fSBarry Smith PetscInt *itmp; 185617ab2063SBarry Smith 18573a40ed3dSBarry Smith PetscFunctionBegin; 1858e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 185917ab2063SBarry Smith 1860416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1861bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 186217ab2063SBarry Smith if (idx) { 1863bfeeae90SHong Zhang itmp = a->j + a->i[row]; 186426fbe8dcSKarl Rupp if (*nz) *idx = itmp; 186517ab2063SBarry Smith else *idx = 0; 186617ab2063SBarry Smith } 18673a40ed3dSBarry Smith PetscFunctionReturn(0); 186817ab2063SBarry Smith } 186917ab2063SBarry Smith 1870bfeeae90SHong Zhang /* remove this function? */ 1871a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 187217ab2063SBarry Smith { 18733a40ed3dSBarry Smith PetscFunctionBegin; 18743a40ed3dSBarry Smith PetscFunctionReturn(0); 187517ab2063SBarry Smith } 187617ab2063SBarry Smith 1877dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 187817ab2063SBarry Smith { 1879416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 188054f21887SBarry Smith MatScalar *v = a->a; 188136db0b34SBarry Smith PetscReal sum = 0.0; 18826849ba73SBarry Smith PetscErrorCode ierr; 188397f1f81fSBarry Smith PetscInt i,j; 188417ab2063SBarry Smith 18853a40ed3dSBarry Smith PetscFunctionBegin; 188617ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1887570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1888570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 1889570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 1890570b7f6dSBarry Smith #else 1891416022c9SBarry Smith for (i=0; i<a->nz; i++) { 189236db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 189317ab2063SBarry Smith } 18948f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1895570b7f6dSBarry Smith #endif 189651f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 18973a40ed3dSBarry Smith } else if (type == NORM_1) { 189836db0b34SBarry Smith PetscReal *tmp; 189997f1f81fSBarry Smith PetscInt *jj = a->j; 19001795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 1901064f8208SBarry Smith *nrm = 0.0; 1902416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1903bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 190417ab2063SBarry Smith } 1905d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1906064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 190717ab2063SBarry Smith } 1908606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 190951f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 19103a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1911064f8208SBarry Smith *nrm = 0.0; 1912d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1913bfeeae90SHong Zhang v = a->a + a->i[j]; 191417ab2063SBarry Smith sum = 0.0; 1915416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1916cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 191717ab2063SBarry Smith } 1918064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 191917ab2063SBarry Smith } 192051f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 1921f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 19223a40ed3dSBarry Smith PetscFunctionReturn(0); 192317ab2063SBarry Smith } 192417ab2063SBarry Smith 19254e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 19264e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 19274e938277SHong Zhang { 19284e938277SHong Zhang PetscErrorCode ierr; 19294e938277SHong Zhang PetscInt i,j,anzj; 19304e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 19314e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 19324e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 19334e938277SHong Zhang 19344e938277SHong Zhang PetscFunctionBegin; 19354e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 1936854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 1937785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 1938785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 19394e938277SHong Zhang 19404e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 19414e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 194226fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 19434e938277SHong Zhang /* Form ati for csr format of A^T. */ 194426fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 19454e938277SHong Zhang 19464e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 19474e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 19484e938277SHong Zhang 19494e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 19504e938277SHong Zhang for (i=0;i<am;i++) { 19514e938277SHong Zhang anzj = ai[i+1] - ai[i]; 19524e938277SHong Zhang for (j=0;j<anzj;j++) { 19534e938277SHong Zhang atj[atfill[*aj]] = i; 19544e938277SHong Zhang atfill[*aj++] += 1; 19554e938277SHong Zhang } 19564e938277SHong Zhang } 19574e938277SHong Zhang 19584e938277SHong Zhang /* Clean up temporary space and complete requests. */ 19594e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 1960ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 196133d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1962a2f3521dSMark F. Adams 19634e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 19644e938277SHong Zhang b->free_a = PETSC_FALSE; 19654e938277SHong Zhang b->free_ij = PETSC_TRUE; 19664e938277SHong Zhang b->nonew = 0; 19674e938277SHong Zhang PetscFunctionReturn(0); 19684e938277SHong Zhang } 19694e938277SHong Zhang 1970fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 197117ab2063SBarry Smith { 1972416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1973416022c9SBarry Smith Mat C; 19746849ba73SBarry Smith PetscErrorCode ierr; 1975d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 197654f21887SBarry Smith MatScalar *array = a->a; 197717ab2063SBarry Smith 19783a40ed3dSBarry Smith PetscFunctionBegin; 1979cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1980fc4dec0aSBarry Smith 1981cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1982854ce69bSBarry Smith ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr); 1983bfeeae90SHong Zhang 1984bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1985ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1986d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 198733d57670SJed Brown ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 19887adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1989ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1990606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 1991a541d17aSBarry Smith } else { 1992a541d17aSBarry Smith C = *B; 1993a541d17aSBarry Smith } 1994a541d17aSBarry Smith 199517ab2063SBarry Smith for (i=0; i<m; i++) { 199617ab2063SBarry Smith len = ai[i+1]-ai[i]; 199787d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1998b9b97703SBarry Smith array += len; 1999b9b97703SBarry Smith aj += len; 200017ab2063SBarry Smith } 20016d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20026d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 200317ab2063SBarry Smith 2004cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 2005416022c9SBarry Smith *B = C; 200617ab2063SBarry Smith } else { 200728be2f97SBarry Smith ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 200817ab2063SBarry Smith } 20093a40ed3dSBarry Smith PetscFunctionReturn(0); 201017ab2063SBarry Smith } 201117ab2063SBarry Smith 20127087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2013cd0d46ebSvictorle { 20143d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 201554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 201654f21887SBarry Smith MatScalar *va,*vb; 20176849ba73SBarry Smith PetscErrorCode ierr; 201897f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2019cd0d46ebSvictorle 2020cd0d46ebSvictorle PetscFunctionBegin; 2021cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2022cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20235485867bSBarry Smith if (ma!=nb || na!=mb) { 20245485867bSBarry Smith *f = PETSC_FALSE; 20255485867bSBarry Smith PetscFunctionReturn(0); 20265485867bSBarry Smith } 2027cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2028cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2029cd0d46ebSvictorle va = aij->a; vb = bij->a; 2030785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2031785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2032cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2033cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2034cd0d46ebSvictorle 2035cd0d46ebSvictorle *f = PETSC_TRUE; 2036cd0d46ebSvictorle for (i=0; i<ma; i++) { 2037cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 203897f1f81fSBarry Smith PetscInt idc,idr; 20395485867bSBarry Smith PetscScalar vc,vr; 2040cd0d46ebSvictorle /* column/row index/value */ 20415485867bSBarry Smith idc = adx[aptr[i]]; 20425485867bSBarry Smith idr = bdx[bptr[idc]]; 20435485867bSBarry Smith vc = va[aptr[i]]; 20445485867bSBarry Smith vr = vb[bptr[idc]]; 20455485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20465485867bSBarry Smith *f = PETSC_FALSE; 20475485867bSBarry Smith goto done; 2048cd0d46ebSvictorle } else { 20495485867bSBarry Smith aptr[i]++; 20505485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2051cd0d46ebSvictorle } 2052cd0d46ebSvictorle } 2053cd0d46ebSvictorle } 2054cd0d46ebSvictorle done: 2055cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20563aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2057cd0d46ebSvictorle PetscFunctionReturn(0); 2058cd0d46ebSvictorle } 2059cd0d46ebSvictorle 20607087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 20611cbb95d3SBarry Smith { 20623d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 206354f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 206454f21887SBarry Smith MatScalar *va,*vb; 20651cbb95d3SBarry Smith PetscErrorCode ierr; 20661cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 20671cbb95d3SBarry Smith 20681cbb95d3SBarry Smith PetscFunctionBegin; 20691cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 20701cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20711cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 20721cbb95d3SBarry Smith *f = PETSC_FALSE; 20731cbb95d3SBarry Smith PetscFunctionReturn(0); 20741cbb95d3SBarry Smith } 20751cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 20761cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 20771cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2078785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2079785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 20801cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 20811cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 20821cbb95d3SBarry Smith 20831cbb95d3SBarry Smith *f = PETSC_TRUE; 20841cbb95d3SBarry Smith for (i=0; i<ma; i++) { 20851cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 20861cbb95d3SBarry Smith PetscInt idc,idr; 20871cbb95d3SBarry Smith PetscScalar vc,vr; 20881cbb95d3SBarry Smith /* column/row index/value */ 20891cbb95d3SBarry Smith idc = adx[aptr[i]]; 20901cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 20911cbb95d3SBarry Smith vc = va[aptr[i]]; 20921cbb95d3SBarry Smith vr = vb[bptr[idc]]; 20931cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 20941cbb95d3SBarry Smith *f = PETSC_FALSE; 20951cbb95d3SBarry Smith goto done; 20961cbb95d3SBarry Smith } else { 20971cbb95d3SBarry Smith aptr[i]++; 20981cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 20991cbb95d3SBarry Smith } 21001cbb95d3SBarry Smith } 21011cbb95d3SBarry Smith } 21021cbb95d3SBarry Smith done: 21031cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 21041cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 21051cbb95d3SBarry Smith PetscFunctionReturn(0); 21061cbb95d3SBarry Smith } 21071cbb95d3SBarry Smith 2108ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21099e29f15eSvictorle { 2110dfbe8321SBarry Smith PetscErrorCode ierr; 21116e111a19SKarl Rupp 21129e29f15eSvictorle PetscFunctionBegin; 21135485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21149e29f15eSvictorle PetscFunctionReturn(0); 21159e29f15eSvictorle } 21169e29f15eSvictorle 2117ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21181cbb95d3SBarry Smith { 21191cbb95d3SBarry Smith PetscErrorCode ierr; 21206e111a19SKarl Rupp 21211cbb95d3SBarry Smith PetscFunctionBegin; 21221cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21231cbb95d3SBarry Smith PetscFunctionReturn(0); 21241cbb95d3SBarry Smith } 21251cbb95d3SBarry Smith 2126dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 212717ab2063SBarry Smith { 2128416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 212954f21887SBarry Smith PetscScalar *l,*r,x; 213054f21887SBarry Smith MatScalar *v; 2131dfbe8321SBarry Smith PetscErrorCode ierr; 2132d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 213317ab2063SBarry Smith 21343a40ed3dSBarry Smith PetscFunctionBegin; 213517ab2063SBarry Smith if (ll) { 21363ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21373ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2138e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2139e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21401ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2141416022c9SBarry Smith v = a->a; 214217ab2063SBarry Smith for (i=0; i<m; i++) { 214317ab2063SBarry Smith x = l[i]; 2144416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 21452205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 214617ab2063SBarry Smith } 21471ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2148efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 214917ab2063SBarry Smith } 215017ab2063SBarry Smith if (rr) { 2151e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2152e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21531ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2154416022c9SBarry Smith v = a->a; jj = a->j; 21552205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 21561ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2157efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 215817ab2063SBarry Smith } 2159acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 21603a40ed3dSBarry Smith PetscFunctionReturn(0); 216117ab2063SBarry Smith } 216217ab2063SBarry Smith 216397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 216417ab2063SBarry Smith { 2165db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 21666849ba73SBarry Smith PetscErrorCode ierr; 2167d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 216897f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 21695d0c19d7SBarry Smith const PetscInt *irow,*icol; 21705d0c19d7SBarry Smith PetscInt nrows,ncols; 217197f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 217254f21887SBarry Smith MatScalar *a_new,*mat_a; 2173416022c9SBarry Smith Mat C; 2174cdc6f3adSToby Isaac PetscBool stride; 217517ab2063SBarry Smith 21763a40ed3dSBarry Smith PetscFunctionBegin; 217799141d43SSatish Balay 217817ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2179b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2180b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 218117ab2063SBarry Smith 2182251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2183ff718158SBarry Smith if (stride) { 2184ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2185ff718158SBarry Smith } else { 2186ff718158SBarry Smith first = 0; 2187ff718158SBarry Smith step = 0; 2188ff718158SBarry Smith } 2189fee21e36SBarry Smith if (stride && step == 1) { 219002834360SBarry Smith /* special case of contiguous rows */ 2191dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 219202834360SBarry Smith /* loop over new rows determining lens and starting points */ 219302834360SBarry Smith for (i=0; i<nrows; i++) { 2194bfeeae90SHong Zhang kstart = ai[irow[i]]; 2195a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2196a91a9bebSLisandro Dalcin starts[i] = kstart; 219702834360SBarry Smith for (k=kstart; k<kend; k++) { 2198bfeeae90SHong Zhang if (aj[k] >= first) { 219902834360SBarry Smith starts[i] = k; 220002834360SBarry Smith break; 220102834360SBarry Smith } 220202834360SBarry Smith } 2203a2744918SBarry Smith sum = 0; 220402834360SBarry Smith while (k < kend) { 2205bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2206a2744918SBarry Smith sum++; 220702834360SBarry Smith } 2208a2744918SBarry Smith lens[i] = sum; 220902834360SBarry Smith } 221002834360SBarry Smith /* create submatrix */ 2211cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 221297f1f81fSBarry Smith PetscInt n_cols,n_rows; 221308480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2214e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2215d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 221608480c60SBarry Smith C = *B; 22173a40ed3dSBarry Smith } else { 22183bef6203SJed Brown PetscInt rbs,cbs; 2219ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2220f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22213bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22223bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22233bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22247adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2225ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 222608480c60SBarry Smith } 2227db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2228db02288aSLois Curfman McInnes 222902834360SBarry Smith /* loop over rows inserting into submatrix */ 2230db02288aSLois Curfman McInnes a_new = c->a; 2231db02288aSLois Curfman McInnes j_new = c->j; 2232db02288aSLois Curfman McInnes i_new = c->i; 2233bfeeae90SHong Zhang 223402834360SBarry Smith for (i=0; i<nrows; i++) { 2235a2744918SBarry Smith ii = starts[i]; 2236a2744918SBarry Smith lensi = lens[i]; 2237a2744918SBarry Smith for (k=0; k<lensi; k++) { 2238a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 223902834360SBarry Smith } 224087828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2241a2744918SBarry Smith a_new += lensi; 2242a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2243a2744918SBarry Smith c->ilen[i] = lensi; 224402834360SBarry Smith } 22450e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22463a40ed3dSBarry Smith } else { 224702834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22481795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2249854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 22504dcab191SBarry Smith for (i=0; i<ncols; i++) { 22514dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 22524dcab191SBarry 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); 22534dcab191SBarry Smith #endif 22544dcab191SBarry Smith smap[icol[i]] = i+1; 22554dcab191SBarry Smith } 22564dcab191SBarry Smith 225702834360SBarry Smith /* determine lens of each row */ 225802834360SBarry Smith for (i=0; i<nrows; i++) { 2259bfeeae90SHong Zhang kstart = ai[irow[i]]; 226002834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 226102834360SBarry Smith lens[i] = 0; 226202834360SBarry Smith for (k=kstart; k<kend; k++) { 2263bfeeae90SHong Zhang if (smap[aj[k]]) { 226402834360SBarry Smith lens[i]++; 226502834360SBarry Smith } 226602834360SBarry Smith } 226702834360SBarry Smith } 226817ab2063SBarry Smith /* Create and fill new matrix */ 2269a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2270ace3abfcSBarry Smith PetscBool equal; 22710f5bd95cSBarry Smith 227299141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2273e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2274d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2275f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2276d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 227708480c60SBarry Smith C = *B; 22783a40ed3dSBarry Smith } else { 22793bef6203SJed Brown PetscInt rbs,cbs; 2280ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2281f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22823bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22833bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22843bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22857adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2286ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 228708480c60SBarry Smith } 228899141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 228917ab2063SBarry Smith for (i=0; i<nrows; i++) { 229099141d43SSatish Balay row = irow[i]; 2291bfeeae90SHong Zhang kstart = ai[row]; 229299141d43SSatish Balay kend = kstart + a->ilen[row]; 2293bfeeae90SHong Zhang mat_i = c->i[i]; 229499141d43SSatish Balay mat_j = c->j + mat_i; 229599141d43SSatish Balay mat_a = c->a + mat_i; 229699141d43SSatish Balay mat_ilen = c->ilen + i; 229717ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2298bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2299ed480e8bSBarry Smith *mat_j++ = tcol - 1; 230099141d43SSatish Balay *mat_a++ = a->a[k]; 230199141d43SSatish Balay (*mat_ilen)++; 230299141d43SSatish Balay 230317ab2063SBarry Smith } 230417ab2063SBarry Smith } 230517ab2063SBarry Smith } 230602834360SBarry Smith /* Free work space */ 230702834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2308606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2309606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2310cdc6f3adSToby Isaac /* sort */ 2311cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2312cdc6f3adSToby Isaac PetscInt ilen; 2313cdc6f3adSToby Isaac 2314cdc6f3adSToby Isaac mat_i = c->i[i]; 2315cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2316cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2317cdc6f3adSToby Isaac ilen = c->ilen[i]; 2318390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2319cdc6f3adSToby Isaac } 232002834360SBarry Smith } 23216d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23226d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 232317ab2063SBarry Smith 232417ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2325416022c9SBarry Smith *B = C; 23263a40ed3dSBarry Smith PetscFunctionReturn(0); 232717ab2063SBarry Smith } 232817ab2063SBarry Smith 2329fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 233082d44351SHong Zhang { 233182d44351SHong Zhang PetscErrorCode ierr; 233282d44351SHong Zhang Mat B; 233382d44351SHong Zhang 233482d44351SHong Zhang PetscFunctionBegin; 2335c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 233682d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 233782d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 233833d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 233982d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 234082d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 234182d44351SHong Zhang *subMat = B; 2342c2d650bdSHong Zhang } else { 2343c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2344c2d650bdSHong Zhang } 234582d44351SHong Zhang PetscFunctionReturn(0); 234682d44351SHong Zhang } 234782d44351SHong Zhang 23489a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2349a871dcd8SBarry Smith { 235063b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2351dfbe8321SBarry Smith PetscErrorCode ierr; 235263b91edcSBarry Smith Mat outA; 2353ace3abfcSBarry Smith PetscBool row_identity,col_identity; 235463b91edcSBarry Smith 23553a40ed3dSBarry Smith PetscFunctionBegin; 2356e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23571df811f5SHong Zhang 2358b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2359b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2360a871dcd8SBarry Smith 236163b91edcSBarry Smith outA = inA; 2362d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2363f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2364f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 23652205254eSKarl Rupp 2366c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 23676bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 23682205254eSKarl Rupp 2369c3122656SLisandro Dalcin a->row = row; 23702205254eSKarl Rupp 2371c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 23726bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 23732205254eSKarl Rupp 2374c3122656SLisandro Dalcin a->col = col; 237563b91edcSBarry Smith 237636db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 23776bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 23784c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 23793bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2380f0ec6fceSSatish Balay 238194a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2382854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 23833bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 238494a9d846SBarry Smith } 238563b91edcSBarry Smith 2386f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2387137fb511SHong Zhang if (row_identity && col_identity) { 2388ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2389137fb511SHong Zhang } else { 2390719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2391137fb511SHong Zhang } 23923a40ed3dSBarry Smith PetscFunctionReturn(0); 2393a871dcd8SBarry Smith } 2394a871dcd8SBarry Smith 2395f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2396f0b747eeSBarry Smith { 2397f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2398f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2399efee365bSSatish Balay PetscErrorCode ierr; 2400c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 24013a40ed3dSBarry Smith 24023a40ed3dSBarry Smith PetscFunctionBegin; 2403c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 24048b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2405efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2406acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 24073a40ed3dSBarry Smith PetscFunctionReturn(0); 2408f0b747eeSBarry Smith } 2409f0b747eeSBarry Smith 241016b64355SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubMat *submatj) 241116b64355SHong Zhang { 241216b64355SHong Zhang PetscErrorCode ierr; 241316b64355SHong Zhang PetscInt i; 241416b64355SHong Zhang 241516b64355SHong Zhang PetscFunctionBegin; 241616b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 241716b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 241816b64355SHong Zhang 241916b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 242016b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 242116b64355SHong Zhang } 242216b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 242316b64355SHong Zhang 242416b64355SHong Zhang if (submatj->rbuf1) { 242516b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 242616b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 242716b64355SHong Zhang } 242816b64355SHong Zhang 242916b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 243016b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 243116b64355SHong Zhang } 243216b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 243316b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 243416b64355SHong Zhang } 243516b64355SHong Zhang 243616b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 243716b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 243816b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 243916b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 244016b64355SHong Zhang #else 244116b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 244216b64355SHong Zhang #endif 244316b64355SHong Zhang 244416b64355SHong Zhang if (!submatj->allcolumns) { 244516b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 244616b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 244716b64355SHong Zhang #else 244816b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 244916b64355SHong Zhang #endif 245016b64355SHong Zhang } 245116b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 245216b64355SHong Zhang 245316b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 245416b64355SHong Zhang PetscFunctionReturn(0); 245516b64355SHong Zhang } 245616b64355SHong Zhang 245716b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C) 245816b64355SHong Zhang { 245916b64355SHong Zhang PetscErrorCode ierr; 246016b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 246116b64355SHong Zhang Mat_SubMat *submatj = c->submatis1; 246216b64355SHong Zhang 246316b64355SHong Zhang PetscFunctionBegin; 246416b64355SHong Zhang ierr = submatj->destroy(C);CHKERRQ(ierr); 2465*e69d178cSHong Zhang ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr); 246616b64355SHong Zhang PetscFunctionReturn(0); 246716b64355SHong Zhang } 246816b64355SHong Zhang 246997f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2470cddf8d76SBarry Smith { 2471dfbe8321SBarry Smith PetscErrorCode ierr; 247297f1f81fSBarry Smith PetscInt i; 2473cddf8d76SBarry Smith 24743a40ed3dSBarry Smith PetscFunctionBegin; 2475cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2476df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2477cddf8d76SBarry Smith } 2478cddf8d76SBarry Smith 2479cddf8d76SBarry Smith for (i=0; i<n; i++) { 24806a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2481cddf8d76SBarry Smith } 24823a40ed3dSBarry Smith PetscFunctionReturn(0); 2483cddf8d76SBarry Smith } 2484cddf8d76SBarry Smith 248597f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 24864dcbc457SBarry Smith { 2487e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 24886849ba73SBarry Smith PetscErrorCode ierr; 24895d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 24905d0c19d7SBarry Smith const PetscInt *idx; 249197f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2492f1af5d2fSBarry Smith PetscBT table; 2493bbd702dbSSatish Balay 24943a40ed3dSBarry Smith PetscFunctionBegin; 2495d0f46423SBarry Smith m = A->rmap->n; 2496e4d965acSSatish Balay ai = a->i; 2497bfeeae90SHong Zhang aj = a->j; 24988a047759SSatish Balay 2499e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 250006763907SSatish Balay 2501854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 250253b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 250306763907SSatish Balay 2504e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2505b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2506e4d965acSSatish Balay isz = 0; 25076831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2508e4d965acSSatish Balay 2509e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25104dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2511b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2512e4d965acSSatish Balay 2513dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2514e4d965acSSatish Balay for (j=0; j<n; ++j) { 25152205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25164dcbc457SBarry Smith } 251706763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25186bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2519e4d965acSSatish Balay 252004a348a9SBarry Smith k = 0; 252104a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 252204a348a9SBarry Smith n = isz; 252306763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2524e4d965acSSatish Balay row = nidx[k]; 2525e4d965acSSatish Balay start = ai[row]; 2526e4d965acSSatish Balay end = ai[row+1]; 252704a348a9SBarry Smith for (l = start; l<end; l++) { 2528efb16452SHong Zhang val = aj[l]; 25292205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2530e4d965acSSatish Balay } 2531e4d965acSSatish Balay } 2532e4d965acSSatish Balay } 253370b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2534e4d965acSSatish Balay } 253594bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2536606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 25373a40ed3dSBarry Smith PetscFunctionReturn(0); 25384dcbc457SBarry Smith } 253917ab2063SBarry Smith 25400513a670SBarry Smith /* -------------------------------------------------------------- */ 2541dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 25420513a670SBarry Smith { 25430513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25446849ba73SBarry Smith PetscErrorCode ierr; 25453b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 25465d0c19d7SBarry Smith const PetscInt *row,*col; 25475d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 254856cd22aeSBarry Smith IS icolp,irowp; 25490298fd71SBarry Smith PetscInt *cwork = NULL; 25500298fd71SBarry Smith PetscScalar *vwork = NULL; 25510513a670SBarry Smith 25523a40ed3dSBarry Smith PetscFunctionBegin; 25534c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 255456cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 25554c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 255656cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 25570513a670SBarry Smith 25580513a670SBarry Smith /* determine lengths of permuted rows */ 2559854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 25602205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2561ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2562f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 256333d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 25647adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2565ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2566606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 25670513a670SBarry Smith 2568785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 25690513a670SBarry Smith for (i=0; i<m; i++) { 257032ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25712205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2572cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 257332ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25740513a670SBarry Smith } 2575606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 25762205254eSKarl Rupp 25773c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 25782205254eSKarl Rupp 25790513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25800513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 258156cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 258256cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 25836bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 25846bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 25853a40ed3dSBarry Smith PetscFunctionReturn(0); 25860513a670SBarry Smith } 25870513a670SBarry Smith 2588dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2589cb5b572fSBarry Smith { 2590dfbe8321SBarry Smith PetscErrorCode ierr; 2591cb5b572fSBarry Smith 2592cb5b572fSBarry Smith PetscFunctionBegin; 259333f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 259433f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2595be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2596be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2597be6bf707SBarry Smith 2598700c5bfcSBarry 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"); 2599d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2600cb5b572fSBarry Smith } else { 2601cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2602cb5b572fSBarry Smith } 2603cb5b572fSBarry Smith PetscFunctionReturn(0); 2604cb5b572fSBarry Smith } 2605cb5b572fSBarry Smith 26064994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2607273d9f13SBarry Smith { 2608dfbe8321SBarry Smith PetscErrorCode ierr; 2609273d9f13SBarry Smith 2610273d9f13SBarry Smith PetscFunctionBegin; 2611ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2612273d9f13SBarry Smith PetscFunctionReturn(0); 2613273d9f13SBarry Smith } 2614273d9f13SBarry Smith 26158c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 26166c0721eeSBarry Smith { 26176c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26186e111a19SKarl Rupp 26196c0721eeSBarry Smith PetscFunctionBegin; 26206c0721eeSBarry Smith *array = a->a; 26216c0721eeSBarry Smith PetscFunctionReturn(0); 26226c0721eeSBarry Smith } 26236c0721eeSBarry Smith 26248c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 26256c0721eeSBarry Smith { 26266c0721eeSBarry Smith PetscFunctionBegin; 26276c0721eeSBarry Smith PetscFunctionReturn(0); 26286c0721eeSBarry Smith } 2629273d9f13SBarry Smith 26308229c054SShri Abhyankar /* 26318229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26328229c054SShri Abhyankar have different nonzero structure. 26338229c054SShri Abhyankar */ 2634b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2635ec7775f6SShri Abhyankar { 2636b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2637ec7775f6SShri Abhyankar 2638ec7775f6SShri Abhyankar PetscFunctionBegin; 2639ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2640ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2641b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2642b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2643b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 26448af7cee1SJed Brown nnz[i] = 0; 26458af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2646b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2647b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 26488af7cee1SJed Brown nnz[i]++; 26498af7cee1SJed Brown } 26508af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2651ec7775f6SShri Abhyankar } 2652ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2653ec7775f6SShri Abhyankar } 2654ec7775f6SShri Abhyankar 2655b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2656b264fe52SHong Zhang { 2657b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2658b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2659b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2660b264fe52SHong Zhang PetscErrorCode ierr; 2661b264fe52SHong Zhang 2662b264fe52SHong Zhang PetscFunctionBegin; 2663b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2664b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2665b264fe52SHong Zhang PetscFunctionReturn(0); 2666b264fe52SHong Zhang } 2667b264fe52SHong Zhang 2668f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2669ac90fabeSBarry Smith { 2670dfbe8321SBarry Smith PetscErrorCode ierr; 2671ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2672c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2673ac90fabeSBarry Smith 2674ac90fabeSBarry Smith PetscFunctionBegin; 2675c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2676ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2677f4df32b1SMatthew Knepley PetscScalar alpha = a; 26788b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2679acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2680a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2681ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2682ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2683ac90fabeSBarry Smith } else { 26848229c054SShri Abhyankar Mat B; 26858229c054SShri Abhyankar PetscInt *nnz; 2686785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2687ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2688bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 26894aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 269033d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2691176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 26928229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2693ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2694ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 269528be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 26968229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2697ac90fabeSBarry Smith } 2698ac90fabeSBarry Smith PetscFunctionReturn(0); 2699ac90fabeSBarry Smith } 2700ac90fabeSBarry Smith 27017087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2702354c94deSBarry Smith { 2703354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2704354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2705354c94deSBarry Smith PetscInt i,nz; 2706354c94deSBarry Smith PetscScalar *a; 2707354c94deSBarry Smith 2708354c94deSBarry Smith PetscFunctionBegin; 2709354c94deSBarry Smith nz = aij->nz; 2710354c94deSBarry Smith a = aij->a; 27112205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2712354c94deSBarry Smith #else 2713354c94deSBarry Smith PetscFunctionBegin; 2714354c94deSBarry Smith #endif 2715354c94deSBarry Smith PetscFunctionReturn(0); 2716354c94deSBarry Smith } 2717354c94deSBarry Smith 2718985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2719e34fafa9SBarry Smith { 2720e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2721e34fafa9SBarry Smith PetscErrorCode ierr; 2722d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2723e34fafa9SBarry Smith PetscReal atmp; 2724985db425SBarry Smith PetscScalar *x; 2725e34fafa9SBarry Smith MatScalar *aa; 2726e34fafa9SBarry Smith 2727e34fafa9SBarry Smith PetscFunctionBegin; 2728e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2729e34fafa9SBarry Smith aa = a->a; 2730e34fafa9SBarry Smith ai = a->i; 2731e34fafa9SBarry Smith aj = a->j; 2732e34fafa9SBarry Smith 2733985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2734e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2735e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2736e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2737e34fafa9SBarry Smith for (i=0; i<m; i++) { 2738e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 27399189402eSHong Zhang x[i] = 0.0; 2740e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2741985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2742985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2743985db425SBarry Smith aa++; aj++; 2744985db425SBarry Smith } 2745985db425SBarry Smith } 2746985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2747985db425SBarry Smith PetscFunctionReturn(0); 2748985db425SBarry Smith } 2749985db425SBarry Smith 2750985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2751985db425SBarry Smith { 2752985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2753985db425SBarry Smith PetscErrorCode ierr; 2754d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2755985db425SBarry Smith PetscScalar *x; 2756985db425SBarry Smith MatScalar *aa; 2757985db425SBarry Smith 2758985db425SBarry Smith PetscFunctionBegin; 2759e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2760985db425SBarry Smith aa = a->a; 2761985db425SBarry Smith ai = a->i; 2762985db425SBarry Smith aj = a->j; 2763985db425SBarry Smith 2764985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2765985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2766985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2767e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2768985db425SBarry Smith for (i=0; i<m; i++) { 2769985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2770d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2771985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2772985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2773985db425SBarry Smith x[i] = 0.0; 2774985db425SBarry Smith if (idx) { 2775985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2776985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2777985db425SBarry Smith if (aj[j] > j) { 2778985db425SBarry Smith idx[i] = j; 2779985db425SBarry Smith break; 2780985db425SBarry Smith } 2781985db425SBarry Smith } 2782985db425SBarry Smith } 2783985db425SBarry Smith } 2784985db425SBarry Smith for (j=0; j<ncols; j++) { 2785985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2786985db425SBarry Smith aa++; aj++; 2787985db425SBarry Smith } 2788985db425SBarry Smith } 2789985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2790985db425SBarry Smith PetscFunctionReturn(0); 2791985db425SBarry Smith } 2792985db425SBarry Smith 2793c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2794c87e5d42SMatthew Knepley { 2795c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2796c87e5d42SMatthew Knepley PetscErrorCode ierr; 2797c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2798c87e5d42SMatthew Knepley PetscReal atmp; 2799c87e5d42SMatthew Knepley PetscScalar *x; 2800c87e5d42SMatthew Knepley MatScalar *aa; 2801c87e5d42SMatthew Knepley 2802c87e5d42SMatthew Knepley PetscFunctionBegin; 2803e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2804c87e5d42SMatthew Knepley aa = a->a; 2805c87e5d42SMatthew Knepley ai = a->i; 2806c87e5d42SMatthew Knepley aj = a->j; 2807c87e5d42SMatthew Knepley 2808c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2809c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2810c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 281160e0710aSBarry 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); 2812c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2813c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2814289a08f5SMatthew Knepley if (ncols) { 2815289a08f5SMatthew Knepley /* Get first nonzero */ 2816289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 2817289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 28182205254eSKarl Rupp if (atmp > 1.0e-12) { 28192205254eSKarl Rupp x[i] = atmp; 28202205254eSKarl Rupp if (idx) idx[i] = aj[j]; 28212205254eSKarl Rupp break; 28222205254eSKarl Rupp } 2823289a08f5SMatthew Knepley } 282412431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2825289a08f5SMatthew Knepley } else { 2826289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2827289a08f5SMatthew Knepley } 2828c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 2829c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2830289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2831c87e5d42SMatthew Knepley aa++; aj++; 2832c87e5d42SMatthew Knepley } 2833c87e5d42SMatthew Knepley } 2834c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2835c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2836c87e5d42SMatthew Knepley } 2837c87e5d42SMatthew Knepley 2838985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2839985db425SBarry Smith { 2840985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2841985db425SBarry Smith PetscErrorCode ierr; 2842d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 2843d9ca1df4SBarry Smith const PetscInt *ai,*aj; 2844985db425SBarry Smith PetscScalar *x; 2845d9ca1df4SBarry Smith const MatScalar *aa; 2846985db425SBarry Smith 2847985db425SBarry Smith PetscFunctionBegin; 2848e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2849985db425SBarry Smith aa = a->a; 2850985db425SBarry Smith ai = a->i; 2851985db425SBarry Smith aj = a->j; 2852985db425SBarry Smith 2853985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2854985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2855985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2856e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2857985db425SBarry Smith for (i=0; i<m; i++) { 2858985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2859d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2860985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2861985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2862985db425SBarry Smith x[i] = 0.0; 2863985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2864985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2865985db425SBarry Smith for (j=0; j<ncols; j++) { 2866985db425SBarry Smith if (aj[j] > j) { 2867985db425SBarry Smith idx[i] = j; 2868985db425SBarry Smith break; 2869985db425SBarry Smith } 2870985db425SBarry Smith } 2871985db425SBarry Smith } 2872985db425SBarry Smith } 2873985db425SBarry Smith for (j=0; j<ncols; j++) { 2874985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2875985db425SBarry Smith aa++; aj++; 2876e34fafa9SBarry Smith } 2877e34fafa9SBarry Smith } 2878e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2879e34fafa9SBarry Smith PetscFunctionReturn(0); 2880e34fafa9SBarry Smith } 2881bbead8a2SBarry Smith 2882bbead8a2SBarry Smith #include <petscblaslapack.h> 2883af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h> 2884bbead8a2SBarry Smith 2885713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2886bbead8a2SBarry Smith { 2887bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2888bbead8a2SBarry Smith PetscErrorCode ierr; 288933d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2890bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2891bbead8a2SBarry Smith PetscReal shift = 0.0; 28921a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 2893bbead8a2SBarry Smith 2894bbead8a2SBarry Smith PetscFunctionBegin; 2895a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 28964a0d0026SBarry Smith if (a->ibdiagvalid) { 28974a0d0026SBarry Smith if (values) *values = a->ibdiag; 28984a0d0026SBarry Smith PetscFunctionReturn(0); 28994a0d0026SBarry Smith } 2900bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2901bbead8a2SBarry Smith if (!a->ibdiag) { 2902785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 29033bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2904bbead8a2SBarry Smith } 2905bbead8a2SBarry Smith diag = a->ibdiag; 2906bbead8a2SBarry Smith if (values) *values = a->ibdiag; 2907bbead8a2SBarry Smith /* factor and invert each block */ 2908bbead8a2SBarry Smith switch (bs) { 2909bbead8a2SBarry Smith case 1: 2910bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2911bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 2912ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 2913ec1892c8SHong Zhang if (allowzeropivot) { 29147b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 29157b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 29167b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 29177b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 29187b6c816cSBarry 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); 2919ec1892c8SHong Zhang } 2920bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 2921bbead8a2SBarry Smith } 2922bbead8a2SBarry Smith break; 2923bbead8a2SBarry Smith case 2: 2924bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2925bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 2926bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 2927a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29287b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 292996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 2930bbead8a2SBarry Smith diag += 4; 2931bbead8a2SBarry Smith } 2932bbead8a2SBarry Smith break; 2933bbead8a2SBarry Smith case 3: 2934bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2935bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 2936bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 2937a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29387b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 293996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 2940bbead8a2SBarry Smith diag += 9; 2941bbead8a2SBarry Smith } 2942bbead8a2SBarry Smith break; 2943bbead8a2SBarry Smith case 4: 2944bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2945bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 2946bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 2947a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29487b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 294996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 2950bbead8a2SBarry Smith diag += 16; 2951bbead8a2SBarry Smith } 2952bbead8a2SBarry Smith break; 2953bbead8a2SBarry Smith case 5: 2954bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2955bbead8a2SBarry 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; 2956bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 2957a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29587b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 295996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 2960bbead8a2SBarry Smith diag += 25; 2961bbead8a2SBarry Smith } 2962bbead8a2SBarry Smith break; 2963bbead8a2SBarry Smith case 6: 2964bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2965bbead8a2SBarry 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; 2966bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 2967a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29687b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 296996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 2970bbead8a2SBarry Smith diag += 36; 2971bbead8a2SBarry Smith } 2972bbead8a2SBarry Smith break; 2973bbead8a2SBarry Smith case 7: 2974bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2975bbead8a2SBarry 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; 2976bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 2977a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29787b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 297996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 2980bbead8a2SBarry Smith diag += 49; 2981bbead8a2SBarry Smith } 2982bbead8a2SBarry Smith break; 2983bbead8a2SBarry Smith default: 2984dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 2985bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2986bbead8a2SBarry Smith for (j=0; j<bs; j++) { 2987bbead8a2SBarry Smith IJ[j] = bs*i + j; 2988bbead8a2SBarry Smith } 2989bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 29905f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29917b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 299296b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 2993bbead8a2SBarry Smith diag += bs2; 2994bbead8a2SBarry Smith } 2995bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 2996bbead8a2SBarry Smith } 2997bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 2998bbead8a2SBarry Smith PetscFunctionReturn(0); 2999bbead8a2SBarry Smith } 3000bbead8a2SBarry Smith 300173a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 300273a71a0fSBarry Smith { 300373a71a0fSBarry Smith PetscErrorCode ierr; 300473a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 300573a71a0fSBarry Smith PetscScalar a; 300673a71a0fSBarry Smith PetscInt m,n,i,j,col; 300773a71a0fSBarry Smith 300873a71a0fSBarry Smith PetscFunctionBegin; 300973a71a0fSBarry Smith if (!x->assembled) { 301073a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 301173a71a0fSBarry Smith for (i=0; i<m; i++) { 301273a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 301373a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 301473a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 301573a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 301673a71a0fSBarry Smith } 301773a71a0fSBarry Smith } 301873a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 301973a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 302073a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 302173a71a0fSBarry Smith PetscFunctionReturn(0); 302273a71a0fSBarry Smith } 302373a71a0fSBarry Smith 30247d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a) 30257d68702bSBarry Smith { 30267d68702bSBarry Smith PetscErrorCode ierr; 30277d68702bSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)Y->data; 30287d68702bSBarry Smith 30297d68702bSBarry Smith PetscFunctionBegin; 30306f33a894SBarry Smith if (!Y->preallocated || !aij->nz) { 30317d68702bSBarry Smith ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr); 30327d68702bSBarry Smith } 30337d68702bSBarry Smith ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 30347d68702bSBarry Smith PetscFunctionReturn(0); 30357d68702bSBarry Smith } 30367d68702bSBarry Smith 3037682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 30380a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3039cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3040cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3041cb5b572fSBarry Smith MatMult_SeqAIJ, 304297304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 30437c922b88SBarry Smith MatMultTranspose_SeqAIJ, 30447c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3045db4efbfdSBarry Smith 0, 3046db4efbfdSBarry Smith 0, 3047db4efbfdSBarry Smith 0, 3048db4efbfdSBarry Smith /* 10*/ 0, 3049cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3050cb5b572fSBarry Smith 0, 305141f059aeSBarry Smith MatSOR_SeqAIJ, 305217ab2063SBarry Smith MatTranspose_SeqAIJ, 305397304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3054cb5b572fSBarry Smith MatEqual_SeqAIJ, 3055cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3056cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3057cb5b572fSBarry Smith MatNorm_SeqAIJ, 305897304618SKris Buschelman /* 20*/ 0, 3059cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3060cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3061cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3062d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3063db4efbfdSBarry Smith 0, 3064db4efbfdSBarry Smith 0, 3065db4efbfdSBarry Smith 0, 3066db4efbfdSBarry Smith 0, 30674994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3068db4efbfdSBarry Smith 0, 3069db4efbfdSBarry Smith 0, 30708c778c55SBarry Smith 0, 30718c778c55SBarry Smith 0, 3072d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3073cb5b572fSBarry Smith 0, 3074cb5b572fSBarry Smith 0, 3075cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3076cb5b572fSBarry Smith 0, 3077d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 3078cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3079cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3080cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3081cb5b572fSBarry Smith MatCopy_SeqAIJ, 3082d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3083cb5b572fSBarry Smith MatScale_SeqAIJ, 30847d68702bSBarry Smith MatShift_SeqAIJ, 308579299369SBarry Smith MatDiagonalSet_SeqAIJ, 30866e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 308773a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 30883b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 30893b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 30903b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3091a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 309293dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3093b9617806SBarry Smith 0, 30940513a670SBarry Smith 0, 3095cda55fadSBarry Smith MatPermute_SeqAIJ, 3096cda55fadSBarry Smith 0, 3097d519adbfSMatthew Knepley /* 59*/ 0, 3098b9b97703SBarry Smith MatDestroy_SeqAIJ, 3099b9b97703SBarry Smith MatView_SeqAIJ, 3100357abbc8SBarry Smith 0, 3101321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3102321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3103321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3104ee4f033dSBarry Smith 0, 3105ee4f033dSBarry Smith 0, 3106ee4f033dSBarry Smith 0, 3107d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3108c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3109ee4f033dSBarry Smith 0, 3110dcf5cc72SBarry Smith 0, 31112c93a97aSBarry Smith 0, 31122c93a97aSBarry Smith /* 74*/ 0, 31133acb8795SBarry Smith MatFDColoringApply_AIJ, 311497304618SKris Buschelman 0, 311597304618SKris Buschelman 0, 311697304618SKris Buschelman 0, 31176ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 311897304618SKris Buschelman 0, 311997304618SKris Buschelman 0, 312097304618SKris Buschelman 0, 3121bc011b1eSHong Zhang MatLoad_SeqAIJ, 3122d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31231cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31246284ec50SHong Zhang 0, 31256284ec50SHong Zhang 0, 3126bc011b1eSHong Zhang 0, 3127d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 312826be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 312926be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 313065e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 31314a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 313265e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 31336fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 31346fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 31356fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 31362121bac1SHong Zhang 0, 31372121bac1SHong Zhang /* 99*/ 0, 3138609c6c4dSKris Buschelman 0, 3139609c6c4dSKris Buschelman 0, 314087d4246cSBarry Smith MatConjugate_SeqAIJ, 314187d4246cSBarry Smith 0, 3142d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 314399cafbc1SBarry Smith MatRealPart_SeqAIJ, 3144f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3145f5edf698SHong Zhang 0, 31462bebee5dSHong Zhang 0, 3147cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3148985db425SBarry Smith 0, 31492af78befSBarry Smith MatGetRowMin_SeqAIJ, 31502af78befSBarry Smith 0, 3151599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3152d519adbfSMatthew Knepley /*114*/ 0, 3153599ef60dSHong Zhang 0, 31543c2a7987SHong Zhang 0, 3155fe97e370SBarry Smith 0, 3156fbdbba38SShri Abhyankar 0, 3157fbdbba38SShri Abhyankar /*119*/ 0, 3158fbdbba38SShri Abhyankar 0, 3159fbdbba38SShri Abhyankar 0, 316082d44351SHong Zhang 0, 3161b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 31620716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3163bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 316437868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 316537868618SMatthew G Knepley 0, 316637868618SMatthew G Knepley 0, 31675df89d91SHong Zhang /*129*/ 0, 316875648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 316975648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 317075648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3171b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3172b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 31732b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 31742b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 31752b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 31763964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 31773964eb88SJed Brown /*139*/0, 3178f9426fe0SMark Adams 0, 31791919a2e2SJed Brown 0, 31803a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 31819c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 31829c8f2541SHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ 31839e29f15eSvictorle }; 318417ab2063SBarry Smith 31857087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3186bef8e0ddSBarry Smith { 3187bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 318897f1f81fSBarry Smith PetscInt i,nz,n; 3189bef8e0ddSBarry Smith 3190bef8e0ddSBarry Smith PetscFunctionBegin; 3191bef8e0ddSBarry Smith nz = aij->maxnz; 3192d0f46423SBarry Smith n = mat->rmap->n; 3193bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3194bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3195bef8e0ddSBarry Smith } 3196bef8e0ddSBarry Smith aij->nz = nz; 3197bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3198bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3199bef8e0ddSBarry Smith } 3200bef8e0ddSBarry Smith PetscFunctionReturn(0); 3201bef8e0ddSBarry Smith } 3202bef8e0ddSBarry Smith 3203bef8e0ddSBarry Smith /*@ 3204bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3205bef8e0ddSBarry Smith in the matrix. 3206bef8e0ddSBarry Smith 3207bef8e0ddSBarry Smith Input Parameters: 3208bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3209bef8e0ddSBarry Smith - indices - the column indices 3210bef8e0ddSBarry Smith 321115091d37SBarry Smith Level: advanced 321215091d37SBarry Smith 3213bef8e0ddSBarry Smith Notes: 3214bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3215bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3216bef8e0ddSBarry Smith of the MatSetValues() operation. 3217bef8e0ddSBarry Smith 3218bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3219d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3220bef8e0ddSBarry Smith 3221bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3222bef8e0ddSBarry Smith 3223b9617806SBarry Smith The indices should start with zero, not one. 3224b9617806SBarry Smith 3225bef8e0ddSBarry Smith @*/ 32267087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3227bef8e0ddSBarry Smith { 32284ac538c5SBarry Smith PetscErrorCode ierr; 3229bef8e0ddSBarry Smith 3230bef8e0ddSBarry Smith PetscFunctionBegin; 32310700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 32324482741eSBarry Smith PetscValidPointer(indices,2); 32334ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3234bef8e0ddSBarry Smith PetscFunctionReturn(0); 3235bef8e0ddSBarry Smith } 3236bef8e0ddSBarry Smith 3237be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3238be6bf707SBarry Smith 32397087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3240be6bf707SBarry Smith { 3241be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 32426849ba73SBarry Smith PetscErrorCode ierr; 3243d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3244be6bf707SBarry Smith 3245be6bf707SBarry Smith PetscFunctionBegin; 3246169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3247be6bf707SBarry Smith 3248be6bf707SBarry Smith /* allocate space for values if not already there */ 3249be6bf707SBarry Smith if (!aij->saved_values) { 3250854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 32513bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3252be6bf707SBarry Smith } 3253be6bf707SBarry Smith 3254be6bf707SBarry Smith /* copy values over */ 325587828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3256be6bf707SBarry Smith PetscFunctionReturn(0); 3257be6bf707SBarry Smith } 3258be6bf707SBarry Smith 3259be6bf707SBarry Smith /*@ 3260be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3261be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3262be6bf707SBarry Smith nonlinear portion. 3263be6bf707SBarry Smith 3264be6bf707SBarry Smith Collect on Mat 3265be6bf707SBarry Smith 3266be6bf707SBarry Smith Input Parameters: 32670e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3268be6bf707SBarry Smith 326915091d37SBarry Smith Level: advanced 327015091d37SBarry Smith 3271be6bf707SBarry Smith Common Usage, with SNESSolve(): 3272be6bf707SBarry Smith $ Create Jacobian matrix 3273be6bf707SBarry Smith $ Set linear terms into matrix 3274be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3275be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3276be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3277512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3278be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3279be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3280be6bf707SBarry Smith $ In your Jacobian routine 3281be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3282be6bf707SBarry Smith $ Set nonlinear terms in matrix 3283be6bf707SBarry Smith 3284be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3285be6bf707SBarry Smith $ // build linear portion of Jacobian 3286512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3287be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3288be6bf707SBarry Smith $ loop over nonlinear iterations 3289be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3290be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3291be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3292be6bf707SBarry Smith $ Solve linear system with Jacobian 3293be6bf707SBarry Smith $ endloop 3294be6bf707SBarry Smith 3295be6bf707SBarry Smith Notes: 3296be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3297512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3298be6bf707SBarry Smith calling this routine. 3299be6bf707SBarry Smith 33000c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33010c468ba9SBarry Smith and does not allocated additional space. 33020c468ba9SBarry Smith 3303be6bf707SBarry Smith .seealso: MatRetrieveValues() 3304be6bf707SBarry Smith 3305be6bf707SBarry Smith @*/ 33067087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3307be6bf707SBarry Smith { 33084ac538c5SBarry Smith PetscErrorCode ierr; 3309be6bf707SBarry Smith 3310be6bf707SBarry Smith PetscFunctionBegin; 33110700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3312e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3313e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33144ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3315be6bf707SBarry Smith PetscFunctionReturn(0); 3316be6bf707SBarry Smith } 3317be6bf707SBarry Smith 33187087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3319be6bf707SBarry Smith { 3320be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33216849ba73SBarry Smith PetscErrorCode ierr; 3322d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3323be6bf707SBarry Smith 3324be6bf707SBarry Smith PetscFunctionBegin; 3325169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3326f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3327be6bf707SBarry Smith /* copy values over */ 332887828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3329be6bf707SBarry Smith PetscFunctionReturn(0); 3330be6bf707SBarry Smith } 3331be6bf707SBarry Smith 3332be6bf707SBarry Smith /*@ 3333be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3334be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3335be6bf707SBarry Smith nonlinear portion. 3336be6bf707SBarry Smith 3337be6bf707SBarry Smith Collect on Mat 3338be6bf707SBarry Smith 3339be6bf707SBarry Smith Input Parameters: 3340386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3341be6bf707SBarry Smith 334215091d37SBarry Smith Level: advanced 334315091d37SBarry Smith 3344be6bf707SBarry Smith .seealso: MatStoreValues() 3345be6bf707SBarry Smith 3346be6bf707SBarry Smith @*/ 33477087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3348be6bf707SBarry Smith { 33494ac538c5SBarry Smith PetscErrorCode ierr; 3350be6bf707SBarry Smith 3351be6bf707SBarry Smith PetscFunctionBegin; 33520700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3353e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3354e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33554ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3356be6bf707SBarry Smith PetscFunctionReturn(0); 3357be6bf707SBarry Smith } 3358be6bf707SBarry Smith 3359f83d6046SBarry Smith 3360be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 336117ab2063SBarry Smith /*@C 3362682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 33630d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 33646e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 336551c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 33662bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 336717ab2063SBarry Smith 3368db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3369db81eaa0SLois Curfman McInnes 337017ab2063SBarry Smith Input Parameters: 3371db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 337217ab2063SBarry Smith . m - number of rows 337317ab2063SBarry Smith . n - number of columns 337417ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 337551c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 33760298fd71SBarry Smith (possibly different for each row) or NULL 337717ab2063SBarry Smith 337817ab2063SBarry Smith Output Parameter: 3379416022c9SBarry Smith . A - the matrix 338017ab2063SBarry Smith 3381175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3382ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3383175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3384175b88e8SBarry Smith 3385b259b22eSLois Curfman McInnes Notes: 338649a6f317SBarry Smith If nnz is given then nz is ignored 338749a6f317SBarry Smith 338817ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 338917ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 33900002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 339144cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 339217ab2063SBarry Smith 339317ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 33940298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 33953d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 33966da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 339717ab2063SBarry Smith 3398682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 33994fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3400682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34016c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34026c7ebb05SLois Curfman McInnes 34036c7ebb05SLois Curfman McInnes Options Database Keys: 3404698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34059db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 340617ab2063SBarry Smith 3407027ccd11SLois Curfman McInnes Level: intermediate 3408027ccd11SLois Curfman McInnes 340969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 341036db0b34SBarry Smith 341117ab2063SBarry Smith @*/ 34127087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 341317ab2063SBarry Smith { 3414dfbe8321SBarry Smith PetscErrorCode ierr; 34156945ee14SBarry Smith 34163a40ed3dSBarry Smith PetscFunctionBegin; 3417f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3418117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3419c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3420d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3421273d9f13SBarry Smith PetscFunctionReturn(0); 3422273d9f13SBarry Smith } 3423273d9f13SBarry Smith 3424273d9f13SBarry Smith /*@C 3425273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3426273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3427273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3428273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3429273d9f13SBarry Smith 3430273d9f13SBarry Smith Collective on MPI_Comm 3431273d9f13SBarry Smith 3432273d9f13SBarry Smith Input Parameters: 34331c4f3114SJed Brown + B - The matrix 3434273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3435273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34360298fd71SBarry Smith (possibly different for each row) or NULL 3437273d9f13SBarry Smith 3438273d9f13SBarry Smith Notes: 343949a6f317SBarry Smith If nnz is given then nz is ignored 344049a6f317SBarry Smith 3441273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3442273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3443273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3444273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3445273d9f13SBarry Smith 3446273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34470298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3448273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3449273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3450273d9f13SBarry Smith 3451aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3452aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3453aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3454aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3455aa95bbe8SBarry Smith 3456a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3457a96a251dSBarry Smith entries or columns indices 3458a96a251dSBarry Smith 3459273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3460273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3461273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3462273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3463273d9f13SBarry Smith 3464273d9f13SBarry Smith Options Database Keys: 3465698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3466698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3467273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3468273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3469273d9f13SBarry Smith the user still MUST index entries starting at 0! 3470273d9f13SBarry Smith 3471273d9f13SBarry Smith Level: intermediate 3472273d9f13SBarry Smith 347369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3474273d9f13SBarry Smith 3475273d9f13SBarry Smith @*/ 34767087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3477273d9f13SBarry Smith { 34784ac538c5SBarry Smith PetscErrorCode ierr; 3479a23d5eceSKris Buschelman 3480a23d5eceSKris Buschelman PetscFunctionBegin; 34816ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 34826ba663aaSJed Brown PetscValidType(B,1); 34834ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3484a23d5eceSKris Buschelman PetscFunctionReturn(0); 3485a23d5eceSKris Buschelman } 3486a23d5eceSKris Buschelman 34877087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3488a23d5eceSKris Buschelman { 3489273d9f13SBarry Smith Mat_SeqAIJ *b; 34902576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 34916849ba73SBarry Smith PetscErrorCode ierr; 349297f1f81fSBarry Smith PetscInt i; 3493273d9f13SBarry Smith 3494273d9f13SBarry Smith PetscFunctionBegin; 34952576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3496a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3497c461c341SBarry Smith skipallocation = PETSC_TRUE; 3498c461c341SBarry Smith nz = 0; 3499c461c341SBarry Smith } 3500c461c341SBarry Smith 350126283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 350226283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3503899cda47SBarry Smith 3504435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 350560e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3506b73539f3SBarry Smith if (nnz) { 3507d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 350860e0710aSBarry 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]); 350960e0710aSBarry 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); 3510b73539f3SBarry Smith } 3511b73539f3SBarry Smith } 3512b73539f3SBarry Smith 3513273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35142205254eSKarl Rupp 3515273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3516273d9f13SBarry Smith 3517ab93d7beSBarry Smith if (!skipallocation) { 35182ee49352SLisandro Dalcin if (!b->imax) { 3519dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 35203bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 35212ee49352SLisandro Dalcin } 3522273d9f13SBarry Smith if (!nnz) { 3523435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3524c62bd62aSJed Brown else if (nz < 0) nz = 1; 3525d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3526d0f46423SBarry Smith nz = nz*B->rmap->n; 3527273d9f13SBarry Smith } else { 3528273d9f13SBarry Smith nz = 0; 3529d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3530273d9f13SBarry Smith } 3531ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 35322205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3533ab93d7beSBarry Smith 3534273d9f13SBarry Smith /* allocate the matrix space */ 353553dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 35362ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3537dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 35383bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3539bfeeae90SHong Zhang b->i[0] = 0; 3540d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 35415da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 35425da197adSKris Buschelman } 3543273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3544e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3545e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3546c461c341SBarry Smith } else { 3547e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3548e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3549c461c341SBarry Smith } 3550273d9f13SBarry Smith 3551273d9f13SBarry Smith b->nz = 0; 3552273d9f13SBarry Smith b->maxnz = nz; 3553273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 35542205254eSKarl Rupp if (realalloc) { 35552205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 35562205254eSKarl Rupp } 3557cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3558cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3559273d9f13SBarry Smith PetscFunctionReturn(0); 3560273d9f13SBarry Smith } 3561273d9f13SBarry Smith 356258d36128SBarry Smith /*@ 3563a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3564a1661176SMatthew Knepley 3565a1661176SMatthew Knepley Input Parameters: 3566a1661176SMatthew Knepley + B - the matrix 3567a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3568a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3569a1661176SMatthew Knepley - v - optional values in the matrix 3570a1661176SMatthew Knepley 3571a1661176SMatthew Knepley Level: developer 3572a1661176SMatthew Knepley 357358d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 357458d36128SBarry Smith 3575a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3576a1661176SMatthew Knepley 3577a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3578a1661176SMatthew Knepley @*/ 3579a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3580a1661176SMatthew Knepley { 3581a1661176SMatthew Knepley PetscErrorCode ierr; 3582a1661176SMatthew Knepley 3583a1661176SMatthew Knepley PetscFunctionBegin; 35840700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35856ba663aaSJed Brown PetscValidType(B,1); 35864ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3587a1661176SMatthew Knepley PetscFunctionReturn(0); 3588a1661176SMatthew Knepley } 3589a1661176SMatthew Knepley 35907087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3591a1661176SMatthew Knepley { 3592a1661176SMatthew Knepley PetscInt i; 3593a1661176SMatthew Knepley PetscInt m,n; 3594a1661176SMatthew Knepley PetscInt nz; 3595a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3596a1661176SMatthew Knepley PetscScalar *values; 3597a1661176SMatthew Knepley PetscErrorCode ierr; 3598a1661176SMatthew Knepley 3599a1661176SMatthew Knepley PetscFunctionBegin; 360065e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3601779a8d59SSatish Balay 3602779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3603779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3604779a8d59SSatish Balay 3605779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3606854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 3607a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3608b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3609a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 361065e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3611a1661176SMatthew Knepley nnz[i] = nz; 3612a1661176SMatthew Knepley } 3613a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3614a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3615a1661176SMatthew Knepley 3616a1661176SMatthew Knepley if (v) { 3617a1661176SMatthew Knepley values = (PetscScalar*) v; 3618a1661176SMatthew Knepley } else { 36191795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3620a1661176SMatthew Knepley } 3621a1661176SMatthew Knepley 3622a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3623b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3624b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3625a1661176SMatthew Knepley } 3626a1661176SMatthew Knepley 3627a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3628a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3629a1661176SMatthew Knepley 3630a1661176SMatthew Knepley if (!v) { 3631a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3632a1661176SMatthew Knepley } 36337827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3634a1661176SMatthew Knepley PetscFunctionReturn(0); 3635a1661176SMatthew Knepley } 3636a1661176SMatthew Knepley 3637c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3638af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 3639170fe5c8SBarry Smith 3640170fe5c8SBarry Smith /* 3641170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3642170fe5c8SBarry Smith 3643170fe5c8SBarry Smith n p p 3644170fe5c8SBarry Smith ( ) ( ) ( ) 3645170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3646170fe5c8SBarry Smith ( ) ( ) ( ) 3647170fe5c8SBarry Smith 3648170fe5c8SBarry Smith */ 3649170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3650170fe5c8SBarry Smith { 3651170fe5c8SBarry Smith PetscErrorCode ierr; 3652170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3653170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3654170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 36551de00fd4SBarry Smith PetscInt i,n,m,q,p; 3656170fe5c8SBarry Smith const PetscInt *ii,*idx; 3657170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3658170fe5c8SBarry Smith PetscScalar *c,*c_q; 3659170fe5c8SBarry Smith 3660170fe5c8SBarry Smith PetscFunctionBegin; 3661d0f46423SBarry Smith m = A->rmap->n; 3662d0f46423SBarry Smith n = A->cmap->n; 3663d0f46423SBarry Smith p = B->cmap->n; 3664170fe5c8SBarry Smith a = sub_a->v; 3665170fe5c8SBarry Smith b = sub_b->a; 3666170fe5c8SBarry Smith c = sub_c->v; 3667170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3668170fe5c8SBarry Smith 3669170fe5c8SBarry Smith ii = sub_b->i; 3670170fe5c8SBarry Smith idx = sub_b->j; 3671170fe5c8SBarry Smith for (i=0; i<n; i++) { 3672170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3673170fe5c8SBarry Smith while (q-->0) { 3674170fe5c8SBarry Smith c_q = c + m*(*idx); 3675170fe5c8SBarry Smith a_q = a + m*i; 3676854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3677170fe5c8SBarry Smith idx++; 3678170fe5c8SBarry Smith b++; 3679170fe5c8SBarry Smith } 3680170fe5c8SBarry Smith } 3681170fe5c8SBarry Smith PetscFunctionReturn(0); 3682170fe5c8SBarry Smith } 3683170fe5c8SBarry Smith 3684170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3685170fe5c8SBarry Smith { 3686170fe5c8SBarry Smith PetscErrorCode ierr; 3687d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3688170fe5c8SBarry Smith Mat Cmat; 3689170fe5c8SBarry Smith 3690170fe5c8SBarry Smith PetscFunctionBegin; 369160e0710aSBarry 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); 3692ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3693170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 369433d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 3695170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 36960298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3697d73949e8SHong Zhang 3698d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 36992205254eSKarl Rupp 3700170fe5c8SBarry Smith *C = Cmat; 3701170fe5c8SBarry Smith PetscFunctionReturn(0); 3702170fe5c8SBarry Smith } 3703170fe5c8SBarry Smith 3704170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3705150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3706170fe5c8SBarry Smith { 3707170fe5c8SBarry Smith PetscErrorCode ierr; 3708170fe5c8SBarry Smith 3709170fe5c8SBarry Smith PetscFunctionBegin; 3710170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 37113ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3712170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 37133ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3714170fe5c8SBarry Smith } 37153ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3716170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 37173ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3718170fe5c8SBarry Smith PetscFunctionReturn(0); 3719170fe5c8SBarry Smith } 3720170fe5c8SBarry Smith 3721170fe5c8SBarry Smith 37220bad9183SKris Buschelman /*MC 3723fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 37240bad9183SKris Buschelman based on compressed sparse row format. 37250bad9183SKris Buschelman 37260bad9183SKris Buschelman Options Database Keys: 37270bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 37280bad9183SKris Buschelman 37290bad9183SKris Buschelman Level: beginner 37300bad9183SKris Buschelman 3731f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 37320bad9183SKris Buschelman M*/ 37330bad9183SKris Buschelman 3734ccd284c7SBarry Smith /*MC 3735ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3736ccd284c7SBarry Smith 3737ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3738ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 3739ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 3740ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3741ccd284c7SBarry Smith the above preallocation routines for simplicity. 3742ccd284c7SBarry Smith 3743ccd284c7SBarry Smith Options Database Keys: 3744ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 3745ccd284c7SBarry Smith 3746ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 3747ccd284c7SBarry Smith enough exist. 3748ccd284c7SBarry Smith 3749ccd284c7SBarry Smith Level: beginner 3750ccd284c7SBarry Smith 3751ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 3752ccd284c7SBarry Smith M*/ 3753ccd284c7SBarry Smith 3754ccd284c7SBarry Smith /*MC 3755ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 3756ccd284c7SBarry Smith 3757ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 3758ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 3759ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 3760ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3761ccd284c7SBarry Smith the above preallocation routines for simplicity. 3762ccd284c7SBarry Smith 3763ccd284c7SBarry Smith Options Database Keys: 3764ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 3765ccd284c7SBarry Smith 3766ccd284c7SBarry Smith Level: beginner 3767ccd284c7SBarry Smith 3768ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 3769ccd284c7SBarry Smith M*/ 3770ccd284c7SBarry Smith 3771cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 3772af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3773cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 3774af8000cdSHong Zhang #endif 377563c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 377663c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 37773dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 377863c07aadSStefano Zampini #endif 3779cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 378042c9c57cSBarry Smith 3781b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 378229b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 378329b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3784b3866ffcSBarry Smith #endif 378517667f90SBarry Smith 3786c0c8ee5eSDmitry Karpeev 37878c778c55SBarry Smith /*@C 37888397e458SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored 37898c778c55SBarry Smith 37908c778c55SBarry Smith Not Collective 37918c778c55SBarry Smith 37928c778c55SBarry Smith Input Parameter: 3793579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 37948c778c55SBarry Smith 37958c778c55SBarry Smith Output Parameter: 37968c778c55SBarry Smith . array - pointer to the data 37978c778c55SBarry Smith 37988c778c55SBarry Smith Level: intermediate 37998c778c55SBarry Smith 3800774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 38018c778c55SBarry Smith @*/ 38028c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 38038c778c55SBarry Smith { 38048c778c55SBarry Smith PetscErrorCode ierr; 38058c778c55SBarry Smith 38068c778c55SBarry Smith PetscFunctionBegin; 38078c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38088c778c55SBarry Smith PetscFunctionReturn(0); 38098c778c55SBarry Smith } 38108c778c55SBarry Smith 381121e72a00SBarry Smith /*@C 381221e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 381321e72a00SBarry Smith 381421e72a00SBarry Smith Not Collective 381521e72a00SBarry Smith 381621e72a00SBarry Smith Input Parameter: 3817579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 381821e72a00SBarry Smith 381921e72a00SBarry Smith Output Parameter: 382021e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 382121e72a00SBarry Smith 382221e72a00SBarry Smith Level: intermediate 382321e72a00SBarry Smith 382421e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 382521e72a00SBarry Smith @*/ 382621e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 382721e72a00SBarry Smith { 382821e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 382921e72a00SBarry Smith 383021e72a00SBarry Smith PetscFunctionBegin; 383121e72a00SBarry Smith *nz = aij->rmax; 383221e72a00SBarry Smith PetscFunctionReturn(0); 383321e72a00SBarry Smith } 383421e72a00SBarry Smith 38358c778c55SBarry Smith /*@C 3836579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 38378c778c55SBarry Smith 38388c778c55SBarry Smith Not Collective 38398c778c55SBarry Smith 38408c778c55SBarry Smith Input Parameters: 3841579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38428c778c55SBarry Smith . array - pointer to the data 38438c778c55SBarry Smith 38448c778c55SBarry Smith Level: intermediate 38458c778c55SBarry Smith 3846774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 38478c778c55SBarry Smith @*/ 38488c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 38498c778c55SBarry Smith { 38508c778c55SBarry Smith PetscErrorCode ierr; 38518c778c55SBarry Smith 38528c778c55SBarry Smith PetscFunctionBegin; 38538c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38548c778c55SBarry Smith PetscFunctionReturn(0); 38558c778c55SBarry Smith } 38568c778c55SBarry Smith 38578cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 3858273d9f13SBarry Smith { 3859273d9f13SBarry Smith Mat_SeqAIJ *b; 3860dfbe8321SBarry Smith PetscErrorCode ierr; 386138baddfdSBarry Smith PetscMPIInt size; 3862273d9f13SBarry Smith 3863273d9f13SBarry Smith PetscFunctionBegin; 3864ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 3865e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3866273d9f13SBarry Smith 3867b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 38682205254eSKarl Rupp 3869b0a32e0cSBarry Smith B->data = (void*)b; 38702205254eSKarl Rupp 3871549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 38722205254eSKarl Rupp 3873416022c9SBarry Smith b->row = 0; 3874416022c9SBarry Smith b->col = 0; 387582bf6240SBarry Smith b->icol = 0; 3876b810aeb4SBarry Smith b->reallocs = 0; 387736db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3878f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3879416022c9SBarry Smith b->nonew = 0; 3880416022c9SBarry Smith b->diag = 0; 3881416022c9SBarry Smith b->solve_work = 0; 38822a1b7f2aSHong Zhang B->spptr = 0; 3883be6bf707SBarry Smith b->saved_values = 0; 3884d7f994e1SBarry Smith b->idiag = 0; 388571f1c65dSBarry Smith b->mdiag = 0; 388671f1c65dSBarry Smith b->ssor_work = 0; 388771f1c65dSBarry Smith b->omega = 1.0; 388871f1c65dSBarry Smith b->fshift = 0.0; 388971f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3890bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3891a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 389217ab2063SBarry Smith 389335d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3894bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 3895bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 38968c778c55SBarry Smith 3897b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3898bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3899bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3900b3866ffcSBarry Smith #endif 390117f1a0eaSHong Zhang 3902bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3903bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3904bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3905bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3906bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3907bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3908bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3909af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3910af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 3911af8000cdSHong Zhang #endif 391263c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 391363c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 39143dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 391563c07aadSStefano Zampini #endif 3916b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 3917bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3918bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3921bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3922bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3923bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3924bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 39254108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 392617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 39273a40ed3dSBarry Smith PetscFunctionReturn(0); 392817ab2063SBarry Smith } 392917ab2063SBarry Smith 3930b24902e0SBarry Smith /* 3931b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3932b24902e0SBarry Smith */ 3933ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 393417ab2063SBarry Smith { 3935416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 39366849ba73SBarry Smith PetscErrorCode ierr; 3937d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 393817ab2063SBarry Smith 39393a40ed3dSBarry Smith PetscFunctionBegin; 3940273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3941273d9f13SBarry Smith 3942d5f3da31SBarry Smith C->factortype = A->factortype; 3943416022c9SBarry Smith c->row = 0; 3944416022c9SBarry Smith c->col = 0; 394582bf6240SBarry Smith c->icol = 0; 39466ad4291fSHong Zhang c->reallocs = 0; 394717ab2063SBarry Smith 39486ad4291fSHong Zhang C->assembled = PETSC_TRUE; 394917ab2063SBarry Smith 3950aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3951aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3952eec197d1SBarry Smith 3953dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 39543bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 395517ab2063SBarry Smith for (i=0; i<m; i++) { 3956416022c9SBarry Smith c->imax[i] = a->imax[i]; 3957416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 395817ab2063SBarry Smith } 395917ab2063SBarry Smith 396017ab2063SBarry Smith /* allocate the matrix space */ 3961f77e22a1SHong Zhang if (mallocmatspace) { 3962dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 39633bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 39642205254eSKarl Rupp 3965f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 39662205254eSKarl Rupp 396797f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 396817ab2063SBarry Smith if (m > 0) { 396997f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3970be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3971bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3972be6bf707SBarry Smith } else { 3973bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 397417ab2063SBarry Smith } 397508480c60SBarry Smith } 3976f77e22a1SHong Zhang } 397717ab2063SBarry Smith 39786ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3979416022c9SBarry Smith c->roworiented = a->roworiented; 3980416022c9SBarry Smith c->nonew = a->nonew; 3981416022c9SBarry Smith if (a->diag) { 3982854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 39833bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 398417ab2063SBarry Smith for (i=0; i<m; i++) { 3985416022c9SBarry Smith c->diag[i] = a->diag[i]; 398617ab2063SBarry Smith } 39873a40ed3dSBarry Smith } else c->diag = 0; 39882205254eSKarl Rupp 39896ad4291fSHong Zhang c->solve_work = 0; 39906ad4291fSHong Zhang c->saved_values = 0; 39916ad4291fSHong Zhang c->idiag = 0; 399271f1c65dSBarry Smith c->ssor_work = 0; 3993a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 3994e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3995e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 39966ad4291fSHong Zhang 3997893ad86cSHong Zhang c->rmax = a->rmax; 3998416022c9SBarry Smith c->nz = a->nz; 39998ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4000273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4001754ec7b1SSatish Balay 40026ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 40036ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4004cd6b891eSBarry Smith if (a->compressedrow.use) { 40056ad4291fSHong Zhang i = a->compressedrow.nrows; 4006dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 40076ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 40086ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 400927ea64f8SHong Zhang } else { 401027ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 40110298fd71SBarry Smith c->compressedrow.i = NULL; 40120298fd71SBarry Smith c->compressedrow.rindex = NULL; 40136ad4291fSHong Zhang } 4014ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4015e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 40164846f1f5SKris Buschelman 40172205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4018140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 40193a40ed3dSBarry Smith PetscFunctionReturn(0); 402017ab2063SBarry Smith } 402117ab2063SBarry Smith 4022b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4023b24902e0SBarry Smith { 4024b24902e0SBarry Smith PetscErrorCode ierr; 4025b24902e0SBarry Smith 4026b24902e0SBarry Smith PetscFunctionBegin; 4027ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 40284b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4029cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 403033d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4031cfd3f464SBarry Smith } 4032a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4033f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4034b24902e0SBarry Smith PetscFunctionReturn(0); 4035b24902e0SBarry Smith } 4036b24902e0SBarry Smith 4037112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4038fbdbba38SShri Abhyankar { 4039fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4040fbdbba38SShri Abhyankar PetscErrorCode ierr; 4041fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4042fbdbba38SShri Abhyankar int fd; 4043fbdbba38SShri Abhyankar PetscMPIInt size; 4044fbdbba38SShri Abhyankar MPI_Comm comm; 40453059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4046fbdbba38SShri Abhyankar 4047fbdbba38SShri Abhyankar PetscFunctionBegin; 4048c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 4049c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4050fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4051fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4052fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4053bbead8a2SBarry Smith 40540298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 40550298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4056bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 40573059b6faSBarry Smith if (bs < 0) bs = 1; 40583059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4059bbead8a2SBarry Smith 4060fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4061fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4062fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4063fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4064fbdbba38SShri Abhyankar 4065bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4066fbdbba38SShri Abhyankar 4067fbdbba38SShri Abhyankar /* read in row lengths */ 4068785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4069fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4070fbdbba38SShri Abhyankar 4071fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4072fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 407360e0710aSBarry 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); 4074fbdbba38SShri Abhyankar 4075fbdbba38SShri Abhyankar /* set global size if not set already*/ 4076f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4077fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4078aabbc4fbSShri Abhyankar } else { 40799d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4080fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 40814c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 40824c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 40834c5b953cSHong Zhang } 408460e0710aSBarry 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); 4085aabbc4fbSShri Abhyankar } 4086fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4087fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4088fbdbba38SShri Abhyankar 4089fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4090fbdbba38SShri Abhyankar 4091fbdbba38SShri Abhyankar /* read in nonzero values */ 4092fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4093fbdbba38SShri Abhyankar 4094fbdbba38SShri Abhyankar /* set matrix "i" values */ 4095fbdbba38SShri Abhyankar a->i[0] = 0; 4096fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4097fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4098fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4099fbdbba38SShri Abhyankar } 4100fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4101fbdbba38SShri Abhyankar 4102fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4103fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4104fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4105fbdbba38SShri Abhyankar } 4106fbdbba38SShri Abhyankar 4107ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 41087264ac53SSatish Balay { 41097264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4110dfbe8321SBarry Smith PetscErrorCode ierr; 4111eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4112eeffb40dSHong Zhang PetscInt k; 4113eeffb40dSHong Zhang #endif 41147264ac53SSatish Balay 41153a40ed3dSBarry Smith PetscFunctionBegin; 4116bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4117d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4118ca44d042SBarry Smith *flg = PETSC_FALSE; 4119ca44d042SBarry Smith PetscFunctionReturn(0); 4120bcd2baecSBarry Smith } 41217264ac53SSatish Balay 41227264ac53SSatish Balay /* if the a->i are the same */ 4123d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4124abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 41257264ac53SSatish Balay 41267264ac53SSatish Balay /* if a->j are the same */ 412797f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4128abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4129bcd2baecSBarry Smith 4130bcd2baecSBarry Smith /* if a->a are the same */ 4131eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4132eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4133eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4134eeffb40dSHong Zhang *flg = PETSC_FALSE; 41353a40ed3dSBarry Smith PetscFunctionReturn(0); 4136eeffb40dSHong Zhang } 4137eeffb40dSHong Zhang } 4138eeffb40dSHong Zhang #else 4139eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4140eeffb40dSHong Zhang #endif 4141eeffb40dSHong Zhang PetscFunctionReturn(0); 41427264ac53SSatish Balay } 414336db0b34SBarry Smith 414405869f15SSatish Balay /*@ 414536db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 414636db0b34SBarry Smith provided by the user. 414736db0b34SBarry Smith 4148c75a6043SHong Zhang Collective on MPI_Comm 414936db0b34SBarry Smith 415036db0b34SBarry Smith Input Parameters: 415136db0b34SBarry Smith + comm - must be an MPI communicator of size 1 415236db0b34SBarry Smith . m - number of rows 415336db0b34SBarry Smith . n - number of columns 415436db0b34SBarry Smith . i - row indices 415536db0b34SBarry Smith . j - column indices 415636db0b34SBarry Smith - a - matrix values 415736db0b34SBarry Smith 415836db0b34SBarry Smith Output Parameter: 415936db0b34SBarry Smith . mat - the matrix 416036db0b34SBarry Smith 416136db0b34SBarry Smith Level: intermediate 416236db0b34SBarry Smith 416336db0b34SBarry Smith Notes: 41640551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4165292fb18eSBarry Smith once the matrix is destroyed and not before 416636db0b34SBarry Smith 416736db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 416836db0b34SBarry Smith 4169bfeeae90SHong Zhang The i and j indices are 0 based 417036db0b34SBarry Smith 4171a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4172a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 41738eef79e4SBarry Smith as shown 4174a4552177SSatish Balay 41758eef79e4SBarry Smith $ 1 0 0 41768eef79e4SBarry Smith $ 2 0 3 41778eef79e4SBarry Smith $ 4 5 6 41788eef79e4SBarry Smith $ 41798eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 41808eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 41818eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4182a4552177SSatish Balay 41839985e31cSBarry Smith 418469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 418536db0b34SBarry Smith 418636db0b34SBarry Smith @*/ 4187c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 418836db0b34SBarry Smith { 4189dfbe8321SBarry Smith PetscErrorCode ierr; 4190cbcfb4deSHong Zhang PetscInt ii; 419136db0b34SBarry Smith Mat_SeqAIJ *aij; 4192cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4193cbcfb4deSHong Zhang PetscInt jj; 4194cbcfb4deSHong Zhang #endif 419536db0b34SBarry Smith 419636db0b34SBarry Smith PetscFunctionBegin; 419741096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4198f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4199f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4200a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4201ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4202ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4203ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4204dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4205ab93d7beSBarry Smith 420636db0b34SBarry Smith aij->i = i; 420736db0b34SBarry Smith aij->j = j; 420836db0b34SBarry Smith aij->a = a; 420936db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 421036db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4211e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4212e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 421336db0b34SBarry Smith 421436db0b34SBarry Smith for (ii=0; ii<m; ii++) { 421536db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 42162515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 421760e0710aSBarry 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]); 42189985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4219e32f2f54SBarry 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); 4220e32f2f54SBarry 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); 42219985e31cSBarry Smith } 422236db0b34SBarry Smith #endif 422336db0b34SBarry Smith } 42242515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 422536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 422660e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 422760e0710aSBarry 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]); 422836db0b34SBarry Smith } 422936db0b34SBarry Smith #endif 423036db0b34SBarry Smith 4231b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4232b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 423336db0b34SBarry Smith PetscFunctionReturn(0); 423436db0b34SBarry Smith } 423580ef6e79SMatthew G Knepley /*@C 4236d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 42378a0b0e6bSVictor Minden provided by the user. 42388a0b0e6bSVictor Minden 42398a0b0e6bSVictor Minden Collective on MPI_Comm 42408a0b0e6bSVictor Minden 42418a0b0e6bSVictor Minden Input Parameters: 42428a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 42438a0b0e6bSVictor Minden . m - number of rows 42448a0b0e6bSVictor Minden . n - number of columns 42458a0b0e6bSVictor Minden . i - row indices 42468a0b0e6bSVictor Minden . j - column indices 42471230e6d1SVictor Minden . a - matrix values 42481230e6d1SVictor Minden . nz - number of nonzeros 42491230e6d1SVictor Minden - idx - 0 or 1 based 42508a0b0e6bSVictor Minden 42518a0b0e6bSVictor Minden Output Parameter: 42528a0b0e6bSVictor Minden . mat - the matrix 42538a0b0e6bSVictor Minden 42548a0b0e6bSVictor Minden Level: intermediate 42558a0b0e6bSVictor Minden 42568a0b0e6bSVictor Minden Notes: 42578a0b0e6bSVictor Minden The i and j indices are 0 based 42588a0b0e6bSVictor Minden 42598a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 42608a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 42618a0b0e6bSVictor Minden as shown: 42628a0b0e6bSVictor Minden 42638a0b0e6bSVictor Minden 1 0 0 42648a0b0e6bSVictor Minden 2 0 3 42658a0b0e6bSVictor Minden 4 5 6 42668a0b0e6bSVictor Minden 42678a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 42688a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 42698a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 42708a0b0e6bSVictor Minden 42718a0b0e6bSVictor Minden 427269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 42738a0b0e6bSVictor Minden 42748a0b0e6bSVictor Minden @*/ 4275c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 42768a0b0e6bSVictor Minden { 42778a0b0e6bSVictor Minden PetscErrorCode ierr; 4278d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 42798a0b0e6bSVictor Minden 42808a0b0e6bSVictor Minden 42818a0b0e6bSVictor Minden PetscFunctionBegin; 42821795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 42831230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4284c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 42851230e6d1SVictor Minden } 42868a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 42878a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 42888a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 42891230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 42901230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 42911230e6d1SVictor Minden if (idx) { 42921230e6d1SVictor Minden row = i[ii] - 1; 42931230e6d1SVictor Minden col = j[ii] - 1; 42941230e6d1SVictor Minden } else { 42951230e6d1SVictor Minden row = i[ii]; 42961230e6d1SVictor Minden col = j[ii]; 42978a0b0e6bSVictor Minden } 42981230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 42998a0b0e6bSVictor Minden } 43008a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43018a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4302d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 43038a0b0e6bSVictor Minden PetscFunctionReturn(0); 43048a0b0e6bSVictor Minden } 430536db0b34SBarry Smith 4306acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4307acf2f550SJed Brown { 4308acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4309acf2f550SJed Brown PetscErrorCode ierr; 4310acf2f550SJed Brown 4311acf2f550SJed Brown PetscFunctionBegin; 4312acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4313acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 43142205254eSKarl Rupp 4315acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4316acf2f550SJed Brown PetscFunctionReturn(0); 4317acf2f550SJed Brown } 4318acf2f550SJed Brown 43199c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 43209c8f2541SHong Zhang { 43219c8f2541SHong Zhang PetscErrorCode ierr; 43228761c3d6SHong Zhang PetscMPIInt size; 43239c8f2541SHong Zhang 43249c8f2541SHong Zhang PetscFunctionBegin; 43258761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 43268761c3d6SHong Zhang if (size == 1 && scall == MAT_REUSE_MATRIX) { 43278761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 43288761c3d6SHong Zhang } else { 43299c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 43308761c3d6SHong Zhang } 43319c8f2541SHong Zhang PetscFunctionReturn(0); 43329c8f2541SHong Zhang } 43339c8f2541SHong Zhang 433481824310SBarry Smith /* 433553dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 433653dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 433753dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 433853dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 433953dd7562SDmitry Karpeev */ 434053dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 434153dd7562SDmitry Karpeev { 434253dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 434353dd7562SDmitry Karpeev PetscErrorCode ierr; 434453dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 434553dd7562SDmitry Karpeev PetscBool seqaij; 434653dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 434753dd7562SDmitry Karpeev PetscScalar v; 434853dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 434953dd7562SDmitry Karpeev 435053dd7562SDmitry Karpeev PetscFunctionBegin; 435153dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 435253dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 435353dd7562SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 435453dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 435553dd7562SDmitry Karpeev if (rowemb) { 435653dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 435753dd7562SDmitry 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); 435853dd7562SDmitry Karpeev } else { 43596c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 436053dd7562SDmitry Karpeev } 436153dd7562SDmitry Karpeev if (colemb) { 436253dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 436353dd7562SDmitry 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); 436453dd7562SDmitry Karpeev } else { 436553dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 436653dd7562SDmitry Karpeev } 436753dd7562SDmitry Karpeev 436853dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 436953dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 437053dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 437153dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 437253dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 437353dd7562SDmitry Karpeev } 437453dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 437553dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 437653dd7562SDmitry Karpeev } 437753dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 437853dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 437953dd7562SDmitry Karpeev } 438053dd7562SDmitry Karpeev count = 0; 438153dd7562SDmitry Karpeev rowindices = NULL; 438253dd7562SDmitry Karpeev colindices = NULL; 438353dd7562SDmitry Karpeev if (rowemb) { 438453dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 438553dd7562SDmitry Karpeev } 438653dd7562SDmitry Karpeev if (colemb) { 438753dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 438853dd7562SDmitry Karpeev } 438953dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 439053dd7562SDmitry Karpeev PetscInt row; 439153dd7562SDmitry Karpeev row = i; 439253dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 439353dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 439453dd7562SDmitry Karpeev PetscInt col; 439553dd7562SDmitry Karpeev col = Baij->j[count]; 439653dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 439753dd7562SDmitry Karpeev v = Baij->a[count]; 439853dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 439953dd7562SDmitry Karpeev ++count; 440053dd7562SDmitry Karpeev } 440153dd7562SDmitry Karpeev } 440253dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 440353dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 440453dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 440553dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 440653dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 440753dd7562SDmitry Karpeev PetscFunctionReturn(0); 440853dd7562SDmitry Karpeev } 440953dd7562SDmitry Karpeev 441053dd7562SDmitry Karpeev 441153dd7562SDmitry Karpeev /* 441281824310SBarry Smith Special version for direct calls from Fortran 441381824310SBarry Smith */ 4414af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 441581824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 441681824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 441781824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 441881824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 441981824310SBarry Smith #endif 442081824310SBarry Smith 442181824310SBarry Smith /* Change these macros so can be used in void function */ 442281824310SBarry Smith #undef CHKERRQ 4423ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 442481824310SBarry Smith #undef SETERRQ2 4425e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 44264994cf47SJed Brown #undef SETERRQ3 44274994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 442881824310SBarry Smith 44298cc058d9SJed 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) 443081824310SBarry Smith { 443181824310SBarry Smith Mat A = *AA; 443281824310SBarry Smith PetscInt m = *mm, n = *nn; 443381824310SBarry Smith InsertMode is = *isis; 443481824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 443581824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 443681824310SBarry Smith PetscInt *imax,*ai,*ailen; 443781824310SBarry Smith PetscErrorCode ierr; 443881824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 443954f21887SBarry Smith MatScalar *ap,value,*aa; 4440ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4441ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 444281824310SBarry Smith 444381824310SBarry Smith PetscFunctionBegin; 44444994cf47SJed Brown MatCheckPreallocated(A,1); 444581824310SBarry Smith imax = a->imax; 444681824310SBarry Smith ai = a->i; 444781824310SBarry Smith ailen = a->ilen; 444881824310SBarry Smith aj = a->j; 444981824310SBarry Smith aa = a->a; 445081824310SBarry Smith 445181824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 445281824310SBarry Smith row = im[k]; 445381824310SBarry Smith if (row < 0) continue; 445481824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4455ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 445681824310SBarry Smith #endif 445781824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 445881824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 445981824310SBarry Smith low = 0; 446081824310SBarry Smith high = nrow; 446181824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 446281824310SBarry Smith if (in[l] < 0) continue; 446381824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4464ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 446581824310SBarry Smith #endif 446681824310SBarry Smith col = in[l]; 44672205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 44682205254eSKarl Rupp else value = v[k + l*m]; 44692205254eSKarl Rupp 447081824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 447181824310SBarry Smith 44722205254eSKarl Rupp if (col <= lastcol) low = 0; 44732205254eSKarl Rupp else high = nrow; 447481824310SBarry Smith lastcol = col; 447581824310SBarry Smith while (high-low > 5) { 447681824310SBarry Smith t = (low+high)/2; 447781824310SBarry Smith if (rp[t] > col) high = t; 447881824310SBarry Smith else low = t; 447981824310SBarry Smith } 448081824310SBarry Smith for (i=low; i<high; i++) { 448181824310SBarry Smith if (rp[i] > col) break; 448281824310SBarry Smith if (rp[i] == col) { 448381824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 448481824310SBarry Smith else ap[i] = value; 448581824310SBarry Smith goto noinsert; 448681824310SBarry Smith } 448781824310SBarry Smith } 448881824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 448981824310SBarry Smith if (nonew == 1) goto noinsert; 4490ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4491fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 449281824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 449381824310SBarry Smith /* shift up all the later entries in this row */ 449481824310SBarry Smith for (ii=N; ii>=i; ii--) { 449581824310SBarry Smith rp[ii+1] = rp[ii]; 449681824310SBarry Smith ap[ii+1] = ap[ii]; 449781824310SBarry Smith } 449881824310SBarry Smith rp[i] = col; 449981824310SBarry Smith ap[i] = value; 4500e56f5c9eSBarry Smith A->nonzerostate++; 450181824310SBarry Smith noinsert:; 450281824310SBarry Smith low = i + 1; 450381824310SBarry Smith } 450481824310SBarry Smith ailen[row] = nrow; 450581824310SBarry Smith } 450681824310SBarry Smith PetscFunctionReturnVoid(); 450781824310SBarry Smith } 45089f7953f8SBarry Smith 4509