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 } 433*dcd36c23SBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) 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 } 452*dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) 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; 56143e49210SHong Zhang if (!a->a) PetscFunctionReturn(0); 56243e49210SHong Zhang 563b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 56471c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 56597f1f81fSBarry Smith PetscInt nofinalvalue = 0; 56660e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 567c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 568d00d2cf4SBarry Smith nofinalvalue = 1; 569d00d2cf4SBarry Smith } 570d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 571d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 57277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 573fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 574fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 575fbfe6fa7SJed Brown #else 57677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 577fbfe6fa7SJed Brown #endif 578b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 57917ab2063SBarry Smith 58017ab2063SBarry Smith for (i=0; i<m; i++) { 58160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 582aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 583a9bf72d8SJed 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); 58417ab2063SBarry Smith #else 58560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 58617ab2063SBarry Smith #endif 58717ab2063SBarry Smith } 58817ab2063SBarry Smith } 589d00d2cf4SBarry Smith if (nofinalvalue) { 590c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 591c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 592c337ccceSJed Brown #else 593d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 594c337ccceSJed Brown #endif 595d00d2cf4SBarry Smith } 596317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 597fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 598d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 59968369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 600cd155464SBarry Smith PetscFunctionReturn(0); 601fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 602d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 60344cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 60477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 60560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 606aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 60736db0b34SBarry Smith 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 (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 61060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 61136db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 61260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6136831982aSBarry Smith } 61444cd7ae7SLois Curfman McInnes #else 61560e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 61644cd7ae7SLois Curfman McInnes #endif 61744cd7ae7SLois Curfman McInnes } 618b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 61944cd7ae7SLois Curfman McInnes } 620d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 621fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 62297f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 623d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 624854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 625496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 626496be53dSLois Curfman McInnes sptr[i] = nzd+1; 62760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 628496be53dSLois Curfman McInnes if (a->j[j] >= i) { 629aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 63036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 631496be53dSLois Curfman McInnes #else 632496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 633496be53dSLois Curfman McInnes #endif 634496be53dSLois Curfman McInnes } 635496be53dSLois Curfman McInnes } 636496be53dSLois Curfman McInnes } 6372e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 63877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 6392e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 6402205254eSKarl Rupp if (i+4<m) { 6412205254eSKarl 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); 6422205254eSKarl Rupp } else if (i+3<m) { 6432205254eSKarl 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); 6442205254eSKarl Rupp } else if (i+2<m) { 6452205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6462205254eSKarl Rupp } else if (i+1<m) { 6472205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6482205254eSKarl Rupp } else if (i<m) { 6492205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6502205254eSKarl Rupp } else { 6512205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6522205254eSKarl Rupp } 653496be53dSLois Curfman McInnes } 654b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 655606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 656496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 65760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 65877431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 659496be53dSLois Curfman McInnes } 660b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 661496be53dSLois Curfman McInnes } 662b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 663496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 66460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 665496be53dSLois Curfman McInnes if (a->j[j] >= i) { 666aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 66736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 66860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6696831982aSBarry Smith } 670496be53dSLois Curfman McInnes #else 67160e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 672496be53dSLois Curfman McInnes #endif 673496be53dSLois Curfman McInnes } 674496be53dSLois Curfman McInnes } 675b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 676496be53dSLois Curfman McInnes } 677d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 678fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 67997f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 68087828ca2SBarry Smith PetscScalar value; 68168f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 68268f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 68368f1ed48SBarry Smith 68468f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 68568f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 68668f1ed48SBarry Smith realonly = PETSC_FALSE; 68768f1ed48SBarry Smith break; 68868f1ed48SBarry Smith } 68968f1ed48SBarry Smith } 69068f1ed48SBarry Smith #endif 69102594712SBarry Smith 692d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 69302594712SBarry Smith for (i=0; i<m; i++) { 69402594712SBarry Smith jcnt = 0; 695d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 696e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 69702594712SBarry Smith value = a->a[cnt++]; 698e24b481bSBarry Smith jcnt++; 69902594712SBarry Smith } else { 70002594712SBarry Smith value = 0.0; 70102594712SBarry Smith } 702aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70368f1ed48SBarry Smith if (realonly) { 70460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 70568f1ed48SBarry Smith } else { 70660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 70768f1ed48SBarry Smith } 70802594712SBarry Smith #else 70960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 71002594712SBarry Smith #endif 71102594712SBarry Smith } 712b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 71302594712SBarry Smith } 714d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7153c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 716150b93efSMatthew G. Knepley PetscInt fshift=1; 717d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7183c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 71919303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 7203c215bfdSMatthew Knepley #else 72119303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 7223c215bfdSMatthew Knepley #endif 723d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 7243c215bfdSMatthew Knepley for (i=0; i<m; i++) { 72560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 7263c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 727a9a0e077SKarl 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); 7283c215bfdSMatthew Knepley #else 729150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 7303c215bfdSMatthew Knepley #endif 7313c215bfdSMatthew Knepley } 7323c215bfdSMatthew Knepley } 733d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7343a40ed3dSBarry Smith } else { 735d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 736d5f3da31SBarry Smith if (A->factortype) { 73716cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 73816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 73916cd7e1dSShri Abhyankar /* L part */ 74060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 74116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 74216cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 74360e0710aSBarry 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 if (PetscImaginaryPart(a->a[j]) < 0.0) { 7456712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 74616cd7e1dSShri Abhyankar } else { 74760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 74816cd7e1dSShri Abhyankar } 74916cd7e1dSShri Abhyankar #else 75060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 75116cd7e1dSShri Abhyankar #endif 75216cd7e1dSShri Abhyankar } 75316cd7e1dSShri Abhyankar /* diagonal */ 75416cd7e1dSShri Abhyankar j = a->diag[i]; 75516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 75616cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 75760e0710aSBarry 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 if (PetscImaginaryPart(a->a[j]) < 0.0) { 7596712e2f1SBarry 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); 76016cd7e1dSShri Abhyankar } else { 76160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 76216cd7e1dSShri Abhyankar } 76316cd7e1dSShri Abhyankar #else 76460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 76516cd7e1dSShri Abhyankar #endif 76616cd7e1dSShri Abhyankar 76716cd7e1dSShri Abhyankar /* U part */ 76860e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 76916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 77016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 77160e0710aSBarry 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 if (PetscImaginaryPart(a->a[j]) < 0.0) { 77322ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 77416cd7e1dSShri Abhyankar } else { 77560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 77616cd7e1dSShri Abhyankar } 77716cd7e1dSShri Abhyankar #else 77860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 77916cd7e1dSShri Abhyankar #endif 78016cd7e1dSShri Abhyankar } 78116cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 78216cd7e1dSShri Abhyankar } 78316cd7e1dSShri Abhyankar } else { 78417ab2063SBarry Smith for (i=0; i<m; i++) { 78577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 78660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 787aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 78836db0b34SBarry Smith 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); 79036db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 79160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7923a40ed3dSBarry Smith } else { 79360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 79417ab2063SBarry Smith } 79517ab2063SBarry Smith #else 79660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 79717ab2063SBarry Smith #endif 79817ab2063SBarry Smith } 799b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 80017ab2063SBarry Smith } 80116cd7e1dSShri Abhyankar } 802d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 80317ab2063SBarry Smith } 804b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8053a40ed3dSBarry Smith PetscFunctionReturn(0); 806416022c9SBarry Smith } 807416022c9SBarry Smith 8089804daf3SBarry Smith #include <petscdraw.h> 809dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 810416022c9SBarry Smith { 811480ef9eaSBarry Smith Mat A = (Mat) Aa; 812416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 813dfbe8321SBarry Smith PetscErrorCode ierr; 814383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 815383922c3SLisandro Dalcin int color; 816b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 817b0a32e0cSBarry Smith PetscViewer viewer; 818f3ef73ceSBarry Smith PetscViewerFormat format; 819cddf8d76SBarry Smith 8203a40ed3dSBarry Smith PetscFunctionBegin; 821480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 822b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 823b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 824383922c3SLisandro Dalcin 825416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 8260513a670SBarry Smith 827fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 828383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8290513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 830b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 831416022c9SBarry Smith for (i=0; i<m; i++) { 832cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 833bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 834bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 83536db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 836b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 837cddf8d76SBarry Smith } 838cddf8d76SBarry Smith } 839b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 840cddf8d76SBarry Smith for (i=0; i<m; i++) { 841cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 842bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 843bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 844cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 845b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 846cddf8d76SBarry Smith } 847cddf8d76SBarry Smith } 848b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 849cddf8d76SBarry Smith for (i=0; i<m; i++) { 850cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 851bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 852bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 85336db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 854b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 855416022c9SBarry Smith } 856416022c9SBarry Smith } 857383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8580513a670SBarry Smith } else { 8590513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8600513a670SBarry Smith /* first determine max of all nonzero values */ 861b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 862383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 863b0a32e0cSBarry Smith PetscDraw popup; 8640513a670SBarry Smith 8650513a670SBarry Smith for (i=0; i<nz; i++) { 8660513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8670513a670SBarry Smith } 868383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 869b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 87045f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 871383922c3SLisandro Dalcin 872383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8730513a670SBarry Smith for (i=0; i<m; i++) { 874383922c3SLisandro Dalcin y_l = m - i - 1.0; 875383922c3SLisandro Dalcin y_r = y_l + 1.0; 876bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 877383922c3SLisandro Dalcin x_l = a->j[j]; 878383922c3SLisandro Dalcin x_r = x_l + 1.0; 879b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 880b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8810513a670SBarry Smith count++; 8820513a670SBarry Smith } 8830513a670SBarry Smith } 884383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8850513a670SBarry Smith } 886480ef9eaSBarry Smith PetscFunctionReturn(0); 887480ef9eaSBarry Smith } 888cddf8d76SBarry Smith 8899804daf3SBarry Smith #include <petscdraw.h> 890dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 891480ef9eaSBarry Smith { 892dfbe8321SBarry Smith PetscErrorCode ierr; 893b0a32e0cSBarry Smith PetscDraw draw; 89436db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 895ace3abfcSBarry Smith PetscBool isnull; 896480ef9eaSBarry Smith 897480ef9eaSBarry Smith PetscFunctionBegin; 898b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 899b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 900480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 901480ef9eaSBarry Smith 902d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 903480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 904b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 905832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 906b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 9070298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 908832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 9093a40ed3dSBarry Smith PetscFunctionReturn(0); 910416022c9SBarry Smith } 911416022c9SBarry Smith 912dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 913416022c9SBarry Smith { 914dfbe8321SBarry Smith PetscErrorCode ierr; 915ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 916416022c9SBarry Smith 9173a40ed3dSBarry Smith PetscFunctionBegin; 918251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 919251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 920251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 921c45a1595SBarry Smith if (iascii) { 9223a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 9230f5bd95cSBarry Smith } else if (isbinary) { 9243a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 9250f5bd95cSBarry Smith } else if (isdraw) { 9263a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 92711aeaf0aSBarry Smith } 9284108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 9293a40ed3dSBarry Smith PetscFunctionReturn(0); 93017ab2063SBarry Smith } 93119bcc07fSBarry Smith 932dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 93317ab2063SBarry Smith { 934416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9356849ba73SBarry Smith PetscErrorCode ierr; 93697f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 937d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 93854f21887SBarry Smith MatScalar *aa = a->a,*ap; 9393447b6efSHong Zhang PetscReal ratio = 0.6; 94017ab2063SBarry Smith 9413a40ed3dSBarry Smith PetscFunctionBegin; 9423a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 94317ab2063SBarry Smith 94443ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 94517ab2063SBarry Smith for (i=1; i<m; i++) { 946416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 94717ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 94894a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 94917ab2063SBarry Smith if (fshift) { 950bfeeae90SHong Zhang ip = aj + ai[i]; 951bfeeae90SHong Zhang ap = aa + ai[i]; 95217ab2063SBarry Smith N = ailen[i]; 95317ab2063SBarry Smith for (j=0; j<N; j++) { 95417ab2063SBarry Smith ip[j-fshift] = ip[j]; 95517ab2063SBarry Smith ap[j-fshift] = ap[j]; 95617ab2063SBarry Smith } 95717ab2063SBarry Smith } 95817ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 95917ab2063SBarry Smith } 96017ab2063SBarry Smith if (m) { 96117ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 96217ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 96317ab2063SBarry Smith } 9647b083b7cSBarry Smith 96517ab2063SBarry Smith /* reset ilen and imax for each row */ 9667b083b7cSBarry Smith a->nonzerorowcnt = 0; 96717ab2063SBarry Smith for (i=0; i<m; i++) { 96817ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 9697b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 97017ab2063SBarry Smith } 971bfeeae90SHong Zhang a->nz = ai[m]; 97265e19b50SBarry 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); 97317ab2063SBarry Smith 97409f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 975d0f46423SBarry 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); 976ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 977ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9782205254eSKarl Rupp 9798e58a170SBarry Smith A->info.mallocs += a->reallocs; 980dd5f02e7SSatish Balay a->reallocs = 0; 9816712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 98236db0b34SBarry Smith a->rmax = rmax; 9834e220ebcSLois Curfman McInnes 98411e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 9854108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 986acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9873a40ed3dSBarry Smith PetscFunctionReturn(0); 98817ab2063SBarry Smith } 98917ab2063SBarry Smith 99099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 99199cafbc1SBarry Smith { 99299cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 99399cafbc1SBarry Smith PetscInt i,nz = a->nz; 99454f21887SBarry Smith MatScalar *aa = a->a; 995acf2f550SJed Brown PetscErrorCode ierr; 99699cafbc1SBarry Smith 99799cafbc1SBarry Smith PetscFunctionBegin; 99899cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 999acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 100099cafbc1SBarry Smith PetscFunctionReturn(0); 100199cafbc1SBarry Smith } 100299cafbc1SBarry Smith 100399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 100499cafbc1SBarry Smith { 100599cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 100699cafbc1SBarry Smith PetscInt i,nz = a->nz; 100754f21887SBarry Smith MatScalar *aa = a->a; 1008acf2f550SJed Brown PetscErrorCode ierr; 100999cafbc1SBarry Smith 101099cafbc1SBarry Smith PetscFunctionBegin; 101199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1012acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 101399cafbc1SBarry Smith PetscFunctionReturn(0); 101499cafbc1SBarry Smith } 101599cafbc1SBarry Smith 1016dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 101717ab2063SBarry Smith { 1018416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1019dfbe8321SBarry Smith PetscErrorCode ierr; 10203a40ed3dSBarry Smith 10213a40ed3dSBarry Smith PetscFunctionBegin; 1022d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1023acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10243a40ed3dSBarry Smith PetscFunctionReturn(0); 102517ab2063SBarry Smith } 1026416022c9SBarry Smith 1027dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 102817ab2063SBarry Smith { 1029416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1030dfbe8321SBarry Smith PetscErrorCode ierr; 1031d5d45c9bSBarry Smith 10323a40ed3dSBarry Smith PetscFunctionBegin; 1033aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1034d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 103517ab2063SBarry Smith #endif 1036e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10376bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10386bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 103905b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1040d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 104105b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 104271f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 104305b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10446bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 104505b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10466bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1047cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10480b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1049a30b2313SHong Zhang 10504108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1051bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1052901853e0SKris Buschelman 1053dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1055bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1058bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1059bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1060af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1061af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1062af8000cdSHong Zhang #endif 106363c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 106463c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 10653dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 106663c07aadSStefano Zampini #endif 1067b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1068bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1069bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1070bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1071bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10723a40ed3dSBarry Smith PetscFunctionReturn(0); 107317ab2063SBarry Smith } 107417ab2063SBarry Smith 1075ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 107617ab2063SBarry Smith { 1077416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10784846f1f5SKris Buschelman PetscErrorCode ierr; 10793a40ed3dSBarry Smith 10803a40ed3dSBarry Smith PetscFunctionBegin; 1081a65d3064SKris Buschelman switch (op) { 1082a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 10834e0d8c25SBarry Smith a->roworiented = flg; 1084a65d3064SKris Buschelman break; 1085a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1086a9817697SBarry Smith a->keepnonzeropattern = flg; 1087a65d3064SKris Buschelman break; 1088512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1089512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1090a65d3064SKris Buschelman break; 1091a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 10924e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1093a65d3064SKris Buschelman break; 1094a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 10954e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1096a65d3064SKris Buschelman break; 109728b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 109828b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 109928b2fa4aSMatthew Knepley break; 1100a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 11014e0d8c25SBarry Smith a->ignorezeroentries = flg; 11020df259c2SBarry Smith break; 11033d472b54SHong Zhang case MAT_SPD: 1104b1646e73SJed Brown case MAT_SYMMETRIC: 1105b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1106b1646e73SJed Brown case MAT_HERMITIAN: 1107b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 11085021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11095021d80fSJed Brown break; 11104e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1111a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1112a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1113290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1114a65d3064SKris Buschelman break; 1115b87ac2d8SJed Brown case MAT_USE_INODES: 1116b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1117b87ac2d8SJed Brown break; 1118c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1119c10200c1SHong Zhang A->submat_singleis = flg; 1120c10200c1SHong Zhang break; 1121a65d3064SKris Buschelman default: 1122e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1123a65d3064SKris Buschelman } 11244108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11253a40ed3dSBarry Smith PetscFunctionReturn(0); 112617ab2063SBarry Smith } 112717ab2063SBarry Smith 1128dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 112917ab2063SBarry Smith { 1130416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11316849ba73SBarry Smith PetscErrorCode ierr; 1132d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 113335e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 113417ab2063SBarry Smith 11353a40ed3dSBarry Smith PetscFunctionBegin; 1136d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1137e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 113835e7444dSHong Zhang 1139d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1140d3e70bfaSHong Zhang PetscInt *diag=a->diag; 114135e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11422c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 114335e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 114435e7444dSHong Zhang PetscFunctionReturn(0); 114535e7444dSHong Zhang } 114635e7444dSHong Zhang 11472dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11481ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 114935e7444dSHong Zhang for (i=0; i<n; i++) { 115035e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11512f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 115235e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 115335e7444dSHong Zhang if (aj[j] == i) { 115435e7444dSHong Zhang x[i] = aa[j]; 115517ab2063SBarry Smith break; 115617ab2063SBarry Smith } 115717ab2063SBarry Smith } 115817ab2063SBarry Smith } 11591ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11603a40ed3dSBarry Smith PetscFunctionReturn(0); 116117ab2063SBarry Smith } 116217ab2063SBarry Smith 1163c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1164dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 116517ab2063SBarry Smith { 1166416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1167d9ca1df4SBarry Smith PetscScalar *y; 1168d9ca1df4SBarry Smith const PetscScalar *x; 1169dfbe8321SBarry Smith PetscErrorCode ierr; 1170d0f46423SBarry Smith PetscInt m = A->rmap->n; 11715c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1172d9ca1df4SBarry Smith const MatScalar *v; 1173a77337e4SBarry Smith PetscScalar alpha; 1174d9ca1df4SBarry Smith PetscInt n,i,j; 1175d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 11763447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1177ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11785c897100SBarry Smith #endif 117917ab2063SBarry Smith 11803a40ed3dSBarry Smith PetscFunctionBegin; 11812e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1182d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 11831ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11845c897100SBarry Smith 11855c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1186bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 11875c897100SBarry Smith #else 11883447b6efSHong Zhang if (usecprow) { 11893447b6efSHong Zhang m = cprow.nrows; 11903447b6efSHong Zhang ii = cprow.i; 11917b2bb3b9SHong Zhang ridx = cprow.rindex; 11923447b6efSHong Zhang } else { 11933447b6efSHong Zhang ii = a->i; 11943447b6efSHong Zhang } 119517ab2063SBarry Smith for (i=0; i<m; i++) { 11963447b6efSHong Zhang idx = a->j + ii[i]; 11973447b6efSHong Zhang v = a->a + ii[i]; 11983447b6efSHong Zhang n = ii[i+1] - ii[i]; 11993447b6efSHong Zhang if (usecprow) { 12007b2bb3b9SHong Zhang alpha = x[ridx[i]]; 12013447b6efSHong Zhang } else { 120217ab2063SBarry Smith alpha = x[i]; 12033447b6efSHong Zhang } 120404fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 120517ab2063SBarry Smith } 12065c897100SBarry Smith #endif 1207dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1208d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12091ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12103a40ed3dSBarry Smith PetscFunctionReturn(0); 121117ab2063SBarry Smith } 121217ab2063SBarry Smith 1213dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12145c897100SBarry Smith { 1215dfbe8321SBarry Smith PetscErrorCode ierr; 12165c897100SBarry Smith 12175c897100SBarry Smith PetscFunctionBegin; 1218170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12195c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12205c897100SBarry Smith PetscFunctionReturn(0); 12215c897100SBarry Smith } 12225c897100SBarry Smith 1223c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 122478b84d54SShri Abhyankar 1225dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 122617ab2063SBarry Smith { 1227416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1228d9fead3dSBarry Smith PetscScalar *y; 122954f21887SBarry Smith const PetscScalar *x; 123054f21887SBarry Smith const MatScalar *aa; 1231dfbe8321SBarry Smith PetscErrorCode ierr; 1232003131ecSBarry Smith PetscInt m=A->rmap->n; 12330298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 12347b083b7cSBarry Smith PetscInt n,i; 1235362ced78SSatish Balay PetscScalar sum; 1236ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 123717ab2063SBarry Smith 1238b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 123997952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1240fee21e36SBarry Smith #endif 1241fee21e36SBarry Smith 12423a40ed3dSBarry Smith PetscFunctionBegin; 12433649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12441ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1245416022c9SBarry Smith ii = a->i; 12464eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 12474f390cb1SBarry Smith ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr); 124897952fefSHong Zhang m = a->compressedrow.nrows; 124997952fefSHong Zhang ii = a->compressedrow.i; 125097952fefSHong Zhang ridx = a->compressedrow.rindex; 125197952fefSHong Zhang for (i=0; i<m; i++) { 125297952fefSHong Zhang n = ii[i+1] - ii[i]; 125397952fefSHong Zhang aj = a->j + ii[i]; 125497952fefSHong Zhang aa = a->a + ii[i]; 125597952fefSHong Zhang sum = 0.0; 1256003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1257003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 125897952fefSHong Zhang y[*ridx++] = sum; 125997952fefSHong Zhang } 126097952fefSHong Zhang } else { /* do not use compressed row format */ 1261b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 12623d3eaba7SBarry Smith aj = a->j; 12633d3eaba7SBarry Smith aa = a->a; 1264b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1265b05257ddSBarry Smith #else 126617ab2063SBarry Smith for (i=0; i<m; i++) { 1267003131ecSBarry Smith n = ii[i+1] - ii[i]; 1268003131ecSBarry Smith aj = a->j + ii[i]; 1269003131ecSBarry Smith aa = a->a + ii[i]; 127017ab2063SBarry Smith sum = 0.0; 1271003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 127217ab2063SBarry Smith y[i] = sum; 127317ab2063SBarry Smith } 12748d195f9aSBarry Smith #endif 1275b05257ddSBarry Smith } 12767b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 12773649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12781ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12793a40ed3dSBarry Smith PetscFunctionReturn(0); 128017ab2063SBarry Smith } 128117ab2063SBarry Smith 1282b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1283b434eb95SMatthew G. Knepley { 1284b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1285b434eb95SMatthew G. Knepley PetscScalar *y; 1286b434eb95SMatthew G. Knepley const PetscScalar *x; 1287b434eb95SMatthew G. Knepley const MatScalar *aa; 1288b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1289b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1290b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1291b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1292b434eb95SMatthew G. Knepley PetscScalar sum; 1293b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1294b434eb95SMatthew G. Knepley 1295b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1296b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1297b434eb95SMatthew G. Knepley #endif 1298b434eb95SMatthew G. Knepley 1299b434eb95SMatthew G. Knepley PetscFunctionBegin; 1300b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1301b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1302b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1303b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1304b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1305b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1306b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1307b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1308b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1309b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1310b434eb95SMatthew G. Knepley sum = 0.0; 1311b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1312b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1313b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1314b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1315b434eb95SMatthew G. Knepley } 1316b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13173d3eaba7SBarry Smith ii = a->i; 1318b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1319b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1320b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1321b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1322b434eb95SMatthew G. Knepley sum = 0.0; 1323b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1324b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1325b434eb95SMatthew G. Knepley y[i] = sum; 1326b434eb95SMatthew G. Knepley } 1327b434eb95SMatthew G. Knepley } 1328b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1329b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1330b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1331b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1332b434eb95SMatthew G. Knepley } 1333b434eb95SMatthew G. Knepley 1334b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1335b434eb95SMatthew G. Knepley { 1336b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1337b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1338b434eb95SMatthew G. Knepley const PetscScalar *x; 1339b434eb95SMatthew G. Knepley const MatScalar *aa; 1340b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1341b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1342b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1343b434eb95SMatthew G. Knepley PetscScalar sum; 1344b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1345b434eb95SMatthew G. Knepley 1346b434eb95SMatthew G. Knepley PetscFunctionBegin; 1347b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1348d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1349b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1350b434eb95SMatthew G. Knepley if (zz != yy) { 1351b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1352b434eb95SMatthew G. Knepley } 1353b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1354b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1355b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1356b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1357b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1358b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1359b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1360b434eb95SMatthew G. Knepley sum = y[*ridx]; 1361b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1362b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1363b434eb95SMatthew G. Knepley } 1364b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13653d3eaba7SBarry Smith ii = a->i; 1366b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1367b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1368b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1369b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1370b434eb95SMatthew G. Knepley sum = y[i]; 1371b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1372b434eb95SMatthew G. Knepley z[i] = sum; 1373b434eb95SMatthew G. Knepley } 1374b434eb95SMatthew G. Knepley } 1375b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1376b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1377d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1378b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1379b434eb95SMatthew G. Knepley } 1380b434eb95SMatthew G. Knepley 1381c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1382dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 138317ab2063SBarry Smith { 1384416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1385f15663dcSBarry Smith PetscScalar *y,*z; 1386f15663dcSBarry Smith const PetscScalar *x; 138754f21887SBarry Smith const MatScalar *aa; 1388dfbe8321SBarry Smith PetscErrorCode ierr; 1389d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1390d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1391362ced78SSatish Balay PetscScalar sum; 1392ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 13939ea0dfa2SSatish Balay 13943a40ed3dSBarry Smith PetscFunctionBegin; 1395f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1396d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 13974eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 13984eb6d288SHong Zhang if (zz != yy) { 13994eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 14004eb6d288SHong Zhang } 140197952fefSHong Zhang m = a->compressedrow.nrows; 140297952fefSHong Zhang ii = a->compressedrow.i; 140397952fefSHong Zhang ridx = a->compressedrow.rindex; 140497952fefSHong Zhang for (i=0; i<m; i++) { 140597952fefSHong Zhang n = ii[i+1] - ii[i]; 140697952fefSHong Zhang aj = a->j + ii[i]; 140797952fefSHong Zhang aa = a->a + ii[i]; 140897952fefSHong Zhang sum = y[*ridx]; 1409f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 141097952fefSHong Zhang z[*ridx++] = sum; 141197952fefSHong Zhang } 141297952fefSHong Zhang } else { /* do not use compressed row format */ 14133d3eaba7SBarry Smith ii = a->i; 1414f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 14153d3eaba7SBarry Smith aj = a->j; 14163d3eaba7SBarry Smith aa = a->a; 1417f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1418f15663dcSBarry Smith #else 141917ab2063SBarry Smith for (i=0; i<m; i++) { 1420f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1421f15663dcSBarry Smith aj = a->j + ii[i]; 1422f15663dcSBarry Smith aa = a->a + ii[i]; 142317ab2063SBarry Smith sum = y[i]; 1424f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 142517ab2063SBarry Smith z[i] = sum; 142617ab2063SBarry Smith } 142702ab625aSSatish Balay #endif 1428f15663dcSBarry Smith } 1429dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1430f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1431d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14328154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14336b375ea7SVictor Minden /* 1434918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1435918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1436918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14376b375ea7SVictor Minden */ 1438918e98c3SVictor Minden #endif 14393a40ed3dSBarry Smith PetscFunctionReturn(0); 144017ab2063SBarry Smith } 144117ab2063SBarry Smith 144217ab2063SBarry Smith /* 144317ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 144417ab2063SBarry Smith */ 1445dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 144617ab2063SBarry Smith { 1447416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14486849ba73SBarry Smith PetscErrorCode ierr; 1449d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 145017ab2063SBarry Smith 14513a40ed3dSBarry Smith PetscFunctionBegin; 145209f38230SBarry Smith if (!a->diag) { 1453785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 14543bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 145509f38230SBarry Smith } 1456d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 145709f38230SBarry Smith a->diag[i] = a->i[i+1]; 1458bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1459bfeeae90SHong Zhang if (a->j[j] == i) { 146009f38230SBarry Smith a->diag[i] = j; 146117ab2063SBarry Smith break; 146217ab2063SBarry Smith } 146317ab2063SBarry Smith } 146417ab2063SBarry Smith } 14653a40ed3dSBarry Smith PetscFunctionReturn(0); 146617ab2063SBarry Smith } 146717ab2063SBarry Smith 1468be5855fcSBarry Smith /* 1469be5855fcSBarry Smith Checks for missing diagonals 1470be5855fcSBarry Smith */ 1471ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1472be5855fcSBarry Smith { 1473be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14747734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1475be5855fcSBarry Smith 1476be5855fcSBarry Smith PetscFunctionBegin; 147709f38230SBarry Smith *missing = PETSC_FALSE; 14787734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 147909f38230SBarry Smith *missing = PETSC_TRUE; 148009f38230SBarry Smith if (d) *d = 0; 1481955c1f14SBarry Smith PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n"); 148209f38230SBarry Smith } else { 1483f1e2ffcdSBarry Smith diag = a->diag; 1484d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 14857734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 148609f38230SBarry Smith *missing = PETSC_TRUE; 148709f38230SBarry Smith if (d) *d = i; 1488955c1f14SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D\n",i); 1489358d2f5dSShri Abhyankar break; 149009f38230SBarry Smith } 1491be5855fcSBarry Smith } 1492be5855fcSBarry Smith } 1493be5855fcSBarry Smith PetscFunctionReturn(0); 1494be5855fcSBarry Smith } 1495be5855fcSBarry Smith 1496422a814eSBarry Smith /* 1497422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1498422a814eSBarry Smith */ 14997087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 150071f1c65dSBarry Smith { 150171f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 150271f1c65dSBarry Smith PetscErrorCode ierr; 1503d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 150454f21887SBarry Smith MatScalar *v = a->a; 150554f21887SBarry Smith PetscScalar *idiag,*mdiag; 150671f1c65dSBarry Smith 150771f1c65dSBarry Smith PetscFunctionBegin; 150871f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 150971f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 151071f1c65dSBarry Smith diag = a->diag; 151171f1c65dSBarry Smith if (!a->idiag) { 1512dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 15133bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 151471f1c65dSBarry Smith v = a->a; 151571f1c65dSBarry Smith } 151671f1c65dSBarry Smith mdiag = a->mdiag; 151771f1c65dSBarry Smith idiag = a->idiag; 151871f1c65dSBarry Smith 1519422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 152071f1c65dSBarry Smith for (i=0; i<m; i++) { 152171f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1522899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1523899639b0SHong Zhang if (PetscRealPart(fshift)) { 1524899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 15257b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 15267b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 15277b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 15287b6c816cSBarry Smith } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1529899639b0SHong Zhang } 153071f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 153171f1c65dSBarry Smith } 153271f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 153371f1c65dSBarry Smith } else { 153471f1c65dSBarry Smith for (i=0; i<m; i++) { 153571f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 153671f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 153771f1c65dSBarry Smith } 1538dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 153971f1c65dSBarry Smith } 154071f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 154171f1c65dSBarry Smith PetscFunctionReturn(0); 154271f1c65dSBarry Smith } 154371f1c65dSBarry Smith 1544c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 154541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 154617ab2063SBarry Smith { 1547416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1548e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 15493d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 155054f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1551dfbe8321SBarry Smith PetscErrorCode ierr; 15523d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 155397f1f81fSBarry Smith const PetscInt *idx,*diag; 155417ab2063SBarry Smith 15553a40ed3dSBarry Smith PetscFunctionBegin; 1556b965ef7fSBarry Smith its = its*lits; 155791723122SBarry Smith 155871f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 155971f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 156071f1c65dSBarry Smith a->fshift = fshift; 156171f1c65dSBarry Smith a->omega = omega; 1562ed480e8bSBarry Smith 156371f1c65dSBarry Smith diag = a->diag; 156471f1c65dSBarry Smith t = a->ssor_work; 1565ed480e8bSBarry Smith idiag = a->idiag; 156671f1c65dSBarry Smith mdiag = a->mdiag; 1567ed480e8bSBarry Smith 15681ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 15693649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1570ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 157117ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 157217ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1573ed480e8bSBarry Smith bs = b; 157417ab2063SBarry Smith for (i=0; i<m; i++) { 157571f1c65dSBarry Smith d = fshift + mdiag[i]; 1576416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1577ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1578ed480e8bSBarry Smith v = a->a + diag[i] + 1; 157917ab2063SBarry Smith sum = b[i]*d/omega; 1580003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 158117ab2063SBarry Smith x[i] = sum; 158217ab2063SBarry Smith } 15831ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 15843649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1585efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 15863a40ed3dSBarry Smith PetscFunctionReturn(0); 158717ab2063SBarry Smith } 1588c783ea89SBarry Smith 15892205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 15902205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 159117ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1592887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 159317ab2063SBarry Smith 159417ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 159517ab2063SBarry Smith 1596887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 159717ab2063SBarry Smith */ 159817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 159917ab2063SBarry Smith 160017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 160117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1602416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1603ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1604ed480e8bSBarry Smith v = a->a + diag[i] + 1; 160517ab2063SBarry Smith sum = b[i]; 1606e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1607ed480e8bSBarry Smith x[i] = sum*idiag[i]; 160817ab2063SBarry Smith } 160917ab2063SBarry Smith 161017ab2063SBarry Smith /* t = b - (2*E - D)x */ 1611416022c9SBarry Smith v = a->a; 16122205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 161317ab2063SBarry Smith 161417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1615ed480e8bSBarry Smith ts = t; 1616416022c9SBarry Smith diag = a->diag; 161717ab2063SBarry Smith for (i=0; i<m; i++) { 1618416022c9SBarry Smith n = diag[i] - a->i[i]; 1619ed480e8bSBarry Smith idx = a->j + a->i[i]; 1620ed480e8bSBarry Smith v = a->a + a->i[i]; 162117ab2063SBarry Smith sum = t[i]; 1622003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1623ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1624733d66baSBarry Smith /* x = x + t */ 1625733d66baSBarry Smith x[i] += t[i]; 162617ab2063SBarry Smith } 162717ab2063SBarry Smith 1628dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16291ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16303649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16313a40ed3dSBarry Smith PetscFunctionReturn(0); 163217ab2063SBarry Smith } 163317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 163417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 163517ab2063SBarry Smith for (i=0; i<m; i++) { 1636416022c9SBarry Smith n = diag[i] - a->i[i]; 1637ed480e8bSBarry Smith idx = a->j + a->i[i]; 1638ed480e8bSBarry Smith v = a->a + a->i[i]; 163917ab2063SBarry Smith sum = b[i]; 1640e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16415c99c7daSBarry Smith t[i] = sum; 1642ed480e8bSBarry Smith x[i] = sum*idiag[i]; 164317ab2063SBarry Smith } 16445c99c7daSBarry Smith xb = t; 1645efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16463a40ed3dSBarry Smith } else xb = b; 164717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 164817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1649416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1650ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1651ed480e8bSBarry Smith v = a->a + diag[i] + 1; 165217ab2063SBarry Smith sum = xb[i]; 1653e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16545c99c7daSBarry Smith if (xb == b) { 1655ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16565c99c7daSBarry Smith } else { 1657b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 165817ab2063SBarry Smith } 16595c99c7daSBarry Smith } 1660b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 166117ab2063SBarry Smith } 166217ab2063SBarry Smith its--; 166317ab2063SBarry Smith } 166417ab2063SBarry Smith while (its--) { 166517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 166617ab2063SBarry Smith for (i=0; i<m; i++) { 1667b19a5dc2SMark Adams /* lower */ 1668b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1669ed480e8bSBarry Smith idx = a->j + a->i[i]; 1670ed480e8bSBarry Smith v = a->a + a->i[i]; 167117ab2063SBarry Smith sum = b[i]; 1672e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1673b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1674b19a5dc2SMark Adams /* upper */ 1675b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1676b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1677b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1678b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1679b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 168017ab2063SBarry Smith } 1681b19a5dc2SMark Adams xb = t; 16829f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1683b19a5dc2SMark Adams } else xb = b; 168417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 168517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1686b19a5dc2SMark Adams sum = xb[i]; 1687b19a5dc2SMark Adams if (xb == b) { 1688b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1689416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1690ed480e8bSBarry Smith idx = a->j + a->i[i]; 1691ed480e8bSBarry Smith v = a->a + a->i[i]; 1692e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1693ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1694b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1695b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1696b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1697b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1698b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1699b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 170017ab2063SBarry Smith } 1701b19a5dc2SMark Adams } 1702b19a5dc2SMark Adams if (xb == b) { 17039f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1704b19a5dc2SMark Adams } else { 1705b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1706b19a5dc2SMark Adams } 170717ab2063SBarry Smith } 170817ab2063SBarry Smith } 17091ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17103649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1711365a8a9eSBarry Smith PetscFunctionReturn(0); 171217ab2063SBarry Smith } 171317ab2063SBarry Smith 17142af78befSBarry Smith 1715dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 171617ab2063SBarry Smith { 1717416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17184e220ebcSLois Curfman McInnes 17193a40ed3dSBarry Smith PetscFunctionBegin; 17204e220ebcSLois Curfman McInnes info->block_size = 1.0; 17214e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17224e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17234e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17244e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17258e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17267adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1727d5f3da31SBarry Smith if (A->factortype) { 17284e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17294e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17304e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17314e220ebcSLois Curfman McInnes } else { 17324e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17334e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17344e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17354e220ebcSLois Curfman McInnes } 17363a40ed3dSBarry Smith PetscFunctionReturn(0); 173717ab2063SBarry Smith } 173817ab2063SBarry Smith 17392b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 174017ab2063SBarry Smith { 1741416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1742c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 17436849ba73SBarry Smith PetscErrorCode ierr; 174497b48c8fSBarry Smith const PetscScalar *xx; 174597b48c8fSBarry Smith PetscScalar *bb; 1746c7da8527SEric Chamberland PetscInt d = 0; 174717ab2063SBarry Smith 17483a40ed3dSBarry Smith PetscFunctionBegin; 174997b48c8fSBarry Smith if (x && b) { 175097b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 175197b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 175297b48c8fSBarry Smith for (i=0; i<N; i++) { 175397b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 175497b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 175597b48c8fSBarry Smith } 175697b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 175797b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 175897b48c8fSBarry Smith } 175997b48c8fSBarry Smith 1760a9817697SBarry Smith if (a->keepnonzeropattern) { 1761f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1762e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1763bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1764f1e2ffcdSBarry Smith } 1765f4df32b1SMatthew Knepley if (diag != 0.0) { 1766c7da8527SEric Chamberland for (i=0; i<N; i++) { 1767c7da8527SEric Chamberland d = rows[i]; 1768c7da8527SEric 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); 1769c7da8527SEric Chamberland } 1770f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1771f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1772f1e2ffcdSBarry Smith } 1773f1e2ffcdSBarry Smith } 1774f1e2ffcdSBarry Smith } else { 1775f4df32b1SMatthew Knepley if (diag != 0.0) { 177617ab2063SBarry Smith for (i=0; i<N; i++) { 1777e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 17787ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1779416022c9SBarry Smith a->ilen[rows[i]] = 1; 1780f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1781bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 17827ae801bdSBarry Smith } else { /* in case row was completely empty */ 1783f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 178417ab2063SBarry Smith } 178517ab2063SBarry Smith } 17863a40ed3dSBarry Smith } else { 178717ab2063SBarry Smith for (i=0; i<N; i++) { 1788e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1789416022c9SBarry Smith a->ilen[rows[i]] = 0; 179017ab2063SBarry Smith } 179117ab2063SBarry Smith } 1792e56f5c9eSBarry Smith A->nonzerostate++; 1793f1e2ffcdSBarry Smith } 179443a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17953a40ed3dSBarry Smith PetscFunctionReturn(0); 179617ab2063SBarry Smith } 179717ab2063SBarry Smith 17986e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 17996e169961SBarry Smith { 18006e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18016e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18026e169961SBarry Smith PetscErrorCode ierr; 18032b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18046e169961SBarry Smith const PetscScalar *xx; 18056e169961SBarry Smith PetscScalar *bb; 18066e169961SBarry Smith 18076e169961SBarry Smith PetscFunctionBegin; 18086e169961SBarry Smith if (x && b) { 18096e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18106e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18112b40b63fSBarry Smith vecs = PETSC_TRUE; 18126e169961SBarry Smith } 18131795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 18146e169961SBarry Smith for (i=0; i<N; i++) { 18156e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18166e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18172205254eSKarl Rupp 18186e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18196e169961SBarry Smith } 18206e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18216e169961SBarry Smith if (!zeroed[i]) { 18226e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18236e169961SBarry Smith if (zeroed[a->j[j]]) { 18242b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18256e169961SBarry Smith a->a[j] = 0.0; 18266e169961SBarry Smith } 18276e169961SBarry Smith } 18282b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18296e169961SBarry Smith } 18306e169961SBarry Smith if (x && b) { 18316e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18326e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18336e169961SBarry Smith } 18346e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18356e169961SBarry Smith if (diag != 0.0) { 18366e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18371d5a398dSstefano_zampini if (missing) { 18381d5a398dSstefano_zampini if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18391d5a398dSstefano_zampini else { 18401d5a398dSstefano_zampini for (i=0; i<N; i++) { 18411d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 18421d5a398dSstefano_zampini } 18431d5a398dSstefano_zampini } 18441d5a398dSstefano_zampini } else { 18456e169961SBarry Smith for (i=0; i<N; i++) { 18466e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18476e169961SBarry Smith } 18486e169961SBarry Smith } 18491d5a398dSstefano_zampini } 18506e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18516e169961SBarry Smith PetscFunctionReturn(0); 18526e169961SBarry Smith } 18536e169961SBarry Smith 1854a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 185517ab2063SBarry Smith { 1856416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 185797f1f81fSBarry Smith PetscInt *itmp; 185817ab2063SBarry Smith 18593a40ed3dSBarry Smith PetscFunctionBegin; 1860e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 186117ab2063SBarry Smith 1862416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1863bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 186417ab2063SBarry Smith if (idx) { 1865bfeeae90SHong Zhang itmp = a->j + a->i[row]; 186626fbe8dcSKarl Rupp if (*nz) *idx = itmp; 186717ab2063SBarry Smith else *idx = 0; 186817ab2063SBarry Smith } 18693a40ed3dSBarry Smith PetscFunctionReturn(0); 187017ab2063SBarry Smith } 187117ab2063SBarry Smith 1872bfeeae90SHong Zhang /* remove this function? */ 1873a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 187417ab2063SBarry Smith { 18753a40ed3dSBarry Smith PetscFunctionBegin; 18763a40ed3dSBarry Smith PetscFunctionReturn(0); 187717ab2063SBarry Smith } 187817ab2063SBarry Smith 1879dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 188017ab2063SBarry Smith { 1881416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 188254f21887SBarry Smith MatScalar *v = a->a; 188336db0b34SBarry Smith PetscReal sum = 0.0; 18846849ba73SBarry Smith PetscErrorCode ierr; 188597f1f81fSBarry Smith PetscInt i,j; 188617ab2063SBarry Smith 18873a40ed3dSBarry Smith PetscFunctionBegin; 188817ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1889570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1890570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 1891570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 1892570b7f6dSBarry Smith #else 1893416022c9SBarry Smith for (i=0; i<a->nz; i++) { 189436db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 189517ab2063SBarry Smith } 18968f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1897570b7f6dSBarry Smith #endif 189851f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 18993a40ed3dSBarry Smith } else if (type == NORM_1) { 190036db0b34SBarry Smith PetscReal *tmp; 190197f1f81fSBarry Smith PetscInt *jj = a->j; 19021795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 1903064f8208SBarry Smith *nrm = 0.0; 1904416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1905bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 190617ab2063SBarry Smith } 1907d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1908064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 190917ab2063SBarry Smith } 1910606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 191151f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 19123a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1913064f8208SBarry Smith *nrm = 0.0; 1914d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1915bfeeae90SHong Zhang v = a->a + a->i[j]; 191617ab2063SBarry Smith sum = 0.0; 1917416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1918cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 191917ab2063SBarry Smith } 1920064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 192117ab2063SBarry Smith } 192251f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 1923f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 19243a40ed3dSBarry Smith PetscFunctionReturn(0); 192517ab2063SBarry Smith } 192617ab2063SBarry Smith 19274e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 19284e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 19294e938277SHong Zhang { 19304e938277SHong Zhang PetscErrorCode ierr; 19314e938277SHong Zhang PetscInt i,j,anzj; 19324e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 19334e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 19344e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 19354e938277SHong Zhang 19364e938277SHong Zhang PetscFunctionBegin; 19374e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 1938854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 1939785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 1940785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 19414e938277SHong Zhang 19424e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 19434e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 194426fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 19454e938277SHong Zhang /* Form ati for csr format of A^T. */ 194626fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 19474e938277SHong Zhang 19484e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 19494e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 19504e938277SHong Zhang 19514e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 19524e938277SHong Zhang for (i=0;i<am;i++) { 19534e938277SHong Zhang anzj = ai[i+1] - ai[i]; 19544e938277SHong Zhang for (j=0;j<anzj;j++) { 19554e938277SHong Zhang atj[atfill[*aj]] = i; 19564e938277SHong Zhang atfill[*aj++] += 1; 19574e938277SHong Zhang } 19584e938277SHong Zhang } 19594e938277SHong Zhang 19604e938277SHong Zhang /* Clean up temporary space and complete requests. */ 19614e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 1962ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 196333d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1964a2f3521dSMark F. Adams 19654e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 19664e938277SHong Zhang b->free_a = PETSC_FALSE; 19674e938277SHong Zhang b->free_ij = PETSC_TRUE; 19684e938277SHong Zhang b->nonew = 0; 19694e938277SHong Zhang PetscFunctionReturn(0); 19704e938277SHong Zhang } 19714e938277SHong Zhang 1972fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 197317ab2063SBarry Smith { 1974416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1975416022c9SBarry Smith Mat C; 19766849ba73SBarry Smith PetscErrorCode ierr; 1977d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 197854f21887SBarry Smith MatScalar *array = a->a; 197917ab2063SBarry Smith 19803a40ed3dSBarry Smith PetscFunctionBegin; 1981cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1982fc4dec0aSBarry Smith 1983cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 1984854ce69bSBarry Smith ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr); 1985bfeeae90SHong Zhang 1986bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1987ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 1988d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 198933d57670SJed Brown ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 19907adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1991ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1992606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 1993a541d17aSBarry Smith } else { 1994a541d17aSBarry Smith C = *B; 1995a541d17aSBarry Smith } 1996a541d17aSBarry Smith 199717ab2063SBarry Smith for (i=0; i<m; i++) { 199817ab2063SBarry Smith len = ai[i+1]-ai[i]; 199987d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2000b9b97703SBarry Smith array += len; 2001b9b97703SBarry Smith aj += len; 200217ab2063SBarry Smith } 20036d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20046d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 200517ab2063SBarry Smith 2006cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 2007416022c9SBarry Smith *B = C; 200817ab2063SBarry Smith } else { 200928be2f97SBarry Smith ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 201017ab2063SBarry Smith } 20113a40ed3dSBarry Smith PetscFunctionReturn(0); 201217ab2063SBarry Smith } 201317ab2063SBarry Smith 20147087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2015cd0d46ebSvictorle { 20163d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 201754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 201854f21887SBarry Smith MatScalar *va,*vb; 20196849ba73SBarry Smith PetscErrorCode ierr; 202097f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2021cd0d46ebSvictorle 2022cd0d46ebSvictorle PetscFunctionBegin; 2023cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2024cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20255485867bSBarry Smith if (ma!=nb || na!=mb) { 20265485867bSBarry Smith *f = PETSC_FALSE; 20275485867bSBarry Smith PetscFunctionReturn(0); 20285485867bSBarry Smith } 2029cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2030cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2031cd0d46ebSvictorle va = aij->a; vb = bij->a; 2032785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2033785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2034cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2035cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2036cd0d46ebSvictorle 2037cd0d46ebSvictorle *f = PETSC_TRUE; 2038cd0d46ebSvictorle for (i=0; i<ma; i++) { 2039cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 204097f1f81fSBarry Smith PetscInt idc,idr; 20415485867bSBarry Smith PetscScalar vc,vr; 2042cd0d46ebSvictorle /* column/row index/value */ 20435485867bSBarry Smith idc = adx[aptr[i]]; 20445485867bSBarry Smith idr = bdx[bptr[idc]]; 20455485867bSBarry Smith vc = va[aptr[i]]; 20465485867bSBarry Smith vr = vb[bptr[idc]]; 20475485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20485485867bSBarry Smith *f = PETSC_FALSE; 20495485867bSBarry Smith goto done; 2050cd0d46ebSvictorle } else { 20515485867bSBarry Smith aptr[i]++; 20525485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2053cd0d46ebSvictorle } 2054cd0d46ebSvictorle } 2055cd0d46ebSvictorle } 2056cd0d46ebSvictorle done: 2057cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20583aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2059cd0d46ebSvictorle PetscFunctionReturn(0); 2060cd0d46ebSvictorle } 2061cd0d46ebSvictorle 20627087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 20631cbb95d3SBarry Smith { 20643d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 206554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 206654f21887SBarry Smith MatScalar *va,*vb; 20671cbb95d3SBarry Smith PetscErrorCode ierr; 20681cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 20691cbb95d3SBarry Smith 20701cbb95d3SBarry Smith PetscFunctionBegin; 20711cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 20721cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20731cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 20741cbb95d3SBarry Smith *f = PETSC_FALSE; 20751cbb95d3SBarry Smith PetscFunctionReturn(0); 20761cbb95d3SBarry Smith } 20771cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 20781cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 20791cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2080785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2081785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 20821cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 20831cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 20841cbb95d3SBarry Smith 20851cbb95d3SBarry Smith *f = PETSC_TRUE; 20861cbb95d3SBarry Smith for (i=0; i<ma; i++) { 20871cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 20881cbb95d3SBarry Smith PetscInt idc,idr; 20891cbb95d3SBarry Smith PetscScalar vc,vr; 20901cbb95d3SBarry Smith /* column/row index/value */ 20911cbb95d3SBarry Smith idc = adx[aptr[i]]; 20921cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 20931cbb95d3SBarry Smith vc = va[aptr[i]]; 20941cbb95d3SBarry Smith vr = vb[bptr[idc]]; 20951cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 20961cbb95d3SBarry Smith *f = PETSC_FALSE; 20971cbb95d3SBarry Smith goto done; 20981cbb95d3SBarry Smith } else { 20991cbb95d3SBarry Smith aptr[i]++; 21001cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 21011cbb95d3SBarry Smith } 21021cbb95d3SBarry Smith } 21031cbb95d3SBarry Smith } 21041cbb95d3SBarry Smith done: 21051cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 21061cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 21071cbb95d3SBarry Smith PetscFunctionReturn(0); 21081cbb95d3SBarry Smith } 21091cbb95d3SBarry Smith 2110ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21119e29f15eSvictorle { 2112dfbe8321SBarry Smith PetscErrorCode ierr; 21136e111a19SKarl Rupp 21149e29f15eSvictorle PetscFunctionBegin; 21155485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21169e29f15eSvictorle PetscFunctionReturn(0); 21179e29f15eSvictorle } 21189e29f15eSvictorle 2119ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21201cbb95d3SBarry Smith { 21211cbb95d3SBarry Smith PetscErrorCode ierr; 21226e111a19SKarl Rupp 21231cbb95d3SBarry Smith PetscFunctionBegin; 21241cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21251cbb95d3SBarry Smith PetscFunctionReturn(0); 21261cbb95d3SBarry Smith } 21271cbb95d3SBarry Smith 2128dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 212917ab2063SBarry Smith { 2130416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 213154f21887SBarry Smith PetscScalar *l,*r,x; 213254f21887SBarry Smith MatScalar *v; 2133dfbe8321SBarry Smith PetscErrorCode ierr; 2134d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 213517ab2063SBarry Smith 21363a40ed3dSBarry Smith PetscFunctionBegin; 213717ab2063SBarry Smith if (ll) { 21383ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21393ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2140e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2141e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21421ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2143416022c9SBarry Smith v = a->a; 214417ab2063SBarry Smith for (i=0; i<m; i++) { 214517ab2063SBarry Smith x = l[i]; 2146416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 21472205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 214817ab2063SBarry Smith } 21491ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2150efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 215117ab2063SBarry Smith } 215217ab2063SBarry Smith if (rr) { 2153e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2154e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21551ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2156416022c9SBarry Smith v = a->a; jj = a->j; 21572205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 21581ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2159efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 216017ab2063SBarry Smith } 2161acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 21623a40ed3dSBarry Smith PetscFunctionReturn(0); 216317ab2063SBarry Smith } 216417ab2063SBarry Smith 21657dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 216617ab2063SBarry Smith { 2167db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 21686849ba73SBarry Smith PetscErrorCode ierr; 2169d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 217097f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 21715d0c19d7SBarry Smith const PetscInt *irow,*icol; 21725d0c19d7SBarry Smith PetscInt nrows,ncols; 217397f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 217454f21887SBarry Smith MatScalar *a_new,*mat_a; 2175416022c9SBarry Smith Mat C; 2176cdc6f3adSToby Isaac PetscBool stride; 217717ab2063SBarry Smith 21783a40ed3dSBarry Smith PetscFunctionBegin; 217999141d43SSatish Balay 218017ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2181b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2182b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 218317ab2063SBarry Smith 2184251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2185ff718158SBarry Smith if (stride) { 2186ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2187ff718158SBarry Smith } else { 2188ff718158SBarry Smith first = 0; 2189ff718158SBarry Smith step = 0; 2190ff718158SBarry Smith } 2191fee21e36SBarry Smith if (stride && step == 1) { 219202834360SBarry Smith /* special case of contiguous rows */ 2193dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 219402834360SBarry Smith /* loop over new rows determining lens and starting points */ 219502834360SBarry Smith for (i=0; i<nrows; i++) { 2196bfeeae90SHong Zhang kstart = ai[irow[i]]; 2197a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2198a91a9bebSLisandro Dalcin starts[i] = kstart; 219902834360SBarry Smith for (k=kstart; k<kend; k++) { 2200bfeeae90SHong Zhang if (aj[k] >= first) { 220102834360SBarry Smith starts[i] = k; 220202834360SBarry Smith break; 220302834360SBarry Smith } 220402834360SBarry Smith } 2205a2744918SBarry Smith sum = 0; 220602834360SBarry Smith while (k < kend) { 2207bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2208a2744918SBarry Smith sum++; 220902834360SBarry Smith } 2210a2744918SBarry Smith lens[i] = sum; 221102834360SBarry Smith } 221202834360SBarry Smith /* create submatrix */ 2213cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 221497f1f81fSBarry Smith PetscInt n_cols,n_rows; 221508480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2216e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2217d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 221808480c60SBarry Smith C = *B; 22193a40ed3dSBarry Smith } else { 22203bef6203SJed Brown PetscInt rbs,cbs; 2221ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2222f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22233bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22243bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22253bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22267adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2227ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 222808480c60SBarry Smith } 2229db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2230db02288aSLois Curfman McInnes 223102834360SBarry Smith /* loop over rows inserting into submatrix */ 2232db02288aSLois Curfman McInnes a_new = c->a; 2233db02288aSLois Curfman McInnes j_new = c->j; 2234db02288aSLois Curfman McInnes i_new = c->i; 2235bfeeae90SHong Zhang 223602834360SBarry Smith for (i=0; i<nrows; i++) { 2237a2744918SBarry Smith ii = starts[i]; 2238a2744918SBarry Smith lensi = lens[i]; 2239a2744918SBarry Smith for (k=0; k<lensi; k++) { 2240a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 224102834360SBarry Smith } 224287828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2243a2744918SBarry Smith a_new += lensi; 2244a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2245a2744918SBarry Smith c->ilen[i] = lensi; 224602834360SBarry Smith } 22470e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22483a40ed3dSBarry Smith } else { 224902834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22501795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2251854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 22524dcab191SBarry Smith for (i=0; i<ncols; i++) { 22534dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 22544dcab191SBarry 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); 22554dcab191SBarry Smith #endif 22564dcab191SBarry Smith smap[icol[i]] = i+1; 22574dcab191SBarry Smith } 22584dcab191SBarry Smith 225902834360SBarry Smith /* determine lens of each row */ 226002834360SBarry Smith for (i=0; i<nrows; i++) { 2261bfeeae90SHong Zhang kstart = ai[irow[i]]; 226202834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 226302834360SBarry Smith lens[i] = 0; 226402834360SBarry Smith for (k=kstart; k<kend; k++) { 2265bfeeae90SHong Zhang if (smap[aj[k]]) { 226602834360SBarry Smith lens[i]++; 226702834360SBarry Smith } 226802834360SBarry Smith } 226902834360SBarry Smith } 227017ab2063SBarry Smith /* Create and fill new matrix */ 2271a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2272ace3abfcSBarry Smith PetscBool equal; 22730f5bd95cSBarry Smith 227499141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2275e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2276d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2277f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2278d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 227908480c60SBarry Smith C = *B; 22803a40ed3dSBarry Smith } else { 22813bef6203SJed Brown PetscInt rbs,cbs; 2282ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2283f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22843bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22853bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22863bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22877adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2288ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 228908480c60SBarry Smith } 229099141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 229117ab2063SBarry Smith for (i=0; i<nrows; i++) { 229299141d43SSatish Balay row = irow[i]; 2293bfeeae90SHong Zhang kstart = ai[row]; 229499141d43SSatish Balay kend = kstart + a->ilen[row]; 2295bfeeae90SHong Zhang mat_i = c->i[i]; 229699141d43SSatish Balay mat_j = c->j + mat_i; 229799141d43SSatish Balay mat_a = c->a + mat_i; 229899141d43SSatish Balay mat_ilen = c->ilen + i; 229917ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2300bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2301ed480e8bSBarry Smith *mat_j++ = tcol - 1; 230299141d43SSatish Balay *mat_a++ = a->a[k]; 230399141d43SSatish Balay (*mat_ilen)++; 230499141d43SSatish Balay 230517ab2063SBarry Smith } 230617ab2063SBarry Smith } 230717ab2063SBarry Smith } 230802834360SBarry Smith /* Free work space */ 230902834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2310606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2311606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2312cdc6f3adSToby Isaac /* sort */ 2313cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2314cdc6f3adSToby Isaac PetscInt ilen; 2315cdc6f3adSToby Isaac 2316cdc6f3adSToby Isaac mat_i = c->i[i]; 2317cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2318cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2319cdc6f3adSToby Isaac ilen = c->ilen[i]; 2320390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2321cdc6f3adSToby Isaac } 232202834360SBarry Smith } 23236d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23246d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 232517ab2063SBarry Smith 232617ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2327416022c9SBarry Smith *B = C; 23283a40ed3dSBarry Smith PetscFunctionReturn(0); 232917ab2063SBarry Smith } 233017ab2063SBarry Smith 2331fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 233282d44351SHong Zhang { 233382d44351SHong Zhang PetscErrorCode ierr; 233482d44351SHong Zhang Mat B; 233582d44351SHong Zhang 233682d44351SHong Zhang PetscFunctionBegin; 2337c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 233882d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 233982d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 234033d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 234182d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 234282d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 234382d44351SHong Zhang *subMat = B; 2344c2d650bdSHong Zhang } else { 2345c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2346c2d650bdSHong Zhang } 234782d44351SHong Zhang PetscFunctionReturn(0); 234882d44351SHong Zhang } 234982d44351SHong Zhang 23509a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2351a871dcd8SBarry Smith { 235263b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2353dfbe8321SBarry Smith PetscErrorCode ierr; 235463b91edcSBarry Smith Mat outA; 2355ace3abfcSBarry Smith PetscBool row_identity,col_identity; 235663b91edcSBarry Smith 23573a40ed3dSBarry Smith PetscFunctionBegin; 2358e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23591df811f5SHong Zhang 2360b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2361b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2362a871dcd8SBarry Smith 236363b91edcSBarry Smith outA = inA; 2364d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2365f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2366f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 23672205254eSKarl Rupp 2368c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 23696bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 23702205254eSKarl Rupp 2371c3122656SLisandro Dalcin a->row = row; 23722205254eSKarl Rupp 2373c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 23746bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 23752205254eSKarl Rupp 2376c3122656SLisandro Dalcin a->col = col; 237763b91edcSBarry Smith 237836db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 23796bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 23804c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 23813bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2382f0ec6fceSSatish Balay 238394a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2384854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 23853bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 238694a9d846SBarry Smith } 238763b91edcSBarry Smith 2388f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2389137fb511SHong Zhang if (row_identity && col_identity) { 2390ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2391137fb511SHong Zhang } else { 2392719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2393137fb511SHong Zhang } 23943a40ed3dSBarry Smith PetscFunctionReturn(0); 2395a871dcd8SBarry Smith } 2396a871dcd8SBarry Smith 2397f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2398f0b747eeSBarry Smith { 2399f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2400f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2401efee365bSSatish Balay PetscErrorCode ierr; 2402c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 24033a40ed3dSBarry Smith 24043a40ed3dSBarry Smith PetscFunctionBegin; 2405c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 24068b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2407efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2408acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 24093a40ed3dSBarry Smith PetscFunctionReturn(0); 2410f0b747eeSBarry Smith } 2411f0b747eeSBarry Smith 24125c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj) 241316b64355SHong Zhang { 241416b64355SHong Zhang PetscErrorCode ierr; 241516b64355SHong Zhang PetscInt i; 241616b64355SHong Zhang 241716b64355SHong Zhang PetscFunctionBegin; 241816b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 241916b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 242016b64355SHong Zhang 242116b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 242216b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 242316b64355SHong Zhang } 242416b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 242516b64355SHong Zhang 242616b64355SHong Zhang if (submatj->rbuf1) { 242716b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 242816b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 242916b64355SHong Zhang } 243016b64355SHong Zhang 243116b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 243216b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 243316b64355SHong Zhang } 243416b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 243516b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 243616b64355SHong Zhang } 243716b64355SHong Zhang 243816b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 243916b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 244016b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 244116b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 244216b64355SHong Zhang #else 244316b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 244416b64355SHong Zhang #endif 244516b64355SHong Zhang 244616b64355SHong Zhang if (!submatj->allcolumns) { 244716b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 244816b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 244916b64355SHong Zhang #else 245016b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 245116b64355SHong Zhang #endif 245216b64355SHong Zhang } 245316b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 245416b64355SHong Zhang 245516b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 245616b64355SHong Zhang PetscFunctionReturn(0); 245716b64355SHong Zhang } 245816b64355SHong Zhang 245916b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C) 246016b64355SHong Zhang { 246116b64355SHong Zhang PetscErrorCode ierr; 246216b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 24635c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 246416b64355SHong Zhang 246516b64355SHong Zhang PetscFunctionBegin; 246616b64355SHong Zhang ierr = submatj->destroy(C);CHKERRQ(ierr); 2467e69d178cSHong Zhang ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr); 246816b64355SHong Zhang PetscFunctionReturn(0); 246916b64355SHong Zhang } 247016b64355SHong Zhang 24717dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2472cddf8d76SBarry Smith { 2473dfbe8321SBarry Smith PetscErrorCode ierr; 247497f1f81fSBarry Smith PetscInt i; 2475cddf8d76SBarry Smith 24763a40ed3dSBarry Smith PetscFunctionBegin; 2477cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2478df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2479cddf8d76SBarry Smith } 2480cddf8d76SBarry Smith 2481cddf8d76SBarry Smith for (i=0; i<n; i++) { 24827dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2483cddf8d76SBarry Smith } 24843a40ed3dSBarry Smith PetscFunctionReturn(0); 2485cddf8d76SBarry Smith } 2486cddf8d76SBarry Smith 248797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 24884dcbc457SBarry Smith { 2489e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 24906849ba73SBarry Smith PetscErrorCode ierr; 24915d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 24925d0c19d7SBarry Smith const PetscInt *idx; 249397f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2494f1af5d2fSBarry Smith PetscBT table; 2495bbd702dbSSatish Balay 24963a40ed3dSBarry Smith PetscFunctionBegin; 2497d0f46423SBarry Smith m = A->rmap->n; 2498e4d965acSSatish Balay ai = a->i; 2499bfeeae90SHong Zhang aj = a->j; 25008a047759SSatish Balay 2501e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 250206763907SSatish Balay 2503854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 250453b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 250506763907SSatish Balay 2506e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2507b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2508e4d965acSSatish Balay isz = 0; 25096831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2510e4d965acSSatish Balay 2511e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25124dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2513b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2514e4d965acSSatish Balay 2515dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2516e4d965acSSatish Balay for (j=0; j<n; ++j) { 25172205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25184dcbc457SBarry Smith } 251906763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25206bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2521e4d965acSSatish Balay 252204a348a9SBarry Smith k = 0; 252304a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 252404a348a9SBarry Smith n = isz; 252506763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2526e4d965acSSatish Balay row = nidx[k]; 2527e4d965acSSatish Balay start = ai[row]; 2528e4d965acSSatish Balay end = ai[row+1]; 252904a348a9SBarry Smith for (l = start; l<end; l++) { 2530efb16452SHong Zhang val = aj[l]; 25312205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2532e4d965acSSatish Balay } 2533e4d965acSSatish Balay } 2534e4d965acSSatish Balay } 253570b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2536e4d965acSSatish Balay } 253794bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2538606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 25393a40ed3dSBarry Smith PetscFunctionReturn(0); 25404dcbc457SBarry Smith } 254117ab2063SBarry Smith 25420513a670SBarry Smith /* -------------------------------------------------------------- */ 2543dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 25440513a670SBarry Smith { 25450513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25466849ba73SBarry Smith PetscErrorCode ierr; 25473b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 25485d0c19d7SBarry Smith const PetscInt *row,*col; 25495d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 255056cd22aeSBarry Smith IS icolp,irowp; 25510298fd71SBarry Smith PetscInt *cwork = NULL; 25520298fd71SBarry Smith PetscScalar *vwork = NULL; 25530513a670SBarry Smith 25543a40ed3dSBarry Smith PetscFunctionBegin; 25554c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 255656cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 25574c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 255856cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 25590513a670SBarry Smith 25600513a670SBarry Smith /* determine lengths of permuted rows */ 2561854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 25622205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2563ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2564f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 256533d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 25667adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2567ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2568606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 25690513a670SBarry Smith 2570785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 25710513a670SBarry Smith for (i=0; i<m; i++) { 257232ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25732205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2574cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 257532ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25760513a670SBarry Smith } 2577606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 25782205254eSKarl Rupp 25793c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 25802205254eSKarl Rupp 25810513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25820513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 258356cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 258456cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 25856bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 25866bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 25873a40ed3dSBarry Smith PetscFunctionReturn(0); 25880513a670SBarry Smith } 25890513a670SBarry Smith 2590dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2591cb5b572fSBarry Smith { 2592dfbe8321SBarry Smith PetscErrorCode ierr; 2593cb5b572fSBarry Smith 2594cb5b572fSBarry Smith PetscFunctionBegin; 259533f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 259633f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2597be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2598be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2599be6bf707SBarry Smith 2600700c5bfcSBarry 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"); 2601d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2602cb5b572fSBarry Smith } else { 2603cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2604cb5b572fSBarry Smith } 2605cb5b572fSBarry Smith PetscFunctionReturn(0); 2606cb5b572fSBarry Smith } 2607cb5b572fSBarry Smith 26084994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2609273d9f13SBarry Smith { 2610dfbe8321SBarry Smith PetscErrorCode ierr; 2611273d9f13SBarry Smith 2612273d9f13SBarry Smith PetscFunctionBegin; 2613ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2614273d9f13SBarry Smith PetscFunctionReturn(0); 2615273d9f13SBarry Smith } 2616273d9f13SBarry Smith 26178c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 26186c0721eeSBarry Smith { 26196c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26206e111a19SKarl Rupp 26216c0721eeSBarry Smith PetscFunctionBegin; 26226c0721eeSBarry Smith *array = a->a; 26236c0721eeSBarry Smith PetscFunctionReturn(0); 26246c0721eeSBarry Smith } 26256c0721eeSBarry Smith 26268c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 26276c0721eeSBarry Smith { 26286c0721eeSBarry Smith PetscFunctionBegin; 26296c0721eeSBarry Smith PetscFunctionReturn(0); 26306c0721eeSBarry Smith } 2631273d9f13SBarry Smith 26328229c054SShri Abhyankar /* 26338229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26348229c054SShri Abhyankar have different nonzero structure. 26358229c054SShri Abhyankar */ 2636b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2637ec7775f6SShri Abhyankar { 2638b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2639ec7775f6SShri Abhyankar 2640ec7775f6SShri Abhyankar PetscFunctionBegin; 2641ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2642ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2643b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2644b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2645b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 26468af7cee1SJed Brown nnz[i] = 0; 26478af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2648b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2649b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 26508af7cee1SJed Brown nnz[i]++; 26518af7cee1SJed Brown } 26528af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2653ec7775f6SShri Abhyankar } 2654ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2655ec7775f6SShri Abhyankar } 2656ec7775f6SShri Abhyankar 2657b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2658b264fe52SHong Zhang { 2659b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2660b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2661b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2662b264fe52SHong Zhang PetscErrorCode ierr; 2663b264fe52SHong Zhang 2664b264fe52SHong Zhang PetscFunctionBegin; 2665b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2666b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2667b264fe52SHong Zhang PetscFunctionReturn(0); 2668b264fe52SHong Zhang } 2669b264fe52SHong Zhang 2670f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2671ac90fabeSBarry Smith { 2672dfbe8321SBarry Smith PetscErrorCode ierr; 2673ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2674c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2675ac90fabeSBarry Smith 2676ac90fabeSBarry Smith PetscFunctionBegin; 2677c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2678ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2679f4df32b1SMatthew Knepley PetscScalar alpha = a; 26808b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2681acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2682a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2683ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2684ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2685ac90fabeSBarry Smith } else { 26868229c054SShri Abhyankar Mat B; 26878229c054SShri Abhyankar PetscInt *nnz; 2688785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2689ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2690bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 26914aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 269233d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2693176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 26948229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2695ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2696ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 269728be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 26988229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2699ac90fabeSBarry Smith } 2700ac90fabeSBarry Smith PetscFunctionReturn(0); 2701ac90fabeSBarry Smith } 2702ac90fabeSBarry Smith 27037087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2704354c94deSBarry Smith { 2705354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2706354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2707354c94deSBarry Smith PetscInt i,nz; 2708354c94deSBarry Smith PetscScalar *a; 2709354c94deSBarry Smith 2710354c94deSBarry Smith PetscFunctionBegin; 2711354c94deSBarry Smith nz = aij->nz; 2712354c94deSBarry Smith a = aij->a; 27132205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2714354c94deSBarry Smith #else 2715354c94deSBarry Smith PetscFunctionBegin; 2716354c94deSBarry Smith #endif 2717354c94deSBarry Smith PetscFunctionReturn(0); 2718354c94deSBarry Smith } 2719354c94deSBarry Smith 2720985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2721e34fafa9SBarry Smith { 2722e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2723e34fafa9SBarry Smith PetscErrorCode ierr; 2724d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2725e34fafa9SBarry Smith PetscReal atmp; 2726985db425SBarry Smith PetscScalar *x; 2727e34fafa9SBarry Smith MatScalar *aa; 2728e34fafa9SBarry Smith 2729e34fafa9SBarry Smith PetscFunctionBegin; 2730e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2731e34fafa9SBarry Smith aa = a->a; 2732e34fafa9SBarry Smith ai = a->i; 2733e34fafa9SBarry Smith aj = a->j; 2734e34fafa9SBarry Smith 2735985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2736e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2737e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2738e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2739e34fafa9SBarry Smith for (i=0; i<m; i++) { 2740e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 27419189402eSHong Zhang x[i] = 0.0; 2742e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2743985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2744985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2745985db425SBarry Smith aa++; aj++; 2746985db425SBarry Smith } 2747985db425SBarry Smith } 2748985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2749985db425SBarry Smith PetscFunctionReturn(0); 2750985db425SBarry Smith } 2751985db425SBarry Smith 2752985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2753985db425SBarry Smith { 2754985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2755985db425SBarry Smith PetscErrorCode ierr; 2756d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2757985db425SBarry Smith PetscScalar *x; 2758985db425SBarry Smith MatScalar *aa; 2759985db425SBarry Smith 2760985db425SBarry Smith PetscFunctionBegin; 2761e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2762985db425SBarry Smith aa = a->a; 2763985db425SBarry Smith ai = a->i; 2764985db425SBarry Smith aj = a->j; 2765985db425SBarry Smith 2766985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2767985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2768985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2769e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2770985db425SBarry Smith for (i=0; i<m; i++) { 2771985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2772d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2773985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2774985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2775985db425SBarry Smith x[i] = 0.0; 2776985db425SBarry Smith if (idx) { 2777985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2778985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2779985db425SBarry Smith if (aj[j] > j) { 2780985db425SBarry Smith idx[i] = j; 2781985db425SBarry Smith break; 2782985db425SBarry Smith } 2783985db425SBarry Smith } 2784985db425SBarry Smith } 2785985db425SBarry Smith } 2786985db425SBarry Smith for (j=0; j<ncols; j++) { 2787985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2788985db425SBarry Smith aa++; aj++; 2789985db425SBarry Smith } 2790985db425SBarry Smith } 2791985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2792985db425SBarry Smith PetscFunctionReturn(0); 2793985db425SBarry Smith } 2794985db425SBarry Smith 2795c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2796c87e5d42SMatthew Knepley { 2797c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2798c87e5d42SMatthew Knepley PetscErrorCode ierr; 2799c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2800c87e5d42SMatthew Knepley PetscReal atmp; 2801c87e5d42SMatthew Knepley PetscScalar *x; 2802c87e5d42SMatthew Knepley MatScalar *aa; 2803c87e5d42SMatthew Knepley 2804c87e5d42SMatthew Knepley PetscFunctionBegin; 2805e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2806c87e5d42SMatthew Knepley aa = a->a; 2807c87e5d42SMatthew Knepley ai = a->i; 2808c87e5d42SMatthew Knepley aj = a->j; 2809c87e5d42SMatthew Knepley 2810c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2811c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2812c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 281360e0710aSBarry 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); 2814c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2815c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2816289a08f5SMatthew Knepley if (ncols) { 2817289a08f5SMatthew Knepley /* Get first nonzero */ 2818289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 2819289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 28202205254eSKarl Rupp if (atmp > 1.0e-12) { 28212205254eSKarl Rupp x[i] = atmp; 28222205254eSKarl Rupp if (idx) idx[i] = aj[j]; 28232205254eSKarl Rupp break; 28242205254eSKarl Rupp } 2825289a08f5SMatthew Knepley } 282612431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2827289a08f5SMatthew Knepley } else { 2828289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2829289a08f5SMatthew Knepley } 2830c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 2831c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2832289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2833c87e5d42SMatthew Knepley aa++; aj++; 2834c87e5d42SMatthew Knepley } 2835c87e5d42SMatthew Knepley } 2836c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2837c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2838c87e5d42SMatthew Knepley } 2839c87e5d42SMatthew Knepley 2840985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2841985db425SBarry Smith { 2842985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2843985db425SBarry Smith PetscErrorCode ierr; 2844d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 2845d9ca1df4SBarry Smith const PetscInt *ai,*aj; 2846985db425SBarry Smith PetscScalar *x; 2847d9ca1df4SBarry Smith const MatScalar *aa; 2848985db425SBarry Smith 2849985db425SBarry Smith PetscFunctionBegin; 2850e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2851985db425SBarry Smith aa = a->a; 2852985db425SBarry Smith ai = a->i; 2853985db425SBarry Smith aj = a->j; 2854985db425SBarry Smith 2855985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2856985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2857985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2858e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2859985db425SBarry Smith for (i=0; i<m; i++) { 2860985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2861d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2862985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2863985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2864985db425SBarry Smith x[i] = 0.0; 2865985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2866985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2867985db425SBarry Smith for (j=0; j<ncols; j++) { 2868985db425SBarry Smith if (aj[j] > j) { 2869985db425SBarry Smith idx[i] = j; 2870985db425SBarry Smith break; 2871985db425SBarry Smith } 2872985db425SBarry Smith } 2873985db425SBarry Smith } 2874985db425SBarry Smith } 2875985db425SBarry Smith for (j=0; j<ncols; j++) { 2876985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2877985db425SBarry Smith aa++; aj++; 2878e34fafa9SBarry Smith } 2879e34fafa9SBarry Smith } 2880e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2881e34fafa9SBarry Smith PetscFunctionReturn(0); 2882e34fafa9SBarry Smith } 2883bbead8a2SBarry Smith 2884bbead8a2SBarry Smith #include <petscblaslapack.h> 2885af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h> 2886bbead8a2SBarry Smith 2887713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2888bbead8a2SBarry Smith { 2889bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2890bbead8a2SBarry Smith PetscErrorCode ierr; 289133d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2892bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2893bbead8a2SBarry Smith PetscReal shift = 0.0; 28941a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 2895bbead8a2SBarry Smith 2896bbead8a2SBarry Smith PetscFunctionBegin; 2897a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 28984a0d0026SBarry Smith if (a->ibdiagvalid) { 28994a0d0026SBarry Smith if (values) *values = a->ibdiag; 29004a0d0026SBarry Smith PetscFunctionReturn(0); 29014a0d0026SBarry Smith } 2902bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2903bbead8a2SBarry Smith if (!a->ibdiag) { 2904785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 29053bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2906bbead8a2SBarry Smith } 2907bbead8a2SBarry Smith diag = a->ibdiag; 2908bbead8a2SBarry Smith if (values) *values = a->ibdiag; 2909bbead8a2SBarry Smith /* factor and invert each block */ 2910bbead8a2SBarry Smith switch (bs) { 2911bbead8a2SBarry Smith case 1: 2912bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2913bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 2914ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 2915ec1892c8SHong Zhang if (allowzeropivot) { 29167b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 29177b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 29187b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 29197b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 29207b6c816cSBarry 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); 2921ec1892c8SHong Zhang } 2922bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 2923bbead8a2SBarry Smith } 2924bbead8a2SBarry Smith break; 2925bbead8a2SBarry Smith case 2: 2926bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2927bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 2928bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 2929a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29307b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 293196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 2932bbead8a2SBarry Smith diag += 4; 2933bbead8a2SBarry Smith } 2934bbead8a2SBarry Smith break; 2935bbead8a2SBarry Smith case 3: 2936bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2937bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 2938bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 2939a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29407b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 294196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 2942bbead8a2SBarry Smith diag += 9; 2943bbead8a2SBarry Smith } 2944bbead8a2SBarry Smith break; 2945bbead8a2SBarry Smith case 4: 2946bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2947bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 2948bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 2949a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29507b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 295196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 2952bbead8a2SBarry Smith diag += 16; 2953bbead8a2SBarry Smith } 2954bbead8a2SBarry Smith break; 2955bbead8a2SBarry Smith case 5: 2956bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2957bbead8a2SBarry 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; 2958bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 2959a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29607b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 296196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 2962bbead8a2SBarry Smith diag += 25; 2963bbead8a2SBarry Smith } 2964bbead8a2SBarry Smith break; 2965bbead8a2SBarry Smith case 6: 2966bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2967bbead8a2SBarry 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; 2968bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 2969a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29707b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 297196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 2972bbead8a2SBarry Smith diag += 36; 2973bbead8a2SBarry Smith } 2974bbead8a2SBarry Smith break; 2975bbead8a2SBarry Smith case 7: 2976bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2977bbead8a2SBarry 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; 2978bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 2979a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29807b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 298196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 2982bbead8a2SBarry Smith diag += 49; 2983bbead8a2SBarry Smith } 2984bbead8a2SBarry Smith break; 2985bbead8a2SBarry Smith default: 2986dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 2987bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2988bbead8a2SBarry Smith for (j=0; j<bs; j++) { 2989bbead8a2SBarry Smith IJ[j] = bs*i + j; 2990bbead8a2SBarry Smith } 2991bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 29925f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29937b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 299496b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 2995bbead8a2SBarry Smith diag += bs2; 2996bbead8a2SBarry Smith } 2997bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 2998bbead8a2SBarry Smith } 2999bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3000bbead8a2SBarry Smith PetscFunctionReturn(0); 3001bbead8a2SBarry Smith } 3002bbead8a2SBarry Smith 300373a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 300473a71a0fSBarry Smith { 300573a71a0fSBarry Smith PetscErrorCode ierr; 300673a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 300773a71a0fSBarry Smith PetscScalar a; 300873a71a0fSBarry Smith PetscInt m,n,i,j,col; 300973a71a0fSBarry Smith 301073a71a0fSBarry Smith PetscFunctionBegin; 301173a71a0fSBarry Smith if (!x->assembled) { 301273a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 301373a71a0fSBarry Smith for (i=0; i<m; i++) { 301473a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 301573a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 301673a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 301773a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 301873a71a0fSBarry Smith } 301973a71a0fSBarry Smith } 302073a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 302173a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 302273a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 302373a71a0fSBarry Smith PetscFunctionReturn(0); 302473a71a0fSBarry Smith } 302573a71a0fSBarry Smith 30267d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a) 30277d68702bSBarry Smith { 30287d68702bSBarry Smith PetscErrorCode ierr; 30297d68702bSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)Y->data; 30307d68702bSBarry Smith 30317d68702bSBarry Smith PetscFunctionBegin; 30326f33a894SBarry Smith if (!Y->preallocated || !aij->nz) { 30337d68702bSBarry Smith ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr); 30347d68702bSBarry Smith } 30357d68702bSBarry Smith ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 30367d68702bSBarry Smith PetscFunctionReturn(0); 30377d68702bSBarry Smith } 30387d68702bSBarry Smith 3039682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 30400a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3041cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3042cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3043cb5b572fSBarry Smith MatMult_SeqAIJ, 304497304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 30457c922b88SBarry Smith MatMultTranspose_SeqAIJ, 30467c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3047db4efbfdSBarry Smith 0, 3048db4efbfdSBarry Smith 0, 3049db4efbfdSBarry Smith 0, 3050db4efbfdSBarry Smith /* 10*/ 0, 3051cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3052cb5b572fSBarry Smith 0, 305341f059aeSBarry Smith MatSOR_SeqAIJ, 305417ab2063SBarry Smith MatTranspose_SeqAIJ, 305597304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3056cb5b572fSBarry Smith MatEqual_SeqAIJ, 3057cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3058cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3059cb5b572fSBarry Smith MatNorm_SeqAIJ, 306097304618SKris Buschelman /* 20*/ 0, 3061cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3062cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3063cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3064d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3065db4efbfdSBarry Smith 0, 3066db4efbfdSBarry Smith 0, 3067db4efbfdSBarry Smith 0, 3068db4efbfdSBarry Smith 0, 30694994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3070db4efbfdSBarry Smith 0, 3071db4efbfdSBarry Smith 0, 30728c778c55SBarry Smith 0, 30738c778c55SBarry Smith 0, 3074d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3075cb5b572fSBarry Smith 0, 3076cb5b572fSBarry Smith 0, 3077cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3078cb5b572fSBarry Smith 0, 3079d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 30807dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3081cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3082cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3083cb5b572fSBarry Smith MatCopy_SeqAIJ, 3084d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3085cb5b572fSBarry Smith MatScale_SeqAIJ, 30867d68702bSBarry Smith MatShift_SeqAIJ, 308779299369SBarry Smith MatDiagonalSet_SeqAIJ, 30886e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 308973a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 30903b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 30913b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 30923b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3093a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 309493dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3095b9617806SBarry Smith 0, 30960513a670SBarry Smith 0, 3097cda55fadSBarry Smith MatPermute_SeqAIJ, 3098cda55fadSBarry Smith 0, 3099d519adbfSMatthew Knepley /* 59*/ 0, 3100b9b97703SBarry Smith MatDestroy_SeqAIJ, 3101b9b97703SBarry Smith MatView_SeqAIJ, 3102357abbc8SBarry Smith 0, 3103321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3104321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3105321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3106ee4f033dSBarry Smith 0, 3107ee4f033dSBarry Smith 0, 3108ee4f033dSBarry Smith 0, 3109d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3110c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3111ee4f033dSBarry Smith 0, 3112dcf5cc72SBarry Smith 0, 31132c93a97aSBarry Smith 0, 31142c93a97aSBarry Smith /* 74*/ 0, 31153acb8795SBarry Smith MatFDColoringApply_AIJ, 311697304618SKris Buschelman 0, 311797304618SKris Buschelman 0, 311897304618SKris Buschelman 0, 31196ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 312097304618SKris Buschelman 0, 312197304618SKris Buschelman 0, 312297304618SKris Buschelman 0, 3123bc011b1eSHong Zhang MatLoad_SeqAIJ, 3124d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31251cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31266284ec50SHong Zhang 0, 31276284ec50SHong Zhang 0, 3128bc011b1eSHong Zhang 0, 3129d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 313026be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 313126be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 313265e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 31334a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 313465e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 31356fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 31366fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 31376fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 31382121bac1SHong Zhang 0, 31392121bac1SHong Zhang /* 99*/ 0, 3140609c6c4dSKris Buschelman 0, 3141609c6c4dSKris Buschelman 0, 314287d4246cSBarry Smith MatConjugate_SeqAIJ, 314387d4246cSBarry Smith 0, 3144d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 314599cafbc1SBarry Smith MatRealPart_SeqAIJ, 3146f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3147f5edf698SHong Zhang 0, 31482bebee5dSHong Zhang 0, 3149cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3150985db425SBarry Smith 0, 31512af78befSBarry Smith MatGetRowMin_SeqAIJ, 31522af78befSBarry Smith 0, 3153599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3154d519adbfSMatthew Knepley /*114*/ 0, 3155599ef60dSHong Zhang 0, 31563c2a7987SHong Zhang 0, 3157fe97e370SBarry Smith 0, 3158fbdbba38SShri Abhyankar 0, 3159fbdbba38SShri Abhyankar /*119*/ 0, 3160fbdbba38SShri Abhyankar 0, 3161fbdbba38SShri Abhyankar 0, 316282d44351SHong Zhang 0, 3163b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 31640716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3165bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 316637868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 316737868618SMatthew G Knepley 0, 316837868618SMatthew G Knepley 0, 31695df89d91SHong Zhang /*129*/ 0, 317075648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 317175648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 317275648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3173b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3174b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 31752b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 31762b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 31772b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 31783964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 31793964eb88SJed Brown /*139*/0, 3180f9426fe0SMark Adams 0, 31811919a2e2SJed Brown 0, 31823a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 31839c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 31849c8f2541SHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ 31859e29f15eSvictorle }; 318617ab2063SBarry Smith 31877087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3188bef8e0ddSBarry Smith { 3189bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 319097f1f81fSBarry Smith PetscInt i,nz,n; 3191bef8e0ddSBarry Smith 3192bef8e0ddSBarry Smith PetscFunctionBegin; 3193bef8e0ddSBarry Smith nz = aij->maxnz; 3194d0f46423SBarry Smith n = mat->rmap->n; 3195bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3196bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3197bef8e0ddSBarry Smith } 3198bef8e0ddSBarry Smith aij->nz = nz; 3199bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3200bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3201bef8e0ddSBarry Smith } 3202bef8e0ddSBarry Smith PetscFunctionReturn(0); 3203bef8e0ddSBarry Smith } 3204bef8e0ddSBarry Smith 3205bef8e0ddSBarry Smith /*@ 3206bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3207bef8e0ddSBarry Smith in the matrix. 3208bef8e0ddSBarry Smith 3209bef8e0ddSBarry Smith Input Parameters: 3210bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3211bef8e0ddSBarry Smith - indices - the column indices 3212bef8e0ddSBarry Smith 321315091d37SBarry Smith Level: advanced 321415091d37SBarry Smith 3215bef8e0ddSBarry Smith Notes: 3216bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3217bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3218bef8e0ddSBarry Smith of the MatSetValues() operation. 3219bef8e0ddSBarry Smith 3220bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3221d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3222bef8e0ddSBarry Smith 3223bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3224bef8e0ddSBarry Smith 3225b9617806SBarry Smith The indices should start with zero, not one. 3226b9617806SBarry Smith 3227bef8e0ddSBarry Smith @*/ 32287087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3229bef8e0ddSBarry Smith { 32304ac538c5SBarry Smith PetscErrorCode ierr; 3231bef8e0ddSBarry Smith 3232bef8e0ddSBarry Smith PetscFunctionBegin; 32330700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 32344482741eSBarry Smith PetscValidPointer(indices,2); 32354ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3236bef8e0ddSBarry Smith PetscFunctionReturn(0); 3237bef8e0ddSBarry Smith } 3238bef8e0ddSBarry Smith 3239be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3240be6bf707SBarry Smith 32417087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3242be6bf707SBarry Smith { 3243be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 32446849ba73SBarry Smith PetscErrorCode ierr; 3245d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3246be6bf707SBarry Smith 3247be6bf707SBarry Smith PetscFunctionBegin; 3248169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3249be6bf707SBarry Smith 3250be6bf707SBarry Smith /* allocate space for values if not already there */ 3251be6bf707SBarry Smith if (!aij->saved_values) { 3252854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 32533bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3254be6bf707SBarry Smith } 3255be6bf707SBarry Smith 3256be6bf707SBarry Smith /* copy values over */ 325787828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3258be6bf707SBarry Smith PetscFunctionReturn(0); 3259be6bf707SBarry Smith } 3260be6bf707SBarry Smith 3261be6bf707SBarry Smith /*@ 3262be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3263be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3264be6bf707SBarry Smith nonlinear portion. 3265be6bf707SBarry Smith 3266be6bf707SBarry Smith Collect on Mat 3267be6bf707SBarry Smith 3268be6bf707SBarry Smith Input Parameters: 32690e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3270be6bf707SBarry Smith 327115091d37SBarry Smith Level: advanced 327215091d37SBarry Smith 3273be6bf707SBarry Smith Common Usage, with SNESSolve(): 3274be6bf707SBarry Smith $ Create Jacobian matrix 3275be6bf707SBarry Smith $ Set linear terms into matrix 3276be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3277be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3278be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3279512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3280be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3281be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3282be6bf707SBarry Smith $ In your Jacobian routine 3283be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3284be6bf707SBarry Smith $ Set nonlinear terms in matrix 3285be6bf707SBarry Smith 3286be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3287be6bf707SBarry Smith $ // build linear portion of Jacobian 3288512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3289be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3290be6bf707SBarry Smith $ loop over nonlinear iterations 3291be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3292be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3293be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3294be6bf707SBarry Smith $ Solve linear system with Jacobian 3295be6bf707SBarry Smith $ endloop 3296be6bf707SBarry Smith 3297be6bf707SBarry Smith Notes: 3298be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3299512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3300be6bf707SBarry Smith calling this routine. 3301be6bf707SBarry Smith 33020c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33030c468ba9SBarry Smith and does not allocated additional space. 33040c468ba9SBarry Smith 3305be6bf707SBarry Smith .seealso: MatRetrieveValues() 3306be6bf707SBarry Smith 3307be6bf707SBarry Smith @*/ 33087087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3309be6bf707SBarry Smith { 33104ac538c5SBarry Smith PetscErrorCode ierr; 3311be6bf707SBarry Smith 3312be6bf707SBarry Smith PetscFunctionBegin; 33130700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3314e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3315e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33164ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3317be6bf707SBarry Smith PetscFunctionReturn(0); 3318be6bf707SBarry Smith } 3319be6bf707SBarry Smith 33207087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3321be6bf707SBarry Smith { 3322be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33236849ba73SBarry Smith PetscErrorCode ierr; 3324d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3325be6bf707SBarry Smith 3326be6bf707SBarry Smith PetscFunctionBegin; 3327169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3328f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3329be6bf707SBarry Smith /* copy values over */ 333087828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3331be6bf707SBarry Smith PetscFunctionReturn(0); 3332be6bf707SBarry Smith } 3333be6bf707SBarry Smith 3334be6bf707SBarry Smith /*@ 3335be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3336be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3337be6bf707SBarry Smith nonlinear portion. 3338be6bf707SBarry Smith 3339be6bf707SBarry Smith Collect on Mat 3340be6bf707SBarry Smith 3341be6bf707SBarry Smith Input Parameters: 3342386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3343be6bf707SBarry Smith 334415091d37SBarry Smith Level: advanced 334515091d37SBarry Smith 3346be6bf707SBarry Smith .seealso: MatStoreValues() 3347be6bf707SBarry Smith 3348be6bf707SBarry Smith @*/ 33497087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3350be6bf707SBarry Smith { 33514ac538c5SBarry Smith PetscErrorCode ierr; 3352be6bf707SBarry Smith 3353be6bf707SBarry Smith PetscFunctionBegin; 33540700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3355e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3356e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33574ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3358be6bf707SBarry Smith PetscFunctionReturn(0); 3359be6bf707SBarry Smith } 3360be6bf707SBarry Smith 3361f83d6046SBarry Smith 3362be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 336317ab2063SBarry Smith /*@C 3364682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 33650d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 33666e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 336751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 33682bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 336917ab2063SBarry Smith 3370db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3371db81eaa0SLois Curfman McInnes 337217ab2063SBarry Smith Input Parameters: 3373db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 337417ab2063SBarry Smith . m - number of rows 337517ab2063SBarry Smith . n - number of columns 337617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 337751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 33780298fd71SBarry Smith (possibly different for each row) or NULL 337917ab2063SBarry Smith 338017ab2063SBarry Smith Output Parameter: 3381416022c9SBarry Smith . A - the matrix 338217ab2063SBarry Smith 3383175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3384ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3385175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3386175b88e8SBarry Smith 3387b259b22eSLois Curfman McInnes Notes: 338849a6f317SBarry Smith If nnz is given then nz is ignored 338949a6f317SBarry Smith 339017ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 339117ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 33920002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 339344cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 339417ab2063SBarry Smith 339517ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 33960298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 33973d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 33986da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 339917ab2063SBarry Smith 3400682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 34014fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3402682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34036c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34046c7ebb05SLois Curfman McInnes 34056c7ebb05SLois Curfman McInnes Options Database Keys: 3406698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34079db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 340817ab2063SBarry Smith 3409027ccd11SLois Curfman McInnes Level: intermediate 3410027ccd11SLois Curfman McInnes 341169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 341236db0b34SBarry Smith 341317ab2063SBarry Smith @*/ 34147087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 341517ab2063SBarry Smith { 3416dfbe8321SBarry Smith PetscErrorCode ierr; 34176945ee14SBarry Smith 34183a40ed3dSBarry Smith PetscFunctionBegin; 3419f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3420117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3421c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3422d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3423273d9f13SBarry Smith PetscFunctionReturn(0); 3424273d9f13SBarry Smith } 3425273d9f13SBarry Smith 3426273d9f13SBarry Smith /*@C 3427273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3428273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3429273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3430273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3431273d9f13SBarry Smith 3432273d9f13SBarry Smith Collective on MPI_Comm 3433273d9f13SBarry Smith 3434273d9f13SBarry Smith Input Parameters: 34351c4f3114SJed Brown + B - The matrix 3436273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3437273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34380298fd71SBarry Smith (possibly different for each row) or NULL 3439273d9f13SBarry Smith 3440273d9f13SBarry Smith Notes: 344149a6f317SBarry Smith If nnz is given then nz is ignored 344249a6f317SBarry Smith 3443273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3444273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3445273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3446273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3447273d9f13SBarry Smith 3448273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34490298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3450273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3451273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3452273d9f13SBarry Smith 3453aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3454aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3455aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3456aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3457aa95bbe8SBarry Smith 3458a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3459a96a251dSBarry Smith entries or columns indices 3460a96a251dSBarry Smith 3461273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3462273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3463273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3464273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3465273d9f13SBarry Smith 3466273d9f13SBarry Smith Options Database Keys: 3467698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3468698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3469273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3470273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3471273d9f13SBarry Smith the user still MUST index entries starting at 0! 3472273d9f13SBarry Smith 3473273d9f13SBarry Smith Level: intermediate 3474273d9f13SBarry Smith 347569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3476273d9f13SBarry Smith 3477273d9f13SBarry Smith @*/ 34787087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3479273d9f13SBarry Smith { 34804ac538c5SBarry Smith PetscErrorCode ierr; 3481a23d5eceSKris Buschelman 3482a23d5eceSKris Buschelman PetscFunctionBegin; 34836ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 34846ba663aaSJed Brown PetscValidType(B,1); 34854ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3486a23d5eceSKris Buschelman PetscFunctionReturn(0); 3487a23d5eceSKris Buschelman } 3488a23d5eceSKris Buschelman 34897087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3490a23d5eceSKris Buschelman { 3491273d9f13SBarry Smith Mat_SeqAIJ *b; 34922576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 34936849ba73SBarry Smith PetscErrorCode ierr; 349497f1f81fSBarry Smith PetscInt i; 3495273d9f13SBarry Smith 3496273d9f13SBarry Smith PetscFunctionBegin; 34972576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3498a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3499c461c341SBarry Smith skipallocation = PETSC_TRUE; 3500c461c341SBarry Smith nz = 0; 3501c461c341SBarry Smith } 3502c461c341SBarry Smith 350326283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 350426283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3505899cda47SBarry Smith 3506435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 350760e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3508b73539f3SBarry Smith if (nnz) { 3509d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 351060e0710aSBarry 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]); 351160e0710aSBarry 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); 3512b73539f3SBarry Smith } 3513b73539f3SBarry Smith } 3514b73539f3SBarry Smith 3515273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35162205254eSKarl Rupp 3517273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3518273d9f13SBarry Smith 3519ab93d7beSBarry Smith if (!skipallocation) { 35202ee49352SLisandro Dalcin if (!b->imax) { 3521dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 35223bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 35232ee49352SLisandro Dalcin } 3524273d9f13SBarry Smith if (!nnz) { 3525435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3526c62bd62aSJed Brown else if (nz < 0) nz = 1; 3527d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3528d0f46423SBarry Smith nz = nz*B->rmap->n; 3529273d9f13SBarry Smith } else { 3530273d9f13SBarry Smith nz = 0; 3531d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3532273d9f13SBarry Smith } 3533ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 35342205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3535ab93d7beSBarry Smith 3536273d9f13SBarry Smith /* allocate the matrix space */ 353753dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 35382ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3539dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 35403bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3541bfeeae90SHong Zhang b->i[0] = 0; 3542d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 35435da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 35445da197adSKris Buschelman } 3545273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3546e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3547e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3548c461c341SBarry Smith } else { 3549e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3550e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3551c461c341SBarry Smith } 3552273d9f13SBarry Smith 3553273d9f13SBarry Smith b->nz = 0; 3554273d9f13SBarry Smith b->maxnz = nz; 3555273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 35562205254eSKarl Rupp if (realalloc) { 35572205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 35582205254eSKarl Rupp } 3559cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3560cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3561273d9f13SBarry Smith PetscFunctionReturn(0); 3562273d9f13SBarry Smith } 3563273d9f13SBarry Smith 356458d36128SBarry Smith /*@ 3565a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3566a1661176SMatthew Knepley 3567a1661176SMatthew Knepley Input Parameters: 3568a1661176SMatthew Knepley + B - the matrix 3569a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3570a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3571a1661176SMatthew Knepley - v - optional values in the matrix 3572a1661176SMatthew Knepley 3573a1661176SMatthew Knepley Level: developer 3574a1661176SMatthew Knepley 357558d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 357658d36128SBarry Smith 3577a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3578a1661176SMatthew Knepley 3579a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3580a1661176SMatthew Knepley @*/ 3581a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3582a1661176SMatthew Knepley { 3583a1661176SMatthew Knepley PetscErrorCode ierr; 3584a1661176SMatthew Knepley 3585a1661176SMatthew Knepley PetscFunctionBegin; 35860700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35876ba663aaSJed Brown PetscValidType(B,1); 35884ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3589a1661176SMatthew Knepley PetscFunctionReturn(0); 3590a1661176SMatthew Knepley } 3591a1661176SMatthew Knepley 35927087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3593a1661176SMatthew Knepley { 3594a1661176SMatthew Knepley PetscInt i; 3595a1661176SMatthew Knepley PetscInt m,n; 3596a1661176SMatthew Knepley PetscInt nz; 3597a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3598a1661176SMatthew Knepley PetscScalar *values; 3599a1661176SMatthew Knepley PetscErrorCode ierr; 3600a1661176SMatthew Knepley 3601a1661176SMatthew Knepley PetscFunctionBegin; 360265e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3603779a8d59SSatish Balay 3604779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3605779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3606779a8d59SSatish Balay 3607779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3608854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 3609a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3610b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3611a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 361265e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3613a1661176SMatthew Knepley nnz[i] = nz; 3614a1661176SMatthew Knepley } 3615a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3616a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3617a1661176SMatthew Knepley 3618a1661176SMatthew Knepley if (v) { 3619a1661176SMatthew Knepley values = (PetscScalar*) v; 3620a1661176SMatthew Knepley } else { 36211795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3622a1661176SMatthew Knepley } 3623a1661176SMatthew Knepley 3624a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3625b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3626b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3627a1661176SMatthew Knepley } 3628a1661176SMatthew Knepley 3629a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3630a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3631a1661176SMatthew Knepley 3632a1661176SMatthew Knepley if (!v) { 3633a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3634a1661176SMatthew Knepley } 36357827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3636a1661176SMatthew Knepley PetscFunctionReturn(0); 3637a1661176SMatthew Knepley } 3638a1661176SMatthew Knepley 3639c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3640af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 3641170fe5c8SBarry Smith 3642170fe5c8SBarry Smith /* 3643170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3644170fe5c8SBarry Smith 3645170fe5c8SBarry Smith n p p 3646170fe5c8SBarry Smith ( ) ( ) ( ) 3647170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3648170fe5c8SBarry Smith ( ) ( ) ( ) 3649170fe5c8SBarry Smith 3650170fe5c8SBarry Smith */ 3651170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3652170fe5c8SBarry Smith { 3653170fe5c8SBarry Smith PetscErrorCode ierr; 3654170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3655170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3656170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 36571de00fd4SBarry Smith PetscInt i,n,m,q,p; 3658170fe5c8SBarry Smith const PetscInt *ii,*idx; 3659170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3660170fe5c8SBarry Smith PetscScalar *c,*c_q; 3661170fe5c8SBarry Smith 3662170fe5c8SBarry Smith PetscFunctionBegin; 3663d0f46423SBarry Smith m = A->rmap->n; 3664d0f46423SBarry Smith n = A->cmap->n; 3665d0f46423SBarry Smith p = B->cmap->n; 3666170fe5c8SBarry Smith a = sub_a->v; 3667170fe5c8SBarry Smith b = sub_b->a; 3668170fe5c8SBarry Smith c = sub_c->v; 3669170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3670170fe5c8SBarry Smith 3671170fe5c8SBarry Smith ii = sub_b->i; 3672170fe5c8SBarry Smith idx = sub_b->j; 3673170fe5c8SBarry Smith for (i=0; i<n; i++) { 3674170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3675170fe5c8SBarry Smith while (q-->0) { 3676170fe5c8SBarry Smith c_q = c + m*(*idx); 3677170fe5c8SBarry Smith a_q = a + m*i; 3678854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3679170fe5c8SBarry Smith idx++; 3680170fe5c8SBarry Smith b++; 3681170fe5c8SBarry Smith } 3682170fe5c8SBarry Smith } 3683170fe5c8SBarry Smith PetscFunctionReturn(0); 3684170fe5c8SBarry Smith } 3685170fe5c8SBarry Smith 3686170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3687170fe5c8SBarry Smith { 3688170fe5c8SBarry Smith PetscErrorCode ierr; 3689d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3690170fe5c8SBarry Smith Mat Cmat; 3691170fe5c8SBarry Smith 3692170fe5c8SBarry Smith PetscFunctionBegin; 369360e0710aSBarry 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); 3694ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3695170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 369633d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 3697170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 36980298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3699d73949e8SHong Zhang 3700d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 37012205254eSKarl Rupp 3702170fe5c8SBarry Smith *C = Cmat; 3703170fe5c8SBarry Smith PetscFunctionReturn(0); 3704170fe5c8SBarry Smith } 3705170fe5c8SBarry Smith 3706170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3707150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3708170fe5c8SBarry Smith { 3709170fe5c8SBarry Smith PetscErrorCode ierr; 3710170fe5c8SBarry Smith 3711170fe5c8SBarry Smith PetscFunctionBegin; 3712170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 37133ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3714170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 37153ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3716170fe5c8SBarry Smith } 37173ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3718170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 37193ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3720170fe5c8SBarry Smith PetscFunctionReturn(0); 3721170fe5c8SBarry Smith } 3722170fe5c8SBarry Smith 3723170fe5c8SBarry Smith 37240bad9183SKris Buschelman /*MC 3725fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 37260bad9183SKris Buschelman based on compressed sparse row format. 37270bad9183SKris Buschelman 37280bad9183SKris Buschelman Options Database Keys: 37290bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 37300bad9183SKris Buschelman 37310bad9183SKris Buschelman Level: beginner 37320bad9183SKris Buschelman 3733f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 37340bad9183SKris Buschelman M*/ 37350bad9183SKris Buschelman 3736ccd284c7SBarry Smith /*MC 3737ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3738ccd284c7SBarry Smith 3739ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3740ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 3741ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 3742ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3743ccd284c7SBarry Smith the above preallocation routines for simplicity. 3744ccd284c7SBarry Smith 3745ccd284c7SBarry Smith Options Database Keys: 3746ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 3747ccd284c7SBarry Smith 3748ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 3749ccd284c7SBarry Smith enough exist. 3750ccd284c7SBarry Smith 3751ccd284c7SBarry Smith Level: beginner 3752ccd284c7SBarry Smith 3753ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 3754ccd284c7SBarry Smith M*/ 3755ccd284c7SBarry Smith 3756ccd284c7SBarry Smith /*MC 3757ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 3758ccd284c7SBarry Smith 3759ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 3760ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 3761ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 3762ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3763ccd284c7SBarry Smith the above preallocation routines for simplicity. 3764ccd284c7SBarry Smith 3765ccd284c7SBarry Smith Options Database Keys: 3766ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 3767ccd284c7SBarry Smith 3768ccd284c7SBarry Smith Level: beginner 3769ccd284c7SBarry Smith 3770ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 3771ccd284c7SBarry Smith M*/ 3772ccd284c7SBarry Smith 3773cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 3774af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3775cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 3776af8000cdSHong Zhang #endif 377763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 377863c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 37793dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 378063c07aadSStefano Zampini #endif 3781cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 378242c9c57cSBarry Smith 3783b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 378429b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 378529b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3786b3866ffcSBarry Smith #endif 378717667f90SBarry Smith 3788c0c8ee5eSDmitry Karpeev 37898c778c55SBarry Smith /*@C 37908397e458SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored 37918c778c55SBarry Smith 37928c778c55SBarry Smith Not Collective 37938c778c55SBarry Smith 37948c778c55SBarry Smith Input Parameter: 3795579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 37968c778c55SBarry Smith 37978c778c55SBarry Smith Output Parameter: 37988c778c55SBarry Smith . array - pointer to the data 37998c778c55SBarry Smith 38008c778c55SBarry Smith Level: intermediate 38018c778c55SBarry Smith 3802774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 38038c778c55SBarry Smith @*/ 38048c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 38058c778c55SBarry Smith { 38068c778c55SBarry Smith PetscErrorCode ierr; 38078c778c55SBarry Smith 38088c778c55SBarry Smith PetscFunctionBegin; 38098c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38108c778c55SBarry Smith PetscFunctionReturn(0); 38118c778c55SBarry Smith } 38128c778c55SBarry Smith 381321e72a00SBarry Smith /*@C 381421e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 381521e72a00SBarry Smith 381621e72a00SBarry Smith Not Collective 381721e72a00SBarry Smith 381821e72a00SBarry Smith Input Parameter: 3819579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 382021e72a00SBarry Smith 382121e72a00SBarry Smith Output Parameter: 382221e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 382321e72a00SBarry Smith 382421e72a00SBarry Smith Level: intermediate 382521e72a00SBarry Smith 382621e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 382721e72a00SBarry Smith @*/ 382821e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 382921e72a00SBarry Smith { 383021e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 383121e72a00SBarry Smith 383221e72a00SBarry Smith PetscFunctionBegin; 383321e72a00SBarry Smith *nz = aij->rmax; 383421e72a00SBarry Smith PetscFunctionReturn(0); 383521e72a00SBarry Smith } 383621e72a00SBarry Smith 38378c778c55SBarry Smith /*@C 3838579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 38398c778c55SBarry Smith 38408c778c55SBarry Smith Not Collective 38418c778c55SBarry Smith 38428c778c55SBarry Smith Input Parameters: 3843579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38448c778c55SBarry Smith . array - pointer to the data 38458c778c55SBarry Smith 38468c778c55SBarry Smith Level: intermediate 38478c778c55SBarry Smith 3848774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 38498c778c55SBarry Smith @*/ 38508c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 38518c778c55SBarry Smith { 38528c778c55SBarry Smith PetscErrorCode ierr; 38538c778c55SBarry Smith 38548c778c55SBarry Smith PetscFunctionBegin; 38558c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38568c778c55SBarry Smith PetscFunctionReturn(0); 38578c778c55SBarry Smith } 38588c778c55SBarry Smith 38598cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 3860273d9f13SBarry Smith { 3861273d9f13SBarry Smith Mat_SeqAIJ *b; 3862dfbe8321SBarry Smith PetscErrorCode ierr; 386338baddfdSBarry Smith PetscMPIInt size; 3864273d9f13SBarry Smith 3865273d9f13SBarry Smith PetscFunctionBegin; 3866ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 3867e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3868273d9f13SBarry Smith 3869b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 38702205254eSKarl Rupp 3871b0a32e0cSBarry Smith B->data = (void*)b; 38722205254eSKarl Rupp 3873549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 38742205254eSKarl Rupp 3875416022c9SBarry Smith b->row = 0; 3876416022c9SBarry Smith b->col = 0; 387782bf6240SBarry Smith b->icol = 0; 3878b810aeb4SBarry Smith b->reallocs = 0; 387936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3880f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3881416022c9SBarry Smith b->nonew = 0; 3882416022c9SBarry Smith b->diag = 0; 3883416022c9SBarry Smith b->solve_work = 0; 38842a1b7f2aSHong Zhang B->spptr = 0; 3885be6bf707SBarry Smith b->saved_values = 0; 3886d7f994e1SBarry Smith b->idiag = 0; 388771f1c65dSBarry Smith b->mdiag = 0; 388871f1c65dSBarry Smith b->ssor_work = 0; 388971f1c65dSBarry Smith b->omega = 1.0; 389071f1c65dSBarry Smith b->fshift = 0.0; 389171f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3892bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3893a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 389417ab2063SBarry Smith 389535d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3896bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 3897bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 38988c778c55SBarry Smith 3899b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3900bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3901bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3902b3866ffcSBarry Smith #endif 390317f1a0eaSHong Zhang 3904bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3905bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3906bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3907bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3908bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3909bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3910bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3911af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3912af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 3913af8000cdSHong Zhang #endif 391463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 391563c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 39163dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 391763c07aadSStefano Zampini #endif 3918b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 3919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3921bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3922bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3923bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3924bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3925bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3926bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 39274108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 392817667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 39293a40ed3dSBarry Smith PetscFunctionReturn(0); 393017ab2063SBarry Smith } 393117ab2063SBarry Smith 3932b24902e0SBarry Smith /* 3933b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3934b24902e0SBarry Smith */ 3935ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 393617ab2063SBarry Smith { 3937416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 39386849ba73SBarry Smith PetscErrorCode ierr; 3939d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 394017ab2063SBarry Smith 39413a40ed3dSBarry Smith PetscFunctionBegin; 3942273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3943273d9f13SBarry Smith 3944d5f3da31SBarry Smith C->factortype = A->factortype; 3945416022c9SBarry Smith c->row = 0; 3946416022c9SBarry Smith c->col = 0; 394782bf6240SBarry Smith c->icol = 0; 39486ad4291fSHong Zhang c->reallocs = 0; 394917ab2063SBarry Smith 39506ad4291fSHong Zhang C->assembled = PETSC_TRUE; 395117ab2063SBarry Smith 3952aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3953aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3954eec197d1SBarry Smith 3955dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 39563bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 395717ab2063SBarry Smith for (i=0; i<m; i++) { 3958416022c9SBarry Smith c->imax[i] = a->imax[i]; 3959416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 396017ab2063SBarry Smith } 396117ab2063SBarry Smith 396217ab2063SBarry Smith /* allocate the matrix space */ 3963f77e22a1SHong Zhang if (mallocmatspace) { 3964dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 39653bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 39662205254eSKarl Rupp 3967f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 39682205254eSKarl Rupp 396997f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 397017ab2063SBarry Smith if (m > 0) { 397197f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3972be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3973bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3974be6bf707SBarry Smith } else { 3975bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 397617ab2063SBarry Smith } 397708480c60SBarry Smith } 3978f77e22a1SHong Zhang } 397917ab2063SBarry Smith 39806ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3981416022c9SBarry Smith c->roworiented = a->roworiented; 3982416022c9SBarry Smith c->nonew = a->nonew; 3983416022c9SBarry Smith if (a->diag) { 3984854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 39853bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 398617ab2063SBarry Smith for (i=0; i<m; i++) { 3987416022c9SBarry Smith c->diag[i] = a->diag[i]; 398817ab2063SBarry Smith } 39893a40ed3dSBarry Smith } else c->diag = 0; 39902205254eSKarl Rupp 39916ad4291fSHong Zhang c->solve_work = 0; 39926ad4291fSHong Zhang c->saved_values = 0; 39936ad4291fSHong Zhang c->idiag = 0; 399471f1c65dSBarry Smith c->ssor_work = 0; 3995a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 3996e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3997e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 39986ad4291fSHong Zhang 3999893ad86cSHong Zhang c->rmax = a->rmax; 4000416022c9SBarry Smith c->nz = a->nz; 40018ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4002273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4003754ec7b1SSatish Balay 40046ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 40056ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4006cd6b891eSBarry Smith if (a->compressedrow.use) { 40076ad4291fSHong Zhang i = a->compressedrow.nrows; 4008dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 40096ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 40106ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 401127ea64f8SHong Zhang } else { 401227ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 40130298fd71SBarry Smith c->compressedrow.i = NULL; 40140298fd71SBarry Smith c->compressedrow.rindex = NULL; 40156ad4291fSHong Zhang } 4016ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4017e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 40184846f1f5SKris Buschelman 40192205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4020140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 40213a40ed3dSBarry Smith PetscFunctionReturn(0); 402217ab2063SBarry Smith } 402317ab2063SBarry Smith 4024b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4025b24902e0SBarry Smith { 4026b24902e0SBarry Smith PetscErrorCode ierr; 4027b24902e0SBarry Smith 4028b24902e0SBarry Smith PetscFunctionBegin; 4029ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 40304b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4031cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 403233d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4033cfd3f464SBarry Smith } 4034a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4035f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4036b24902e0SBarry Smith PetscFunctionReturn(0); 4037b24902e0SBarry Smith } 4038b24902e0SBarry Smith 4039112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4040fbdbba38SShri Abhyankar { 4041fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4042fbdbba38SShri Abhyankar PetscErrorCode ierr; 4043fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4044fbdbba38SShri Abhyankar int fd; 4045fbdbba38SShri Abhyankar PetscMPIInt size; 4046fbdbba38SShri Abhyankar MPI_Comm comm; 40473059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4048fbdbba38SShri Abhyankar 4049fbdbba38SShri Abhyankar PetscFunctionBegin; 4050c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 4051c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4052fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4053fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4054fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4055bbead8a2SBarry Smith 40560298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 40570298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4058bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 40593059b6faSBarry Smith if (bs < 0) bs = 1; 40603059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4061bbead8a2SBarry Smith 4062fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4063fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4064fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4065fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4066fbdbba38SShri Abhyankar 4067bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4068fbdbba38SShri Abhyankar 4069fbdbba38SShri Abhyankar /* read in row lengths */ 4070785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4071fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4072fbdbba38SShri Abhyankar 4073fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4074fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 407560e0710aSBarry 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); 4076fbdbba38SShri Abhyankar 4077fbdbba38SShri Abhyankar /* set global size if not set already*/ 4078f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4079fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4080aabbc4fbSShri Abhyankar } else { 40819d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4082fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 40834c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 40844c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 40854c5b953cSHong Zhang } 408660e0710aSBarry 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); 4087aabbc4fbSShri Abhyankar } 4088fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4089fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4090fbdbba38SShri Abhyankar 4091fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4092fbdbba38SShri Abhyankar 4093fbdbba38SShri Abhyankar /* read in nonzero values */ 4094fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4095fbdbba38SShri Abhyankar 4096fbdbba38SShri Abhyankar /* set matrix "i" values */ 4097fbdbba38SShri Abhyankar a->i[0] = 0; 4098fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4099fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4100fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4101fbdbba38SShri Abhyankar } 4102fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4103fbdbba38SShri Abhyankar 4104fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4105fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4106fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4107fbdbba38SShri Abhyankar } 4108fbdbba38SShri Abhyankar 4109ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 41107264ac53SSatish Balay { 41117264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4112dfbe8321SBarry Smith PetscErrorCode ierr; 4113eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4114eeffb40dSHong Zhang PetscInt k; 4115eeffb40dSHong Zhang #endif 41167264ac53SSatish Balay 41173a40ed3dSBarry Smith PetscFunctionBegin; 4118bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4119d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4120ca44d042SBarry Smith *flg = PETSC_FALSE; 4121ca44d042SBarry Smith PetscFunctionReturn(0); 4122bcd2baecSBarry Smith } 41237264ac53SSatish Balay 41247264ac53SSatish Balay /* if the a->i are the same */ 4125d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4126abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 41277264ac53SSatish Balay 41287264ac53SSatish Balay /* if a->j are the same */ 412997f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4130abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4131bcd2baecSBarry Smith 4132bcd2baecSBarry Smith /* if a->a are the same */ 4133eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4134eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4135eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4136eeffb40dSHong Zhang *flg = PETSC_FALSE; 41373a40ed3dSBarry Smith PetscFunctionReturn(0); 4138eeffb40dSHong Zhang } 4139eeffb40dSHong Zhang } 4140eeffb40dSHong Zhang #else 4141eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4142eeffb40dSHong Zhang #endif 4143eeffb40dSHong Zhang PetscFunctionReturn(0); 41447264ac53SSatish Balay } 414536db0b34SBarry Smith 414605869f15SSatish Balay /*@ 414736db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 414836db0b34SBarry Smith provided by the user. 414936db0b34SBarry Smith 4150c75a6043SHong Zhang Collective on MPI_Comm 415136db0b34SBarry Smith 415236db0b34SBarry Smith Input Parameters: 415336db0b34SBarry Smith + comm - must be an MPI communicator of size 1 415436db0b34SBarry Smith . m - number of rows 415536db0b34SBarry Smith . n - number of columns 415636db0b34SBarry Smith . i - row indices 415736db0b34SBarry Smith . j - column indices 415836db0b34SBarry Smith - a - matrix values 415936db0b34SBarry Smith 416036db0b34SBarry Smith Output Parameter: 416136db0b34SBarry Smith . mat - the matrix 416236db0b34SBarry Smith 416336db0b34SBarry Smith Level: intermediate 416436db0b34SBarry Smith 416536db0b34SBarry Smith Notes: 41660551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4167292fb18eSBarry Smith once the matrix is destroyed and not before 416836db0b34SBarry Smith 416936db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 417036db0b34SBarry Smith 4171bfeeae90SHong Zhang The i and j indices are 0 based 417236db0b34SBarry Smith 4173a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4174a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 41758eef79e4SBarry Smith as shown 4176a4552177SSatish Balay 41778eef79e4SBarry Smith $ 1 0 0 41788eef79e4SBarry Smith $ 2 0 3 41798eef79e4SBarry Smith $ 4 5 6 41808eef79e4SBarry Smith $ 41818eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 41828eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 41838eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4184a4552177SSatish Balay 41859985e31cSBarry Smith 418669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 418736db0b34SBarry Smith 418836db0b34SBarry Smith @*/ 4189c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 419036db0b34SBarry Smith { 4191dfbe8321SBarry Smith PetscErrorCode ierr; 4192cbcfb4deSHong Zhang PetscInt ii; 419336db0b34SBarry Smith Mat_SeqAIJ *aij; 4194cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4195cbcfb4deSHong Zhang PetscInt jj; 4196cbcfb4deSHong Zhang #endif 419736db0b34SBarry Smith 419836db0b34SBarry Smith PetscFunctionBegin; 419941096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4200f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4201f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4202a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4203ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4204ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4205ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4206dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4207ab93d7beSBarry Smith 420836db0b34SBarry Smith aij->i = i; 420936db0b34SBarry Smith aij->j = j; 421036db0b34SBarry Smith aij->a = a; 421136db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 421236db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4213e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4214e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 421536db0b34SBarry Smith 421636db0b34SBarry Smith for (ii=0; ii<m; ii++) { 421736db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 42182515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 421960e0710aSBarry 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]); 42209985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4221e32f2f54SBarry 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); 4222e32f2f54SBarry 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); 42239985e31cSBarry Smith } 422436db0b34SBarry Smith #endif 422536db0b34SBarry Smith } 42262515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 422736db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 422860e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 422960e0710aSBarry 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]); 423036db0b34SBarry Smith } 423136db0b34SBarry Smith #endif 423236db0b34SBarry Smith 4233b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4234b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 423536db0b34SBarry Smith PetscFunctionReturn(0); 423636db0b34SBarry Smith } 423780ef6e79SMatthew G Knepley /*@C 4238d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 42398a0b0e6bSVictor Minden provided by the user. 42408a0b0e6bSVictor Minden 42418a0b0e6bSVictor Minden Collective on MPI_Comm 42428a0b0e6bSVictor Minden 42438a0b0e6bSVictor Minden Input Parameters: 42448a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 42458a0b0e6bSVictor Minden . m - number of rows 42468a0b0e6bSVictor Minden . n - number of columns 42478a0b0e6bSVictor Minden . i - row indices 42488a0b0e6bSVictor Minden . j - column indices 42491230e6d1SVictor Minden . a - matrix values 42501230e6d1SVictor Minden . nz - number of nonzeros 42511230e6d1SVictor Minden - idx - 0 or 1 based 42528a0b0e6bSVictor Minden 42538a0b0e6bSVictor Minden Output Parameter: 42548a0b0e6bSVictor Minden . mat - the matrix 42558a0b0e6bSVictor Minden 42568a0b0e6bSVictor Minden Level: intermediate 42578a0b0e6bSVictor Minden 42588a0b0e6bSVictor Minden Notes: 42598a0b0e6bSVictor Minden The i and j indices are 0 based 42608a0b0e6bSVictor Minden 42618a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 42628a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 42638a0b0e6bSVictor Minden as shown: 42648a0b0e6bSVictor Minden 42658a0b0e6bSVictor Minden 1 0 0 42668a0b0e6bSVictor Minden 2 0 3 42678a0b0e6bSVictor Minden 4 5 6 42688a0b0e6bSVictor Minden 42698a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 42708a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 42718a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 42728a0b0e6bSVictor Minden 42738a0b0e6bSVictor Minden 427469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 42758a0b0e6bSVictor Minden 42768a0b0e6bSVictor Minden @*/ 4277c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 42788a0b0e6bSVictor Minden { 42798a0b0e6bSVictor Minden PetscErrorCode ierr; 4280d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 42818a0b0e6bSVictor Minden 42828a0b0e6bSVictor Minden 42838a0b0e6bSVictor Minden PetscFunctionBegin; 42841795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 42851230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4286c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 42871230e6d1SVictor Minden } 42888a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 42898a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 42908a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 42911230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 42921230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 42931230e6d1SVictor Minden if (idx) { 42941230e6d1SVictor Minden row = i[ii] - 1; 42951230e6d1SVictor Minden col = j[ii] - 1; 42961230e6d1SVictor Minden } else { 42971230e6d1SVictor Minden row = i[ii]; 42981230e6d1SVictor Minden col = j[ii]; 42998a0b0e6bSVictor Minden } 43001230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 43018a0b0e6bSVictor Minden } 43028a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43038a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4304d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 43058a0b0e6bSVictor Minden PetscFunctionReturn(0); 43068a0b0e6bSVictor Minden } 430736db0b34SBarry Smith 4308acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4309acf2f550SJed Brown { 4310acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4311acf2f550SJed Brown PetscErrorCode ierr; 4312acf2f550SJed Brown 4313acf2f550SJed Brown PetscFunctionBegin; 4314acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4315acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 43162205254eSKarl Rupp 4317acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4318acf2f550SJed Brown PetscFunctionReturn(0); 4319acf2f550SJed Brown } 4320acf2f550SJed Brown 43219c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 43229c8f2541SHong Zhang { 43239c8f2541SHong Zhang PetscErrorCode ierr; 43248761c3d6SHong Zhang PetscMPIInt size; 43259c8f2541SHong Zhang 43269c8f2541SHong Zhang PetscFunctionBegin; 43278761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 43288761c3d6SHong Zhang if (size == 1 && scall == MAT_REUSE_MATRIX) { 43298761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 43308761c3d6SHong Zhang } else { 43319c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 43328761c3d6SHong Zhang } 43339c8f2541SHong Zhang PetscFunctionReturn(0); 43349c8f2541SHong Zhang } 43359c8f2541SHong Zhang 433681824310SBarry Smith /* 433753dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 433853dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 433953dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 434053dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 434153dd7562SDmitry Karpeev */ 434253dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 434353dd7562SDmitry Karpeev { 434453dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 434553dd7562SDmitry Karpeev PetscErrorCode ierr; 434653dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 434753dd7562SDmitry Karpeev PetscBool seqaij; 434853dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 434953dd7562SDmitry Karpeev PetscScalar v; 435053dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 435153dd7562SDmitry Karpeev 435253dd7562SDmitry Karpeev PetscFunctionBegin; 435353dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 435453dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 435553dd7562SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 435653dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 435753dd7562SDmitry Karpeev if (rowemb) { 435853dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 435953dd7562SDmitry 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); 436053dd7562SDmitry Karpeev } else { 43616c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 436253dd7562SDmitry Karpeev } 436353dd7562SDmitry Karpeev if (colemb) { 436453dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 436553dd7562SDmitry 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); 436653dd7562SDmitry Karpeev } else { 436753dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 436853dd7562SDmitry Karpeev } 436953dd7562SDmitry Karpeev 437053dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 437153dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 437253dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 437353dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 437453dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 437553dd7562SDmitry Karpeev } 437653dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 437753dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 437853dd7562SDmitry Karpeev } 437953dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 438053dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 438153dd7562SDmitry Karpeev } 438253dd7562SDmitry Karpeev count = 0; 438353dd7562SDmitry Karpeev rowindices = NULL; 438453dd7562SDmitry Karpeev colindices = NULL; 438553dd7562SDmitry Karpeev if (rowemb) { 438653dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 438753dd7562SDmitry Karpeev } 438853dd7562SDmitry Karpeev if (colemb) { 438953dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 439053dd7562SDmitry Karpeev } 439153dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 439253dd7562SDmitry Karpeev PetscInt row; 439353dd7562SDmitry Karpeev row = i; 439453dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 439553dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 439653dd7562SDmitry Karpeev PetscInt col; 439753dd7562SDmitry Karpeev col = Baij->j[count]; 439853dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 439953dd7562SDmitry Karpeev v = Baij->a[count]; 440053dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 440153dd7562SDmitry Karpeev ++count; 440253dd7562SDmitry Karpeev } 440353dd7562SDmitry Karpeev } 440453dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 440553dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 440653dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 440753dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 440853dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 440953dd7562SDmitry Karpeev PetscFunctionReturn(0); 441053dd7562SDmitry Karpeev } 441153dd7562SDmitry Karpeev 441253dd7562SDmitry Karpeev 441353dd7562SDmitry Karpeev /* 441481824310SBarry Smith Special version for direct calls from Fortran 441581824310SBarry Smith */ 4416af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 441781824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 441881824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 441981824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 442081824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 442181824310SBarry Smith #endif 442281824310SBarry Smith 442381824310SBarry Smith /* Change these macros so can be used in void function */ 442481824310SBarry Smith #undef CHKERRQ 4425ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 442681824310SBarry Smith #undef SETERRQ2 4427e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 44284994cf47SJed Brown #undef SETERRQ3 44294994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 443081824310SBarry Smith 44318cc058d9SJed 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) 443281824310SBarry Smith { 443381824310SBarry Smith Mat A = *AA; 443481824310SBarry Smith PetscInt m = *mm, n = *nn; 443581824310SBarry Smith InsertMode is = *isis; 443681824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 443781824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 443881824310SBarry Smith PetscInt *imax,*ai,*ailen; 443981824310SBarry Smith PetscErrorCode ierr; 444081824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 444154f21887SBarry Smith MatScalar *ap,value,*aa; 4442ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4443ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 444481824310SBarry Smith 444581824310SBarry Smith PetscFunctionBegin; 44464994cf47SJed Brown MatCheckPreallocated(A,1); 444781824310SBarry Smith imax = a->imax; 444881824310SBarry Smith ai = a->i; 444981824310SBarry Smith ailen = a->ilen; 445081824310SBarry Smith aj = a->j; 445181824310SBarry Smith aa = a->a; 445281824310SBarry Smith 445381824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 445481824310SBarry Smith row = im[k]; 445581824310SBarry Smith if (row < 0) continue; 445681824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4457ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 445881824310SBarry Smith #endif 445981824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 446081824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 446181824310SBarry Smith low = 0; 446281824310SBarry Smith high = nrow; 446381824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 446481824310SBarry Smith if (in[l] < 0) continue; 446581824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4466ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 446781824310SBarry Smith #endif 446881824310SBarry Smith col = in[l]; 44692205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 44702205254eSKarl Rupp else value = v[k + l*m]; 44712205254eSKarl Rupp 447281824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 447381824310SBarry Smith 44742205254eSKarl Rupp if (col <= lastcol) low = 0; 44752205254eSKarl Rupp else high = nrow; 447681824310SBarry Smith lastcol = col; 447781824310SBarry Smith while (high-low > 5) { 447881824310SBarry Smith t = (low+high)/2; 447981824310SBarry Smith if (rp[t] > col) high = t; 448081824310SBarry Smith else low = t; 448181824310SBarry Smith } 448281824310SBarry Smith for (i=low; i<high; i++) { 448381824310SBarry Smith if (rp[i] > col) break; 448481824310SBarry Smith if (rp[i] == col) { 448581824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 448681824310SBarry Smith else ap[i] = value; 448781824310SBarry Smith goto noinsert; 448881824310SBarry Smith } 448981824310SBarry Smith } 449081824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 449181824310SBarry Smith if (nonew == 1) goto noinsert; 4492ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4493fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 449481824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 449581824310SBarry Smith /* shift up all the later entries in this row */ 449681824310SBarry Smith for (ii=N; ii>=i; ii--) { 449781824310SBarry Smith rp[ii+1] = rp[ii]; 449881824310SBarry Smith ap[ii+1] = ap[ii]; 449981824310SBarry Smith } 450081824310SBarry Smith rp[i] = col; 450181824310SBarry Smith ap[i] = value; 4502e56f5c9eSBarry Smith A->nonzerostate++; 450381824310SBarry Smith noinsert:; 450481824310SBarry Smith low = i + 1; 450581824310SBarry Smith } 450681824310SBarry Smith ailen[row] = nrow; 450781824310SBarry Smith } 450881824310SBarry Smith PetscFunctionReturnVoid(); 450981824310SBarry Smith } 45109f7953f8SBarry Smith 4511