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> 1106873bf2SBarry Smith #include <petsc-private/kernels/blocktranspose.h> 1278b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 1378b84d54SShri Abhyankar #include <petscthreadcomm.h> 1478b84d54SShri Abhyankar #endif 150716a85fSBarry Smith 160716a85fSBarry Smith #undef __FUNCT__ 170716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ" 180716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 190716a85fSBarry Smith { 200716a85fSBarry Smith PetscErrorCode ierr; 210716a85fSBarry Smith PetscInt i,m,n; 220716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 230716a85fSBarry Smith 240716a85fSBarry Smith PetscFunctionBegin; 250716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 260716a85fSBarry Smith ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr); 270716a85fSBarry Smith if (type == NORM_2) { 280716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 290716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 300716a85fSBarry Smith } 310716a85fSBarry Smith } else if (type == NORM_1) { 320716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 330716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 340716a85fSBarry Smith } 350716a85fSBarry Smith } else if (type == NORM_INFINITY) { 360716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 370716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 380716a85fSBarry Smith } 390716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 400716a85fSBarry Smith 410716a85fSBarry Smith if (type == NORM_2) { 428f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 430716a85fSBarry Smith } 440716a85fSBarry Smith PetscFunctionReturn(0); 450716a85fSBarry Smith } 460716a85fSBarry Smith 474a2ae208SSatish Balay #undef __FUNCT__ 48f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private" 49f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 506ce1633cSBarry Smith { 516ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 526ce1633cSBarry Smith const MatScalar *aa = a->a; 536ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 546ce1633cSBarry Smith const PetscInt *jj = a->j,*diag; 556ce1633cSBarry Smith PetscInt *rows; 566ce1633cSBarry Smith PetscErrorCode ierr; 576ce1633cSBarry Smith 586ce1633cSBarry Smith PetscFunctionBegin; 596ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 606ce1633cSBarry Smith diag = a->diag; 616ce1633cSBarry Smith for (i=0; i<m; i++) { 626ce1633cSBarry Smith if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 636ce1633cSBarry Smith cnt++; 646ce1633cSBarry Smith } 656ce1633cSBarry Smith } 66785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 676ce1633cSBarry Smith cnt = 0; 686ce1633cSBarry Smith for (i=0; i<m; i++) { 696ce1633cSBarry Smith if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 706ce1633cSBarry Smith rows[cnt++] = i; 716ce1633cSBarry Smith } 726ce1633cSBarry Smith } 73f1f41ecbSJed Brown *nrows = cnt; 74f1f41ecbSJed Brown *zrows = rows; 75f1f41ecbSJed Brown PetscFunctionReturn(0); 76f1f41ecbSJed Brown } 77f1f41ecbSJed Brown 78f1f41ecbSJed Brown #undef __FUNCT__ 79f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ" 80f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 81f1f41ecbSJed Brown { 82f1f41ecbSJed Brown PetscInt nrows,*rows; 83f1f41ecbSJed Brown PetscErrorCode ierr; 84f1f41ecbSJed Brown 85f1f41ecbSJed Brown PetscFunctionBegin; 860298fd71SBarry Smith *zrows = NULL; 87f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 88ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 896ce1633cSBarry Smith PetscFunctionReturn(0); 906ce1633cSBarry Smith } 916ce1633cSBarry Smith 926ce1633cSBarry Smith #undef __FUNCT__ 93b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ" 94b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 95b3a44c85SBarry Smith { 96b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 97b3a44c85SBarry Smith const MatScalar *aa; 98b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 99b3a44c85SBarry Smith const PetscInt *ii; 100b3a44c85SBarry Smith PetscInt n,i,j,*rows; 101b3a44c85SBarry Smith PetscErrorCode ierr; 102b3a44c85SBarry Smith 103b3a44c85SBarry Smith PetscFunctionBegin; 104b3a44c85SBarry Smith *keptrows = 0; 105b3a44c85SBarry Smith ii = a->i; 106b3a44c85SBarry Smith for (i=0; i<m; i++) { 107b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 108b3a44c85SBarry Smith if (!n) { 109b3a44c85SBarry Smith cnt++; 110b3a44c85SBarry Smith goto ok1; 111b3a44c85SBarry Smith } 112b3a44c85SBarry Smith aa = a->a + ii[i]; 113b3a44c85SBarry Smith for (j=0; j<n; j++) { 114b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 115b3a44c85SBarry Smith } 116b3a44c85SBarry Smith cnt++; 117b3a44c85SBarry Smith ok1:; 118b3a44c85SBarry Smith } 119b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 120785e854fSJed Brown ierr = PetscMalloc1((A->rmap->n-cnt),&rows);CHKERRQ(ierr); 121b3a44c85SBarry Smith cnt = 0; 122b3a44c85SBarry Smith for (i=0; i<m; i++) { 123b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 124b3a44c85SBarry Smith if (!n) continue; 125b3a44c85SBarry Smith aa = a->a + ii[i]; 126b3a44c85SBarry Smith for (j=0; j<n; j++) { 127b3a44c85SBarry Smith if (aa[j] != 0.0) { 128b3a44c85SBarry Smith rows[cnt++] = i; 129b3a44c85SBarry Smith break; 130b3a44c85SBarry Smith } 131b3a44c85SBarry Smith } 132b3a44c85SBarry Smith } 133b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 134b3a44c85SBarry Smith PetscFunctionReturn(0); 135b3a44c85SBarry Smith } 136b3a44c85SBarry Smith 137b3a44c85SBarry Smith #undef __FUNCT__ 13879299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 1397087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 14079299369SBarry Smith { 14179299369SBarry Smith PetscErrorCode ierr; 14279299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 143d0f46423SBarry Smith PetscInt i,*diag, m = Y->rmap->n; 14454f21887SBarry Smith MatScalar *aa = aij->a; 14554f21887SBarry Smith PetscScalar *v; 146ace3abfcSBarry Smith PetscBool missing; 14779299369SBarry Smith 14879299369SBarry Smith PetscFunctionBegin; 14909f38230SBarry Smith if (Y->assembled) { 1500298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 15109f38230SBarry Smith if (!missing) { 15279299369SBarry Smith diag = aij->diag; 15379299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 15479299369SBarry Smith if (is == INSERT_VALUES) { 15579299369SBarry Smith for (i=0; i<m; i++) { 15679299369SBarry Smith aa[diag[i]] = v[i]; 15779299369SBarry Smith } 15879299369SBarry Smith } else { 15979299369SBarry Smith for (i=0; i<m; i++) { 16079299369SBarry Smith aa[diag[i]] += v[i]; 16179299369SBarry Smith } 16279299369SBarry Smith } 16379299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 16479299369SBarry Smith PetscFunctionReturn(0); 16579299369SBarry Smith } 166acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 16709f38230SBarry Smith } 16809f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 16909f38230SBarry Smith PetscFunctionReturn(0); 17009f38230SBarry Smith } 17179299369SBarry Smith 17279299369SBarry Smith #undef __FUNCT__ 1734a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 1741a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 17517ab2063SBarry Smith { 176416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 177dfbe8321SBarry Smith PetscErrorCode ierr; 17897f1f81fSBarry Smith PetscInt i,ishift; 17917ab2063SBarry Smith 1803a40ed3dSBarry Smith PetscFunctionBegin; 181d0f46423SBarry Smith *m = A->rmap->n; 1823a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 183bfeeae90SHong Zhang ishift = 0; 18453e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 1851a83f524SJed Brown ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 186bfeeae90SHong Zhang } else if (oshift == 1) { 1871a83f524SJed Brown PetscInt *tia; 188d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 1893b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 190785e854fSJed Brown ierr = PetscMalloc1((A->rmap->n+1),&tia);CHKERRQ(ierr); 1911a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 1921a83f524SJed Brown *ia = tia; 193ecc77c7aSBarry Smith if (ja) { 1941a83f524SJed Brown PetscInt *tja; 195785e854fSJed Brown ierr = PetscMalloc1((nz+1),&tja);CHKERRQ(ierr); 1961a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 1971a83f524SJed Brown *ja = tja; 198ecc77c7aSBarry Smith } 1996945ee14SBarry Smith } else { 200ecc77c7aSBarry Smith *ia = a->i; 201ecc77c7aSBarry Smith if (ja) *ja = a->j; 202a2ce50c7SBarry Smith } 2033a40ed3dSBarry Smith PetscFunctionReturn(0); 204a2744918SBarry Smith } 205a2744918SBarry Smith 2064a2ae208SSatish Balay #undef __FUNCT__ 2074a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 2081a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2096945ee14SBarry Smith { 210dfbe8321SBarry Smith PetscErrorCode ierr; 2116945ee14SBarry Smith 2123a40ed3dSBarry Smith PetscFunctionBegin; 2133a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 214bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 215606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 216ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 217bcd2baecSBarry Smith } 2183a40ed3dSBarry Smith PetscFunctionReturn(0); 21917ab2063SBarry Smith } 22017ab2063SBarry Smith 2214a2ae208SSatish Balay #undef __FUNCT__ 2224a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 2231a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2243b2fbd54SBarry Smith { 2253b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 226dfbe8321SBarry Smith PetscErrorCode ierr; 227d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 22897f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2293b2fbd54SBarry Smith 2303a40ed3dSBarry Smith PetscFunctionBegin; 231899cda47SBarry Smith *nn = n; 2323a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2333b2fbd54SBarry Smith if (symmetric) { 2341a83f524SJed Brown ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2353b2fbd54SBarry Smith } else { 2361795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 237785e854fSJed Brown ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr); 238785e854fSJed Brown ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr); 2393b2fbd54SBarry Smith jj = a->j; 2403b2fbd54SBarry Smith for (i=0; i<nz; i++) { 241bfeeae90SHong Zhang collengths[jj[i]]++; 2423b2fbd54SBarry Smith } 2433b2fbd54SBarry Smith cia[0] = oshift; 2443b2fbd54SBarry Smith for (i=0; i<n; i++) { 2453b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2463b2fbd54SBarry Smith } 24797f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2483b2fbd54SBarry Smith jj = a->j; 249a93ec695SBarry Smith for (row=0; row<m; row++) { 250a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 251a93ec695SBarry Smith for (i=0; i<mr; i++) { 252bfeeae90SHong Zhang col = *jj++; 2532205254eSKarl Rupp 2543b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2553b2fbd54SBarry Smith } 2563b2fbd54SBarry Smith } 257606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2583b2fbd54SBarry Smith *ia = cia; *ja = cja; 2593b2fbd54SBarry Smith } 2603a40ed3dSBarry Smith PetscFunctionReturn(0); 2613b2fbd54SBarry Smith } 2623b2fbd54SBarry Smith 2634a2ae208SSatish Balay #undef __FUNCT__ 2644a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 2651a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2663b2fbd54SBarry Smith { 267dfbe8321SBarry Smith PetscErrorCode ierr; 268606d414cSSatish Balay 2693a40ed3dSBarry Smith PetscFunctionBegin; 2703a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2713b2fbd54SBarry Smith 272606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 273606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2743a40ed3dSBarry Smith PetscFunctionReturn(0); 2753b2fbd54SBarry Smith } 2763b2fbd54SBarry Smith 2777cee066cSHong Zhang /* 2787cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 2797cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 280040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 2817cee066cSHong Zhang */ 2827cee066cSHong Zhang #undef __FUNCT__ 2837cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color" 2847cee066cSHong 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) 2857cee066cSHong Zhang { 2867cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2877cee066cSHong Zhang PetscErrorCode ierr; 2887cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 2897cee066cSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 2907cee066cSHong Zhang PetscInt *cspidx; 2917cee066cSHong Zhang 2927cee066cSHong Zhang PetscFunctionBegin; 2937cee066cSHong Zhang *nn = n; 2947cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 295625f6d37SHong Zhang 2961795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 297785e854fSJed Brown ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr); 298785e854fSJed Brown ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr); 299785e854fSJed Brown ierr = PetscMalloc1((nz+1),&cspidx);CHKERRQ(ierr); 3007cee066cSHong Zhang jj = a->j; 3017cee066cSHong Zhang for (i=0; i<nz; i++) { 3027cee066cSHong Zhang collengths[jj[i]]++; 3037cee066cSHong Zhang } 3047cee066cSHong Zhang cia[0] = oshift; 3057cee066cSHong Zhang for (i=0; i<n; i++) { 3067cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3077cee066cSHong Zhang } 3087cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 3097cee066cSHong Zhang jj = a->j; 3107cee066cSHong Zhang for (row=0; row<m; row++) { 3117cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3127cee066cSHong Zhang for (i=0; i<mr; i++) { 3137cee066cSHong Zhang col = *jj++; 3147cee066cSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 3157cee066cSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 3167cee066cSHong Zhang } 3177cee066cSHong Zhang } 3187cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 3197cee066cSHong Zhang *ia = cia; *ja = cja; 3207cee066cSHong Zhang *spidx = cspidx; 3217cee066cSHong Zhang PetscFunctionReturn(0); 3227cee066cSHong Zhang } 3237cee066cSHong Zhang 3247cee066cSHong Zhang #undef __FUNCT__ 3257cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color" 3267cee066cSHong 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) 3277cee066cSHong Zhang { 3287cee066cSHong Zhang PetscErrorCode ierr; 3297cee066cSHong Zhang 3307cee066cSHong Zhang PetscFunctionBegin; 3315243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3327cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3337cee066cSHong Zhang PetscFunctionReturn(0); 3347cee066cSHong Zhang } 3357cee066cSHong Zhang 33687d4246cSBarry Smith #undef __FUNCT__ 33787d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 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 3494a2ae208SSatish Balay #undef __FUNCT__ 3504a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 35197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 35217ab2063SBarry Smith { 353416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 354e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 35597f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 3566849ba73SBarry Smith PetscErrorCode ierr; 357e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 35854f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 359ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 360ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 36117ab2063SBarry Smith 3623a40ed3dSBarry Smith PetscFunctionBegin; 36371fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 36417ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 365416022c9SBarry Smith row = im[k]; 3665ef9f2a5SBarry Smith if (row < 0) continue; 3672515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 368e32f2f54SBarry 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); 3693b2fbd54SBarry Smith #endif 370bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 37117ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 372416022c9SBarry Smith low = 0; 373c71e6ed7SBarry Smith high = nrow; 37417ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 3755ef9f2a5SBarry Smith if (in[l] < 0) continue; 3762515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 377e32f2f54SBarry 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); 3783b2fbd54SBarry Smith #endif 379bfeeae90SHong Zhang col = in[l]; 38016371a99SBarry Smith if (v) { 3814b0e389bSBarry Smith if (roworiented) { 3825ef9f2a5SBarry Smith value = v[l + k*n]; 383bef8e0ddSBarry Smith } else { 3844b0e389bSBarry Smith value = v[k + l*m]; 3854b0e389bSBarry Smith } 38616371a99SBarry Smith } else { 38775567043SBarry Smith value = 0.; 38816371a99SBarry Smith } 389abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 39036db0b34SBarry Smith 3912205254eSKarl Rupp if (col <= lastcol) low = 0; 3922205254eSKarl Rupp else high = nrow; 393e2ee6c50SBarry Smith lastcol = col; 394416022c9SBarry Smith while (high-low > 5) { 395416022c9SBarry Smith t = (low+high)/2; 396416022c9SBarry Smith if (rp[t] > col) high = t; 397416022c9SBarry Smith else low = t; 39817ab2063SBarry Smith } 399416022c9SBarry Smith for (i=low; i<high; i++) { 40017ab2063SBarry Smith if (rp[i] > col) break; 40117ab2063SBarry Smith if (rp[i] == col) { 402416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 40317ab2063SBarry Smith else ap[i] = value; 404e44c0bd4SBarry Smith low = i + 1; 40517ab2063SBarry Smith goto noinsert; 40617ab2063SBarry Smith } 40717ab2063SBarry Smith } 408abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 409c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 410e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 411fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 412c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 413416022c9SBarry Smith /* shift up all the later entries in this row */ 414416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 41517ab2063SBarry Smith rp[ii+1] = rp[ii]; 41617ab2063SBarry Smith ap[ii+1] = ap[ii]; 41717ab2063SBarry Smith } 41817ab2063SBarry Smith rp[i] = col; 41917ab2063SBarry Smith ap[i] = value; 420416022c9SBarry Smith low = i + 1; 421e44c0bd4SBarry Smith noinsert:; 42217ab2063SBarry Smith } 42317ab2063SBarry Smith ailen[row] = nrow; 42417ab2063SBarry Smith } 42588e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 4263a40ed3dSBarry Smith PetscFunctionReturn(0); 42717ab2063SBarry Smith } 42817ab2063SBarry Smith 42981824310SBarry Smith 4304a2ae208SSatish Balay #undef __FUNCT__ 4314a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 432a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4337eb43aa7SLois Curfman McInnes { 4347eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 43597f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 43697f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 43754f21887SBarry Smith MatScalar *ap,*aa = a->a; 4387eb43aa7SLois Curfman McInnes 4393a40ed3dSBarry Smith PetscFunctionBegin; 4407eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 4417eb43aa7SLois Curfman McInnes row = im[k]; 442e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 443e32f2f54SBarry 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); 444bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 4457eb43aa7SLois Curfman McInnes nrow = ailen[row]; 4467eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 447e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 448e32f2f54SBarry 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); 449bfeeae90SHong Zhang col = in[l]; 4507eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 4517eb43aa7SLois Curfman McInnes while (high-low > 5) { 4527eb43aa7SLois Curfman McInnes t = (low+high)/2; 4537eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 4547eb43aa7SLois Curfman McInnes else low = t; 4557eb43aa7SLois Curfman McInnes } 4567eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 4577eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 4587eb43aa7SLois Curfman McInnes if (rp[i] == col) { 459b49de8d1SLois Curfman McInnes *v++ = ap[i]; 4607eb43aa7SLois Curfman McInnes goto finished; 4617eb43aa7SLois Curfman McInnes } 4627eb43aa7SLois Curfman McInnes } 46397e567efSBarry Smith *v++ = 0.0; 4647eb43aa7SLois Curfman McInnes finished:; 4657eb43aa7SLois Curfman McInnes } 4667eb43aa7SLois Curfman McInnes } 4673a40ed3dSBarry Smith PetscFunctionReturn(0); 4687eb43aa7SLois Curfman McInnes } 4697eb43aa7SLois Curfman McInnes 47017ab2063SBarry Smith 4714a2ae208SSatish Balay #undef __FUNCT__ 4724a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 473dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 47417ab2063SBarry Smith { 475416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4766849ba73SBarry Smith PetscErrorCode ierr; 4776f69ff64SBarry Smith PetscInt i,*col_lens; 4786f69ff64SBarry Smith int fd; 479b37d52dbSMark F. Adams FILE *file; 48017ab2063SBarry Smith 4813a40ed3dSBarry Smith PetscFunctionBegin; 482b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 483785e854fSJed Brown ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr); 4842205254eSKarl Rupp 4850700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 486d0f46423SBarry Smith col_lens[1] = A->rmap->n; 487d0f46423SBarry Smith col_lens[2] = A->cmap->n; 488416022c9SBarry Smith col_lens[3] = a->nz; 489416022c9SBarry Smith 490416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 491d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 492416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 49317ab2063SBarry Smith } 494d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 495606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 496416022c9SBarry Smith 497416022c9SBarry Smith /* store column indices (zero start index) */ 4986f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 499416022c9SBarry Smith 500416022c9SBarry Smith /* store nonzero values */ 5016f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 502b37d52dbSMark F. Adams 503b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 504b37d52dbSMark F. Adams if (file) { 505b37d52dbSMark F. Adams fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs); 506b37d52dbSMark F. Adams } 5073a40ed3dSBarry Smith PetscFunctionReturn(0); 50817ab2063SBarry Smith } 509416022c9SBarry Smith 51009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 511cd155464SBarry Smith 5124a2ae208SSatish Balay #undef __FUNCT__ 5134a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 514dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 515416022c9SBarry Smith { 516416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 517dfbe8321SBarry Smith PetscErrorCode ierr; 51860e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 519e060cb09SBarry Smith const char *name; 520f3ef73ceSBarry Smith PetscViewerFormat format; 52117ab2063SBarry Smith 5223a40ed3dSBarry Smith PetscFunctionBegin; 523b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 52471c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 52597f1f81fSBarry Smith PetscInt nofinalvalue = 0; 52660e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 527d00d2cf4SBarry Smith nofinalvalue = 1; 528d00d2cf4SBarry Smith } 529d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 530d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 53177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 53277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 533b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 53417ab2063SBarry Smith 53517ab2063SBarry Smith for (i=0; i<m; i++) { 53660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 537aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 53860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e + %18.16ei \n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 53917ab2063SBarry Smith #else 54060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 54117ab2063SBarry Smith #endif 54217ab2063SBarry Smith } 54317ab2063SBarry Smith } 544d00d2cf4SBarry Smith if (nofinalvalue) { 545d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 546d00d2cf4SBarry Smith } 547317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 548fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 549d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 55068369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 551cd155464SBarry Smith PetscFunctionReturn(0); 552fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 553d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 554dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 55544cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 55677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 55760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 558aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 55936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 56060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 56136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 56260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 56336db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 56460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 5656831982aSBarry Smith } 56644cd7ae7SLois Curfman McInnes #else 56760e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 56844cd7ae7SLois Curfman McInnes #endif 56944cd7ae7SLois Curfman McInnes } 570b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 57144cd7ae7SLois Curfman McInnes } 572d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 573fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 57497f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 575d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 576dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 577785e854fSJed Brown ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr); 578496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 579496be53dSLois Curfman McInnes sptr[i] = nzd+1; 58060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 581496be53dSLois Curfman McInnes if (a->j[j] >= i) { 582aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 58336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 584496be53dSLois Curfman McInnes #else 585496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 586496be53dSLois Curfman McInnes #endif 587496be53dSLois Curfman McInnes } 588496be53dSLois Curfman McInnes } 589496be53dSLois Curfman McInnes } 5902e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 59177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 5922e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 5932205254eSKarl Rupp if (i+4<m) { 5942205254eSKarl 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); 5952205254eSKarl Rupp } else if (i+3<m) { 5962205254eSKarl 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); 5972205254eSKarl Rupp } else if (i+2<m) { 5982205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 5992205254eSKarl Rupp } else if (i+1<m) { 6002205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6012205254eSKarl Rupp } else if (i<m) { 6022205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6032205254eSKarl Rupp } else { 6042205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6052205254eSKarl Rupp } 606496be53dSLois Curfman McInnes } 607b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 608606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 609496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 61060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 61177431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 612496be53dSLois Curfman McInnes } 613b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 614496be53dSLois Curfman McInnes } 615b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 616496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 61760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 618496be53dSLois Curfman McInnes if (a->j[j] >= i) { 619aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 62036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 62160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6226831982aSBarry Smith } 623496be53dSLois Curfman McInnes #else 62460e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 625496be53dSLois Curfman McInnes #endif 626496be53dSLois Curfman McInnes } 627496be53dSLois Curfman McInnes } 628b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 629496be53dSLois Curfman McInnes } 630d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 631fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 63297f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 63387828ca2SBarry Smith PetscScalar value; 63468f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 63568f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 63668f1ed48SBarry Smith 63768f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 63868f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 63968f1ed48SBarry Smith realonly = PETSC_FALSE; 64068f1ed48SBarry Smith break; 64168f1ed48SBarry Smith } 64268f1ed48SBarry Smith } 64368f1ed48SBarry Smith #endif 64402594712SBarry Smith 645d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 646dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 64702594712SBarry Smith for (i=0; i<m; i++) { 64802594712SBarry Smith jcnt = 0; 649d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 650e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 65102594712SBarry Smith value = a->a[cnt++]; 652e24b481bSBarry Smith jcnt++; 65302594712SBarry Smith } else { 65402594712SBarry Smith value = 0.0; 65502594712SBarry Smith } 656aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 65768f1ed48SBarry Smith if (realonly) { 65860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 65968f1ed48SBarry Smith } else { 66060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 66168f1ed48SBarry Smith } 66202594712SBarry Smith #else 66360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 66402594712SBarry Smith #endif 66502594712SBarry Smith } 666b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 66702594712SBarry Smith } 668d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6693c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 670150b93efSMatthew G. Knepley PetscInt fshift=1; 671d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 6723c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 6733c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 6743c215bfdSMatthew Knepley #else 6753c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 6763c215bfdSMatthew Knepley #endif 677d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 6783c215bfdSMatthew Knepley for (i=0; i<m; i++) { 67960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 6803c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 6813c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 68260e0710aSBarry Smith 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); 6833c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 68460e0710aSBarry Smith 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); 6853c215bfdSMatthew Knepley } else { 68660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6873c215bfdSMatthew Knepley } 6883c215bfdSMatthew Knepley #else 689150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 6903c215bfdSMatthew Knepley #endif 6913c215bfdSMatthew Knepley } 6923c215bfdSMatthew Knepley } 693d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6943a40ed3dSBarry Smith } else { 695d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 696dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 697d5f3da31SBarry Smith if (A->factortype) { 69816cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 69916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 70016cd7e1dSShri Abhyankar /* L part */ 70160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 70216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 70316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 70460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 70516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 706*6712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 70716cd7e1dSShri Abhyankar } else { 70860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 70916cd7e1dSShri Abhyankar } 71016cd7e1dSShri Abhyankar #else 71160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 71216cd7e1dSShri Abhyankar #endif 71316cd7e1dSShri Abhyankar } 71416cd7e1dSShri Abhyankar /* diagonal */ 71516cd7e1dSShri Abhyankar j = a->diag[i]; 71616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 71716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 71860e0710aSBarry 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); 71916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 720*6712e2f1SBarry 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); 72116cd7e1dSShri Abhyankar } else { 72260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 72316cd7e1dSShri Abhyankar } 72416cd7e1dSShri Abhyankar #else 72560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 72616cd7e1dSShri Abhyankar #endif 72716cd7e1dSShri Abhyankar 72816cd7e1dSShri Abhyankar /* U part */ 72960e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 73016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 73116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 73260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 73316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 734*6712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]t,(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 73516cd7e1dSShri Abhyankar } else { 73660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 73716cd7e1dSShri Abhyankar } 73816cd7e1dSShri Abhyankar #else 73960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 74016cd7e1dSShri Abhyankar #endif 74116cd7e1dSShri Abhyankar } 74216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 74316cd7e1dSShri Abhyankar } 74416cd7e1dSShri Abhyankar } else { 74517ab2063SBarry Smith for (i=0; i<m; i++) { 74677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 74760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 748aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 74936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 75060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 75136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 75260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7533a40ed3dSBarry Smith } else { 75460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 75517ab2063SBarry Smith } 75617ab2063SBarry Smith #else 75760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 75817ab2063SBarry Smith #endif 75917ab2063SBarry Smith } 760b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 76117ab2063SBarry Smith } 76216cd7e1dSShri Abhyankar } 763d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 76417ab2063SBarry Smith } 765b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7663a40ed3dSBarry Smith PetscFunctionReturn(0); 767416022c9SBarry Smith } 768416022c9SBarry Smith 7699804daf3SBarry Smith #include <petscdraw.h> 7704a2ae208SSatish Balay #undef __FUNCT__ 7714a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 772dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 773416022c9SBarry Smith { 774480ef9eaSBarry Smith Mat A = (Mat) Aa; 775416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 776dfbe8321SBarry Smith PetscErrorCode ierr; 777d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 77836db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 779b0a32e0cSBarry Smith PetscViewer viewer; 780f3ef73ceSBarry Smith PetscViewerFormat format; 781cddf8d76SBarry Smith 7823a40ed3dSBarry Smith PetscFunctionBegin; 783480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 784b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 78519bcc07fSBarry Smith 786b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 787416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 7880513a670SBarry Smith 789fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 7900513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 791b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 792416022c9SBarry Smith for (i=0; i<m; i++) { 793cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 794bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 795bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 79636db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 797b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 798cddf8d76SBarry Smith } 799cddf8d76SBarry Smith } 800b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 801cddf8d76SBarry Smith for (i=0; i<m; i++) { 802cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 803bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 804bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 805cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 806b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 807cddf8d76SBarry Smith } 808cddf8d76SBarry Smith } 809b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 810cddf8d76SBarry Smith for (i=0; i<m; i++) { 811cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 812bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 813bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 81436db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 815b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 816416022c9SBarry Smith } 817416022c9SBarry Smith } 8180513a670SBarry Smith } else { 8190513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8200513a670SBarry Smith /* first determine max of all nonzero values */ 82197f1f81fSBarry Smith PetscInt nz = a->nz,count; 822b0a32e0cSBarry Smith PetscDraw popup; 82336db0b34SBarry Smith PetscReal scale; 8240513a670SBarry Smith 8250513a670SBarry Smith for (i=0; i<nz; i++) { 8260513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8270513a670SBarry Smith } 828b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 829b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 8302205254eSKarl Rupp if (popup) { 8312205254eSKarl Rupp ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr); 8322205254eSKarl Rupp } 8330513a670SBarry Smith count = 0; 8340513a670SBarry Smith for (i=0; i<m; i++) { 8350513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 836bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 837bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 83897f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 839b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8400513a670SBarry Smith count++; 8410513a670SBarry Smith } 8420513a670SBarry Smith } 8430513a670SBarry Smith } 844480ef9eaSBarry Smith PetscFunctionReturn(0); 845480ef9eaSBarry Smith } 846cddf8d76SBarry Smith 8479804daf3SBarry Smith #include <petscdraw.h> 8484a2ae208SSatish Balay #undef __FUNCT__ 8494a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 850dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 851480ef9eaSBarry Smith { 852dfbe8321SBarry Smith PetscErrorCode ierr; 853b0a32e0cSBarry Smith PetscDraw draw; 85436db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 855ace3abfcSBarry Smith PetscBool isnull; 856480ef9eaSBarry Smith 857480ef9eaSBarry Smith PetscFunctionBegin; 858b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 859b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 860480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 861480ef9eaSBarry Smith 862480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 863d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 864480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 865b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 866b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 8670298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 8683a40ed3dSBarry Smith PetscFunctionReturn(0); 869416022c9SBarry Smith } 870416022c9SBarry Smith 8714a2ae208SSatish Balay #undef __FUNCT__ 8724a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 873dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 874416022c9SBarry Smith { 875dfbe8321SBarry Smith PetscErrorCode ierr; 876ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 877416022c9SBarry Smith 8783a40ed3dSBarry Smith PetscFunctionBegin; 879251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 880251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 881251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 882c45a1595SBarry Smith if (iascii) { 8833a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 8840f5bd95cSBarry Smith } else if (isbinary) { 8853a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 8860f5bd95cSBarry Smith } else if (isdraw) { 8873a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 88811aeaf0aSBarry Smith } 8894108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 8903a40ed3dSBarry Smith PetscFunctionReturn(0); 89117ab2063SBarry Smith } 89219bcc07fSBarry Smith 8934a2ae208SSatish Balay #undef __FUNCT__ 8944a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 895dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 89617ab2063SBarry Smith { 897416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8986849ba73SBarry Smith PetscErrorCode ierr; 89997f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 900d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 90154f21887SBarry Smith MatScalar *aa = a->a,*ap; 9023447b6efSHong Zhang PetscReal ratio = 0.6; 90317ab2063SBarry Smith 9043a40ed3dSBarry Smith PetscFunctionBegin; 9053a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 90617ab2063SBarry Smith 90743ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 90817ab2063SBarry Smith for (i=1; i<m; i++) { 909416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 91017ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 91194a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 91217ab2063SBarry Smith if (fshift) { 913bfeeae90SHong Zhang ip = aj + ai[i]; 914bfeeae90SHong Zhang ap = aa + ai[i]; 91517ab2063SBarry Smith N = ailen[i]; 91617ab2063SBarry Smith for (j=0; j<N; j++) { 91717ab2063SBarry Smith ip[j-fshift] = ip[j]; 91817ab2063SBarry Smith ap[j-fshift] = ap[j]; 91917ab2063SBarry Smith } 92017ab2063SBarry Smith } 92117ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 92217ab2063SBarry Smith } 92317ab2063SBarry Smith if (m) { 92417ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 92517ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 92617ab2063SBarry Smith } 9277b083b7cSBarry Smith 92817ab2063SBarry Smith /* reset ilen and imax for each row */ 9297b083b7cSBarry Smith a->nonzerorowcnt = 0; 93017ab2063SBarry Smith for (i=0; i<m; i++) { 93117ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 9327b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 93317ab2063SBarry Smith } 934bfeeae90SHong Zhang a->nz = ai[m]; 93565e19b50SBarry 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); 93617ab2063SBarry Smith 93709f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 938d0f46423SBarry 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); 939ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 940ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9412205254eSKarl Rupp 9428e58a170SBarry Smith A->info.mallocs += a->reallocs; 943dd5f02e7SSatish Balay a->reallocs = 0; 944*6712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 94536db0b34SBarry Smith a->rmax = rmax; 9464e220ebcSLois Curfman McInnes 94711e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 9482205254eSKarl Rupp 94988e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 95071c2f376SKris Buschelman 9514108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 95271f1c65dSBarry Smith 953acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9543a40ed3dSBarry Smith PetscFunctionReturn(0); 95517ab2063SBarry Smith } 95617ab2063SBarry Smith 9574a2ae208SSatish Balay #undef __FUNCT__ 95899cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 95999cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 96099cafbc1SBarry Smith { 96199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 96299cafbc1SBarry Smith PetscInt i,nz = a->nz; 96354f21887SBarry Smith MatScalar *aa = a->a; 964acf2f550SJed Brown PetscErrorCode ierr; 96599cafbc1SBarry Smith 96699cafbc1SBarry Smith PetscFunctionBegin; 96799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 968acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 96999cafbc1SBarry Smith PetscFunctionReturn(0); 97099cafbc1SBarry Smith } 97199cafbc1SBarry Smith 97299cafbc1SBarry Smith #undef __FUNCT__ 97399cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 97499cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 97599cafbc1SBarry Smith { 97699cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 97799cafbc1SBarry Smith PetscInt i,nz = a->nz; 97854f21887SBarry Smith MatScalar *aa = a->a; 979acf2f550SJed Brown PetscErrorCode ierr; 98099cafbc1SBarry Smith 98199cafbc1SBarry Smith PetscFunctionBegin; 98299cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 983acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 98499cafbc1SBarry Smith PetscFunctionReturn(0); 98599cafbc1SBarry Smith } 98699cafbc1SBarry Smith 98778b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 98878b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A) 98978b84d54SShri Abhyankar { 99078b84d54SShri Abhyankar PetscErrorCode ierr; 99178b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 99278b84d54SShri Abhyankar PetscInt n,start,end; 99378b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 99478b84d54SShri Abhyankar 99578b84d54SShri Abhyankar start = trstarts[thread_id]; 99678b84d54SShri Abhyankar end = trstarts[thread_id+1]; 99719baf141SJed Brown n = a->i[end] - a->i[start]; 99819baf141SJed Brown ierr = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr); 99978b84d54SShri Abhyankar return 0; 100078b84d54SShri Abhyankar } 100178b84d54SShri Abhyankar 100278b84d54SShri Abhyankar #undef __FUNCT__ 100378b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ" 100478b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 100578b84d54SShri Abhyankar { 100678b84d54SShri Abhyankar PetscErrorCode ierr; 100778b84d54SShri Abhyankar 100878b84d54SShri Abhyankar PetscFunctionBegin; 1009ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr); 1010acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 101178b84d54SShri Abhyankar PetscFunctionReturn(0); 101278b84d54SShri Abhyankar } 101378b84d54SShri Abhyankar #else 101499cafbc1SBarry Smith #undef __FUNCT__ 10154a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 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 } 102678b84d54SShri Abhyankar #endif 1027416022c9SBarry Smith 10284a2ae208SSatish Balay #undef __FUNCT__ 10294a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 1030dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 103117ab2063SBarry Smith { 1032416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1033dfbe8321SBarry Smith PetscErrorCode ierr; 1034d5d45c9bSBarry Smith 10353a40ed3dSBarry Smith PetscFunctionBegin; 1036aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1037d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 103817ab2063SBarry Smith #endif 1039e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10406bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10416bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 104205b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1043d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 104405b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 104571f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 104605b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10476bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 104805b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10496bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 105005b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 10516bf464f9SBarry Smith ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr); 1052cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10530b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1054a30b2313SHong Zhang 10554108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1056bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1057901853e0SKris Buschelman 1058dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1059bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1060bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1061bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1062bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1063bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1064bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1065bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1066bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1067bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1068bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10693a40ed3dSBarry Smith PetscFunctionReturn(0); 107017ab2063SBarry Smith } 107117ab2063SBarry Smith 10724a2ae208SSatish Balay #undef __FUNCT__ 10734a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 1074ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 107517ab2063SBarry Smith { 1076416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10774846f1f5SKris Buschelman PetscErrorCode ierr; 10783a40ed3dSBarry Smith 10793a40ed3dSBarry Smith PetscFunctionBegin; 1080a65d3064SKris Buschelman switch (op) { 1081a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 10824e0d8c25SBarry Smith a->roworiented = flg; 1083a65d3064SKris Buschelman break; 1084a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1085a9817697SBarry Smith a->keepnonzeropattern = flg; 1086a65d3064SKris Buschelman break; 1087512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1088512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1089a65d3064SKris Buschelman break; 1090a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 10914e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1092a65d3064SKris Buschelman break; 1093a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 10944e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1095a65d3064SKris Buschelman break; 109628b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 109728b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 109828b2fa4aSMatthew Knepley break; 1099a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 11004e0d8c25SBarry Smith a->ignorezeroentries = flg; 11010df259c2SBarry Smith break; 11023d472b54SHong Zhang case MAT_SPD: 1103b1646e73SJed Brown case MAT_SYMMETRIC: 1104b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1105b1646e73SJed Brown case MAT_HERMITIAN: 1106b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 11075021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11085021d80fSJed Brown break; 11094e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1110a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1111a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1112290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1113a65d3064SKris Buschelman break; 1114b87ac2d8SJed Brown case MAT_USE_INODES: 1115b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1116b87ac2d8SJed Brown break; 1117a65d3064SKris Buschelman default: 1118e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1119a65d3064SKris Buschelman } 11204108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11213a40ed3dSBarry Smith PetscFunctionReturn(0); 112217ab2063SBarry Smith } 112317ab2063SBarry Smith 11244a2ae208SSatish Balay #undef __FUNCT__ 11254a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 1126dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 112717ab2063SBarry Smith { 1128416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11296849ba73SBarry Smith PetscErrorCode ierr; 1130d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 113135e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 113217ab2063SBarry Smith 11333a40ed3dSBarry Smith PetscFunctionBegin; 1134d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1135e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 113635e7444dSHong Zhang 1137d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1138d3e70bfaSHong Zhang PetscInt *diag=a->diag; 113935e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11402c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 114135e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 114235e7444dSHong Zhang PetscFunctionReturn(0); 114335e7444dSHong Zhang } 114435e7444dSHong Zhang 11452dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11461ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 114735e7444dSHong Zhang for (i=0; i<n; i++) { 114835e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11492f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 115035e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 115135e7444dSHong Zhang if (aj[j] == i) { 115235e7444dSHong Zhang x[i] = aa[j]; 115317ab2063SBarry Smith break; 115417ab2063SBarry Smith } 115517ab2063SBarry Smith } 115617ab2063SBarry Smith } 11571ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11583a40ed3dSBarry Smith PetscFunctionReturn(0); 115917ab2063SBarry Smith } 116017ab2063SBarry Smith 1161c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 11624a2ae208SSatish Balay #undef __FUNCT__ 11634a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 1164dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 116517ab2063SBarry Smith { 1166416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11675c897100SBarry Smith PetscScalar *x,*y; 1168dfbe8321SBarry Smith PetscErrorCode ierr; 1169d0f46423SBarry Smith PetscInt m = A->rmap->n; 11705c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1171a77337e4SBarry Smith MatScalar *v; 1172a77337e4SBarry Smith PetscScalar alpha; 11730298fd71SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=NULL; 11743447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1175ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11765c897100SBarry Smith #endif 117717ab2063SBarry Smith 11783a40ed3dSBarry Smith PetscFunctionBegin; 11792e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 11801ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 11811ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11825c897100SBarry Smith 11835c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1184bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 11855c897100SBarry Smith #else 11863447b6efSHong Zhang if (usecprow) { 11873447b6efSHong Zhang m = cprow.nrows; 11883447b6efSHong Zhang ii = cprow.i; 11897b2bb3b9SHong Zhang ridx = cprow.rindex; 11903447b6efSHong Zhang } else { 11913447b6efSHong Zhang ii = a->i; 11923447b6efSHong Zhang } 119317ab2063SBarry Smith for (i=0; i<m; i++) { 11943447b6efSHong Zhang idx = a->j + ii[i]; 11953447b6efSHong Zhang v = a->a + ii[i]; 11963447b6efSHong Zhang n = ii[i+1] - ii[i]; 11973447b6efSHong Zhang if (usecprow) { 11987b2bb3b9SHong Zhang alpha = x[ridx[i]]; 11993447b6efSHong Zhang } else { 120017ab2063SBarry Smith alpha = x[i]; 12013447b6efSHong Zhang } 120204fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 120317ab2063SBarry Smith } 12045c897100SBarry Smith #endif 1205dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 12061ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12071ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12083a40ed3dSBarry Smith PetscFunctionReturn(0); 120917ab2063SBarry Smith } 121017ab2063SBarry Smith 12114a2ae208SSatish Balay #undef __FUNCT__ 12125c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 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 #if defined(PETSC_THREADCOMM_ACTIVE) 122578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy) 122678b84d54SShri Abhyankar { 122778b84d54SShri Abhyankar PetscErrorCode ierr; 122878b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122978b84d54SShri Abhyankar PetscScalar *y; 123078b84d54SShri Abhyankar const PetscScalar *x; 123178b84d54SShri Abhyankar const MatScalar *aa; 123278b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 123378b84d54SShri Abhyankar PetscInt n,start,end,i; 123478b84d54SShri Abhyankar const PetscInt *aj,*ai; 123578b84d54SShri Abhyankar PetscScalar sum; 123678b84d54SShri Abhyankar 123778b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 123878b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 123978b84d54SShri Abhyankar start = trstarts[thread_id]; 124078b84d54SShri Abhyankar end = trstarts[thread_id+1]; 124178b84d54SShri Abhyankar aj = a->j; 124278b84d54SShri Abhyankar aa = a->a; 124378b84d54SShri Abhyankar ai = a->i; 124478b84d54SShri Abhyankar for (i=start; i<end; i++) { 124578b84d54SShri Abhyankar n = ai[i+1] - ai[i]; 124678b84d54SShri Abhyankar aj = a->j + ai[i]; 124778b84d54SShri Abhyankar aa = a->a + ai[i]; 124878b84d54SShri Abhyankar sum = 0.0; 124978b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 125078b84d54SShri Abhyankar y[i] = sum; 125178b84d54SShri Abhyankar } 125278b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 125378b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 125478b84d54SShri Abhyankar return 0; 125578b84d54SShri Abhyankar } 125678b84d54SShri Abhyankar 125778b84d54SShri Abhyankar #undef __FUNCT__ 125878b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ" 125978b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 126078b84d54SShri Abhyankar { 126178b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 126278b84d54SShri Abhyankar PetscScalar *y; 126378b84d54SShri Abhyankar const PetscScalar *x; 126478b84d54SShri Abhyankar const MatScalar *aa; 126578b84d54SShri Abhyankar PetscErrorCode ierr; 126678b84d54SShri Abhyankar PetscInt m=A->rmap->n; 12670298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 12687b083b7cSBarry Smith PetscInt n,i; 126978b84d54SShri Abhyankar PetscScalar sum; 127078b84d54SShri Abhyankar PetscBool usecprow=a->compressedrow.use; 127178b84d54SShri Abhyankar 127278b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 127378b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa) 127478b84d54SShri Abhyankar #endif 127578b84d54SShri Abhyankar 127678b84d54SShri Abhyankar PetscFunctionBegin; 127778b84d54SShri Abhyankar aj = a->j; 127878b84d54SShri Abhyankar aa = a->a; 127978b84d54SShri Abhyankar ii = a->i; 128078b84d54SShri Abhyankar if (usecprow) { /* use compressed row format */ 128178b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 128278b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 128378b84d54SShri Abhyankar m = a->compressedrow.nrows; 128478b84d54SShri Abhyankar ii = a->compressedrow.i; 128578b84d54SShri Abhyankar ridx = a->compressedrow.rindex; 128678b84d54SShri Abhyankar for (i=0; i<m; i++) { 128778b84d54SShri Abhyankar n = ii[i+1] - ii[i]; 128878b84d54SShri Abhyankar aj = a->j + ii[i]; 128978b84d54SShri Abhyankar aa = a->a + ii[i]; 129078b84d54SShri Abhyankar sum = 0.0; 129178b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 129278b84d54SShri Abhyankar /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 129378b84d54SShri Abhyankar y[*ridx++] = sum; 129478b84d54SShri Abhyankar } 129578b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 129678b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 129778b84d54SShri Abhyankar } else { /* do not use compressed row format */ 129878b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 129978b84d54SShri Abhyankar fortranmultaij_(&m,x,ii,aj,aa,y); 130078b84d54SShri Abhyankar #else 1301ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 130278b84d54SShri Abhyankar #endif 130378b84d54SShri Abhyankar } 13047b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 130578b84d54SShri Abhyankar PetscFunctionReturn(0); 130678b84d54SShri Abhyankar } 130778b84d54SShri Abhyankar #else 13085c897100SBarry Smith #undef __FUNCT__ 13094a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 1310dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 131117ab2063SBarry Smith { 1312416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1313d9fead3dSBarry Smith PetscScalar *y; 131454f21887SBarry Smith const PetscScalar *x; 131554f21887SBarry Smith const MatScalar *aa; 1316dfbe8321SBarry Smith PetscErrorCode ierr; 1317003131ecSBarry Smith PetscInt m=A->rmap->n; 13180298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 13197b083b7cSBarry Smith PetscInt n,i; 1320362ced78SSatish Balay PetscScalar sum; 1321ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 132217ab2063SBarry Smith 1323b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 132497952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1325fee21e36SBarry Smith #endif 1326fee21e36SBarry Smith 13273a40ed3dSBarry Smith PetscFunctionBegin; 13283649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13291ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 133097952fefSHong Zhang aj = a->j; 133197952fefSHong Zhang aa = a->a; 1332416022c9SBarry Smith ii = a->i; 13334eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 133497952fefSHong Zhang m = a->compressedrow.nrows; 133597952fefSHong Zhang ii = a->compressedrow.i; 133697952fefSHong Zhang ridx = a->compressedrow.rindex; 133797952fefSHong Zhang for (i=0; i<m; i++) { 133897952fefSHong Zhang n = ii[i+1] - ii[i]; 133997952fefSHong Zhang aj = a->j + ii[i]; 134097952fefSHong Zhang aa = a->a + ii[i]; 134197952fefSHong Zhang sum = 0.0; 1342003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1343003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 134497952fefSHong Zhang y[*ridx++] = sum; 134597952fefSHong Zhang } 134697952fefSHong Zhang } else { /* do not use compressed row format */ 1347b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1348b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1349b05257ddSBarry Smith #else 135078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 1351ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 135278b84d54SShri Abhyankar #else 135317ab2063SBarry Smith for (i=0; i<m; i++) { 1354003131ecSBarry Smith n = ii[i+1] - ii[i]; 1355003131ecSBarry Smith aj = a->j + ii[i]; 1356003131ecSBarry Smith aa = a->a + ii[i]; 135717ab2063SBarry Smith sum = 0.0; 1358003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 135917ab2063SBarry Smith y[i] = sum; 136017ab2063SBarry Smith } 13618d195f9aSBarry Smith #endif 136278b84d54SShri Abhyankar #endif 1363b05257ddSBarry Smith } 13647b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 13653649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13661ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13673a40ed3dSBarry Smith PetscFunctionReturn(0); 136817ab2063SBarry Smith } 136978b84d54SShri Abhyankar #endif 137017ab2063SBarry Smith 1371b434eb95SMatthew G. Knepley #undef __FUNCT__ 1372b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ" 1373b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1374b434eb95SMatthew G. Knepley { 1375b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1376b434eb95SMatthew G. Knepley PetscScalar *y; 1377b434eb95SMatthew G. Knepley const PetscScalar *x; 1378b434eb95SMatthew G. Knepley const MatScalar *aa; 1379b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1380b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1381b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1382b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1383b434eb95SMatthew G. Knepley PetscScalar sum; 1384b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1385b434eb95SMatthew G. Knepley 1386b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1387b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1388b434eb95SMatthew G. Knepley #endif 1389b434eb95SMatthew G. Knepley 1390b434eb95SMatthew G. Knepley PetscFunctionBegin; 1391b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1392b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1393b434eb95SMatthew G. Knepley aj = a->j; 1394b434eb95SMatthew G. Knepley aa = a->a; 1395b434eb95SMatthew G. Knepley ii = a->i; 1396b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1397b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1398b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1399b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1400b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1401b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1402b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1403b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1404b434eb95SMatthew G. Knepley sum = 0.0; 1405b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1406b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1407b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1408b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1409b434eb95SMatthew G. Knepley } 1410b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1411b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1412b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1413b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1414b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1415b434eb95SMatthew G. Knepley sum = 0.0; 1416b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1417b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1418b434eb95SMatthew G. Knepley y[i] = sum; 1419b434eb95SMatthew G. Knepley } 1420b434eb95SMatthew G. Knepley } 1421b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1422b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1423b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1424b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1425b434eb95SMatthew G. Knepley } 1426b434eb95SMatthew G. Knepley 1427b434eb95SMatthew G. Knepley #undef __FUNCT__ 1428b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ" 1429b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1430b434eb95SMatthew G. Knepley { 1431b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1432b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1433b434eb95SMatthew G. Knepley const PetscScalar *x; 1434b434eb95SMatthew G. Knepley const MatScalar *aa; 1435b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1436b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1437b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1438b434eb95SMatthew G. Knepley PetscScalar sum; 1439b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1440b434eb95SMatthew G. Knepley 1441b434eb95SMatthew G. Knepley PetscFunctionBegin; 1442b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1443b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1444b434eb95SMatthew G. Knepley if (zz != yy) { 1445b434eb95SMatthew G. Knepley ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 1446b434eb95SMatthew G. Knepley } else { 1447b434eb95SMatthew G. Knepley z = y; 1448b434eb95SMatthew G. Knepley } 1449b434eb95SMatthew G. Knepley 1450b434eb95SMatthew G. Knepley aj = a->j; 1451b434eb95SMatthew G. Knepley aa = a->a; 1452b434eb95SMatthew G. Knepley ii = a->i; 1453b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1454b434eb95SMatthew G. Knepley if (zz != yy) { 1455b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1456b434eb95SMatthew G. Knepley } 1457b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1458b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1459b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1460b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1461b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1462b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1463b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1464b434eb95SMatthew G. Knepley sum = y[*ridx]; 1465b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1466b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1467b434eb95SMatthew G. Knepley } 1468b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1469b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1470b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1471b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1472b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1473b434eb95SMatthew G. Knepley sum = y[i]; 1474b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1475b434eb95SMatthew G. Knepley z[i] = sum; 1476b434eb95SMatthew G. Knepley } 1477b434eb95SMatthew G. Knepley } 1478b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1479b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1480b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1481b434eb95SMatthew G. Knepley if (zz != yy) { 1482b434eb95SMatthew G. Knepley ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 1483b434eb95SMatthew G. Knepley } 1484b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1485b434eb95SMatthew G. Knepley } 1486b434eb95SMatthew G. Knepley 1487c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 14884a2ae208SSatish Balay #undef __FUNCT__ 14894a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1490dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 149117ab2063SBarry Smith { 1492416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1493f15663dcSBarry Smith PetscScalar *y,*z; 1494f15663dcSBarry Smith const PetscScalar *x; 149554f21887SBarry Smith const MatScalar *aa; 1496dfbe8321SBarry Smith PetscErrorCode ierr; 1497d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 14980298fd71SBarry Smith PetscInt n,i,*ridx=NULL; 1499362ced78SSatish Balay PetscScalar sum; 1500ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 15019ea0dfa2SSatish Balay 15023a40ed3dSBarry Smith PetscFunctionBegin; 1503f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15041ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 15052e8a6d31SBarry Smith if (zz != yy) { 15061ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 15072e8a6d31SBarry Smith } else { 15082e8a6d31SBarry Smith z = y; 15092e8a6d31SBarry Smith } 1510bfeeae90SHong Zhang 151197952fefSHong Zhang aj = a->j; 151297952fefSHong Zhang aa = a->a; 1513cddf8d76SBarry Smith ii = a->i; 15144eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 15154eb6d288SHong Zhang if (zz != yy) { 15164eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 15174eb6d288SHong Zhang } 151897952fefSHong Zhang m = a->compressedrow.nrows; 151997952fefSHong Zhang ii = a->compressedrow.i; 152097952fefSHong Zhang ridx = a->compressedrow.rindex; 152197952fefSHong Zhang for (i=0; i<m; i++) { 152297952fefSHong Zhang n = ii[i+1] - ii[i]; 152397952fefSHong Zhang aj = a->j + ii[i]; 152497952fefSHong Zhang aa = a->a + ii[i]; 152597952fefSHong Zhang sum = y[*ridx]; 1526f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 152797952fefSHong Zhang z[*ridx++] = sum; 152897952fefSHong Zhang } 152997952fefSHong Zhang } else { /* do not use compressed row format */ 1530f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1531f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1532f15663dcSBarry Smith #else 153317ab2063SBarry Smith for (i=0; i<m; i++) { 1534f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1535f15663dcSBarry Smith aj = a->j + ii[i]; 1536f15663dcSBarry Smith aa = a->a + ii[i]; 153717ab2063SBarry Smith sum = y[i]; 1538f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 153917ab2063SBarry Smith z[i] = sum; 154017ab2063SBarry Smith } 154102ab625aSSatish Balay #endif 1542f15663dcSBarry Smith } 1543dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1544f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15451ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15462e8a6d31SBarry Smith if (zz != yy) { 15471ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 15482e8a6d31SBarry Smith } 15498154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 15506b375ea7SVictor Minden /* 1551918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1552918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1553918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 15546b375ea7SVictor Minden */ 1555918e98c3SVictor Minden #endif 15563a40ed3dSBarry Smith PetscFunctionReturn(0); 155717ab2063SBarry Smith } 155817ab2063SBarry Smith 155917ab2063SBarry Smith /* 156017ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 156117ab2063SBarry Smith */ 15624a2ae208SSatish Balay #undef __FUNCT__ 15634a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1564dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 156517ab2063SBarry Smith { 1566416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15676849ba73SBarry Smith PetscErrorCode ierr; 1568d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 156917ab2063SBarry Smith 15703a40ed3dSBarry Smith PetscFunctionBegin; 157109f38230SBarry Smith if (!a->diag) { 1572785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 15733bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 157409f38230SBarry Smith } 1575d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 157609f38230SBarry Smith a->diag[i] = a->i[i+1]; 1577bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1578bfeeae90SHong Zhang if (a->j[j] == i) { 157909f38230SBarry Smith a->diag[i] = j; 158017ab2063SBarry Smith break; 158117ab2063SBarry Smith } 158217ab2063SBarry Smith } 158317ab2063SBarry Smith } 15843a40ed3dSBarry Smith PetscFunctionReturn(0); 158517ab2063SBarry Smith } 158617ab2063SBarry Smith 1587be5855fcSBarry Smith /* 1588be5855fcSBarry Smith Checks for missing diagonals 1589be5855fcSBarry Smith */ 15904a2ae208SSatish Balay #undef __FUNCT__ 15914a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1592ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1593be5855fcSBarry Smith { 1594be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 159597f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1596be5855fcSBarry Smith 1597be5855fcSBarry Smith PetscFunctionBegin; 159809f38230SBarry Smith *missing = PETSC_FALSE; 1599d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 160009f38230SBarry Smith *missing = PETSC_TRUE; 160109f38230SBarry Smith if (d) *d = 0; 1602358d2f5dSShri Abhyankar PetscInfo(A,"Matrix has no entries therefore is missing diagonal"); 160309f38230SBarry Smith } else { 1604f1e2ffcdSBarry Smith diag = a->diag; 1605d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1606bfeeae90SHong Zhang if (jj[diag[i]] != i) { 160709f38230SBarry Smith *missing = PETSC_TRUE; 160809f38230SBarry Smith if (d) *d = i; 160909f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 1610358d2f5dSShri Abhyankar break; 161109f38230SBarry Smith } 1612be5855fcSBarry Smith } 1613be5855fcSBarry Smith } 1614be5855fcSBarry Smith PetscFunctionReturn(0); 1615be5855fcSBarry Smith } 1616be5855fcSBarry Smith 161771f1c65dSBarry Smith #undef __FUNCT__ 161871f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 16197087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 162071f1c65dSBarry Smith { 162171f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 162271f1c65dSBarry Smith PetscErrorCode ierr; 1623d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 162454f21887SBarry Smith MatScalar *v = a->a; 162554f21887SBarry Smith PetscScalar *idiag,*mdiag; 162671f1c65dSBarry Smith 162771f1c65dSBarry Smith PetscFunctionBegin; 162871f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 162971f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 163071f1c65dSBarry Smith diag = a->diag; 163171f1c65dSBarry Smith if (!a->idiag) { 1632dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 16333bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 163471f1c65dSBarry Smith v = a->a; 163571f1c65dSBarry Smith } 163671f1c65dSBarry Smith mdiag = a->mdiag; 163771f1c65dSBarry Smith idiag = a->idiag; 163871f1c65dSBarry Smith 1639028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 164071f1c65dSBarry Smith for (i=0; i<m; i++) { 164171f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1642e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 164371f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 164471f1c65dSBarry Smith } 164571f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 164671f1c65dSBarry Smith } else { 164771f1c65dSBarry Smith for (i=0; i<m; i++) { 164871f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 164971f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 165071f1c65dSBarry Smith } 1651dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 165271f1c65dSBarry Smith } 165371f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 165471f1c65dSBarry Smith PetscFunctionReturn(0); 165571f1c65dSBarry Smith } 165671f1c65dSBarry Smith 1657c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 16584a2ae208SSatish Balay #undef __FUNCT__ 165941f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 166041f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 166117ab2063SBarry Smith { 1662416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1663e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1664e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 166554f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1666dfbe8321SBarry Smith PetscErrorCode ierr; 1667d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 166897f1f81fSBarry Smith const PetscInt *idx,*diag; 166917ab2063SBarry Smith 16703a40ed3dSBarry Smith PetscFunctionBegin; 1671b965ef7fSBarry Smith its = its*lits; 167291723122SBarry Smith 167371f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 167471f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 167571f1c65dSBarry Smith a->fshift = fshift; 167671f1c65dSBarry Smith a->omega = omega; 1677ed480e8bSBarry Smith 167871f1c65dSBarry Smith diag = a->diag; 167971f1c65dSBarry Smith t = a->ssor_work; 1680ed480e8bSBarry Smith idiag = a->idiag; 168171f1c65dSBarry Smith mdiag = a->mdiag; 1682ed480e8bSBarry Smith 16831ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 16843649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1685ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 168617ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 168717ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1688ed480e8bSBarry Smith bs = b; 168917ab2063SBarry Smith for (i=0; i<m; i++) { 169071f1c65dSBarry Smith d = fshift + mdiag[i]; 1691416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1692ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1693ed480e8bSBarry Smith v = a->a + diag[i] + 1; 169417ab2063SBarry Smith sum = b[i]*d/omega; 1695003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 169617ab2063SBarry Smith x[i] = sum; 169717ab2063SBarry Smith } 16981ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16993649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1700efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17013a40ed3dSBarry Smith PetscFunctionReturn(0); 170217ab2063SBarry Smith } 1703c783ea89SBarry Smith 17042205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 17052205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 170617ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1707887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 170817ab2063SBarry Smith 170917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 171017ab2063SBarry Smith 1711887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 171217ab2063SBarry Smith */ 171317ab2063SBarry Smith scale = (2.0/omega) - 1.0; 171417ab2063SBarry Smith 171517ab2063SBarry Smith /* x = (E + U)^{-1} b */ 171617ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1717416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1718ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1719ed480e8bSBarry Smith v = a->a + diag[i] + 1; 172017ab2063SBarry Smith sum = b[i]; 1721e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1722ed480e8bSBarry Smith x[i] = sum*idiag[i]; 172317ab2063SBarry Smith } 172417ab2063SBarry Smith 172517ab2063SBarry Smith /* t = b - (2*E - D)x */ 1726416022c9SBarry Smith v = a->a; 17272205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 172817ab2063SBarry Smith 172917ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1730ed480e8bSBarry Smith ts = t; 1731416022c9SBarry Smith diag = a->diag; 173217ab2063SBarry Smith for (i=0; i<m; i++) { 1733416022c9SBarry Smith n = diag[i] - a->i[i]; 1734ed480e8bSBarry Smith idx = a->j + a->i[i]; 1735ed480e8bSBarry Smith v = a->a + a->i[i]; 173617ab2063SBarry Smith sum = t[i]; 1737003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1738ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1739733d66baSBarry Smith /* x = x + t */ 1740733d66baSBarry Smith x[i] += t[i]; 174117ab2063SBarry Smith } 174217ab2063SBarry Smith 1743dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 17441ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17453649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 17463a40ed3dSBarry Smith PetscFunctionReturn(0); 174717ab2063SBarry Smith } 174817ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 174917ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 175017ab2063SBarry Smith for (i=0; i<m; i++) { 1751416022c9SBarry Smith n = diag[i] - a->i[i]; 1752ed480e8bSBarry Smith idx = a->j + a->i[i]; 1753ed480e8bSBarry Smith v = a->a + a->i[i]; 175417ab2063SBarry Smith sum = b[i]; 1755e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 17565c99c7daSBarry Smith t[i] = sum; 1757ed480e8bSBarry Smith x[i] = sum*idiag[i]; 175817ab2063SBarry Smith } 17595c99c7daSBarry Smith xb = t; 1760efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17613a40ed3dSBarry Smith } else xb = b; 176217ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 176317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1764416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1765ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1766ed480e8bSBarry Smith v = a->a + diag[i] + 1; 176717ab2063SBarry Smith sum = xb[i]; 1768e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 17695c99c7daSBarry Smith if (xb == b) { 1770ed480e8bSBarry Smith x[i] = sum*idiag[i]; 17715c99c7daSBarry Smith } else { 1772b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 177317ab2063SBarry Smith } 17745c99c7daSBarry Smith } 1775b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 177617ab2063SBarry Smith } 177717ab2063SBarry Smith its--; 177817ab2063SBarry Smith } 177917ab2063SBarry Smith while (its--) { 178017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 178117ab2063SBarry Smith for (i=0; i<m; i++) { 1782b19a5dc2SMark Adams /* lower */ 1783b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1784ed480e8bSBarry Smith idx = a->j + a->i[i]; 1785ed480e8bSBarry Smith v = a->a + a->i[i]; 178617ab2063SBarry Smith sum = b[i]; 1787e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1788b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1789b19a5dc2SMark Adams /* upper */ 1790b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1791b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1792b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1793b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1794b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 179517ab2063SBarry Smith } 1796b19a5dc2SMark Adams xb = t; 17979f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1798b19a5dc2SMark Adams } else xb = b; 179917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 180017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1801b19a5dc2SMark Adams sum = xb[i]; 1802b19a5dc2SMark Adams if (xb == b) { 1803b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1804416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1805ed480e8bSBarry Smith idx = a->j + a->i[i]; 1806ed480e8bSBarry Smith v = a->a + a->i[i]; 1807e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1808ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1809b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1810b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1811b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1812b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1813b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1814b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 181517ab2063SBarry Smith } 1816b19a5dc2SMark Adams } 1817b19a5dc2SMark Adams if (xb == b) { 18189f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1819b19a5dc2SMark Adams } else { 1820b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1821b19a5dc2SMark Adams } 182217ab2063SBarry Smith } 182317ab2063SBarry Smith } 18241ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18253649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1826365a8a9eSBarry Smith PetscFunctionReturn(0); 182717ab2063SBarry Smith } 182817ab2063SBarry Smith 18292af78befSBarry Smith 18304a2ae208SSatish Balay #undef __FUNCT__ 18314a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1832dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 183317ab2063SBarry Smith { 1834416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18354e220ebcSLois Curfman McInnes 18363a40ed3dSBarry Smith PetscFunctionBegin; 18374e220ebcSLois Curfman McInnes info->block_size = 1.0; 18384e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 18394e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 18404e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 18414e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 18428e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 18437adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1844d5f3da31SBarry Smith if (A->factortype) { 18454e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 18464e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 18474e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 18484e220ebcSLois Curfman McInnes } else { 18494e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 18504e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 18514e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 18524e220ebcSLois Curfman McInnes } 18533a40ed3dSBarry Smith PetscFunctionReturn(0); 185417ab2063SBarry Smith } 185517ab2063SBarry Smith 18564a2ae208SSatish Balay #undef __FUNCT__ 18574a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 18582b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 185917ab2063SBarry Smith { 1860416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18613b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 18626849ba73SBarry Smith PetscErrorCode ierr; 186397b48c8fSBarry Smith const PetscScalar *xx; 186497b48c8fSBarry Smith PetscScalar *bb; 1865ace3abfcSBarry Smith PetscBool missing; 186617ab2063SBarry Smith 18673a40ed3dSBarry Smith PetscFunctionBegin; 186897b48c8fSBarry Smith if (x && b) { 186997b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 187097b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 187197b48c8fSBarry Smith for (i=0; i<N; i++) { 187297b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 187397b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 187497b48c8fSBarry Smith } 187597b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 187697b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 187797b48c8fSBarry Smith } 187897b48c8fSBarry Smith 1879a9817697SBarry Smith if (a->keepnonzeropattern) { 1880f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1881e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1882bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1883f1e2ffcdSBarry Smith } 1884f4df32b1SMatthew Knepley if (diag != 0.0) { 188509f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1886e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1887f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1888f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1889f1e2ffcdSBarry Smith } 1890f1e2ffcdSBarry Smith } 189188e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1892f1e2ffcdSBarry Smith } else { 1893f4df32b1SMatthew Knepley if (diag != 0.0) { 189417ab2063SBarry Smith for (i=0; i<N; i++) { 1895e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18967ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1897416022c9SBarry Smith a->ilen[rows[i]] = 1; 1898f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1899bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 19007ae801bdSBarry Smith } else { /* in case row was completely empty */ 1901f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 190217ab2063SBarry Smith } 190317ab2063SBarry Smith } 19043a40ed3dSBarry Smith } else { 190517ab2063SBarry Smith for (i=0; i<N; i++) { 1906e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1907416022c9SBarry Smith a->ilen[rows[i]] = 0; 190817ab2063SBarry Smith } 190917ab2063SBarry Smith } 191088e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1911f1e2ffcdSBarry Smith } 191243a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19133a40ed3dSBarry Smith PetscFunctionReturn(0); 191417ab2063SBarry Smith } 191517ab2063SBarry Smith 19164a2ae208SSatish Balay #undef __FUNCT__ 19176e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 19186e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 19196e169961SBarry Smith { 19206e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19216e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 19226e169961SBarry Smith PetscErrorCode ierr; 19232b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 19246e169961SBarry Smith const PetscScalar *xx; 19256e169961SBarry Smith PetscScalar *bb; 19266e169961SBarry Smith 19276e169961SBarry Smith PetscFunctionBegin; 19286e169961SBarry Smith if (x && b) { 19296e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 19306e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 19312b40b63fSBarry Smith vecs = PETSC_TRUE; 19326e169961SBarry Smith } 19331795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 19346e169961SBarry Smith for (i=0; i<N; i++) { 19356e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 19366e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 19372205254eSKarl Rupp 19386e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 19396e169961SBarry Smith } 19406e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 19416e169961SBarry Smith if (!zeroed[i]) { 19426e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 19436e169961SBarry Smith if (zeroed[a->j[j]]) { 19442b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 19456e169961SBarry Smith a->a[j] = 0.0; 19466e169961SBarry Smith } 19476e169961SBarry Smith } 19482b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 19496e169961SBarry Smith } 19506e169961SBarry Smith if (x && b) { 19516e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 19526e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 19536e169961SBarry Smith } 19546e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 19556e169961SBarry Smith if (diag != 0.0) { 19566e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 19576e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 19586e169961SBarry Smith for (i=0; i<N; i++) { 19596e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 19606e169961SBarry Smith } 19616e169961SBarry Smith } 19626e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 19636e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19646e169961SBarry Smith PetscFunctionReturn(0); 19656e169961SBarry Smith } 19666e169961SBarry Smith 19676e169961SBarry Smith #undef __FUNCT__ 19684a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1969a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 197017ab2063SBarry Smith { 1971416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 197297f1f81fSBarry Smith PetscInt *itmp; 197317ab2063SBarry Smith 19743a40ed3dSBarry Smith PetscFunctionBegin; 1975e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 197617ab2063SBarry Smith 1977416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1978bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 197917ab2063SBarry Smith if (idx) { 1980bfeeae90SHong Zhang itmp = a->j + a->i[row]; 198126fbe8dcSKarl Rupp if (*nz) *idx = itmp; 198217ab2063SBarry Smith else *idx = 0; 198317ab2063SBarry Smith } 19843a40ed3dSBarry Smith PetscFunctionReturn(0); 198517ab2063SBarry Smith } 198617ab2063SBarry Smith 1987bfeeae90SHong Zhang /* remove this function? */ 19884a2ae208SSatish Balay #undef __FUNCT__ 19894a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1990a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 199117ab2063SBarry Smith { 19923a40ed3dSBarry Smith PetscFunctionBegin; 19933a40ed3dSBarry Smith PetscFunctionReturn(0); 199417ab2063SBarry Smith } 199517ab2063SBarry Smith 19964a2ae208SSatish Balay #undef __FUNCT__ 19974a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1998dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 199917ab2063SBarry Smith { 2000416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 200154f21887SBarry Smith MatScalar *v = a->a; 200236db0b34SBarry Smith PetscReal sum = 0.0; 20036849ba73SBarry Smith PetscErrorCode ierr; 200497f1f81fSBarry Smith PetscInt i,j; 200517ab2063SBarry Smith 20063a40ed3dSBarry Smith PetscFunctionBegin; 200717ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2008416022c9SBarry Smith for (i=0; i<a->nz; i++) { 200936db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 201017ab2063SBarry Smith } 20118f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 20123a40ed3dSBarry Smith } else if (type == NORM_1) { 201336db0b34SBarry Smith PetscReal *tmp; 201497f1f81fSBarry Smith PetscInt *jj = a->j; 20151795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2016064f8208SBarry Smith *nrm = 0.0; 2017416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2018bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 201917ab2063SBarry Smith } 2020d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2021064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 202217ab2063SBarry Smith } 2023606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 20243a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2025064f8208SBarry Smith *nrm = 0.0; 2026d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2027bfeeae90SHong Zhang v = a->a + a->i[j]; 202817ab2063SBarry Smith sum = 0.0; 2029416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2030cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 203117ab2063SBarry Smith } 2032064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 203317ab2063SBarry Smith } 2034f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 20353a40ed3dSBarry Smith PetscFunctionReturn(0); 203617ab2063SBarry Smith } 203717ab2063SBarry Smith 20384e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 20394e938277SHong Zhang #undef __FUNCT__ 20404e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ" 20414e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 20424e938277SHong Zhang { 20434e938277SHong Zhang PetscErrorCode ierr; 20444e938277SHong Zhang PetscInt i,j,anzj; 20454e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 20464e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 20474e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 20484e938277SHong Zhang 20494e938277SHong Zhang PetscFunctionBegin; 20504e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 20511795a4d1SJed Brown ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr); 2052785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2053785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 20544e938277SHong Zhang 20554e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 20564e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 205726fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 20584e938277SHong Zhang /* Form ati for csr format of A^T. */ 205926fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 20604e938277SHong Zhang 20614e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 20624e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 20634e938277SHong Zhang 20644e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 20654e938277SHong Zhang for (i=0;i<am;i++) { 20664e938277SHong Zhang anzj = ai[i+1] - ai[i]; 20674e938277SHong Zhang for (j=0;j<anzj;j++) { 20684e938277SHong Zhang atj[atfill[*aj]] = i; 20694e938277SHong Zhang atfill[*aj++] += 1; 20704e938277SHong Zhang } 20714e938277SHong Zhang } 20724e938277SHong Zhang 20734e938277SHong Zhang /* Clean up temporary space and complete requests. */ 20744e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2075ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 20762205254eSKarl Rupp 2077a2f3521dSMark F. Adams (*B)->rmap->bs = A->cmap->bs; 2078a2f3521dSMark F. Adams (*B)->cmap->bs = A->rmap->bs; 2079a2f3521dSMark F. Adams 20804e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 20814e938277SHong Zhang b->free_a = PETSC_FALSE; 20824e938277SHong Zhang b->free_ij = PETSC_TRUE; 20834e938277SHong Zhang b->nonew = 0; 20844e938277SHong Zhang PetscFunctionReturn(0); 20854e938277SHong Zhang } 20864e938277SHong Zhang 20874a2ae208SSatish Balay #undef __FUNCT__ 20884a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 2089fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 209017ab2063SBarry Smith { 2091416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2092416022c9SBarry Smith Mat C; 20936849ba73SBarry Smith PetscErrorCode ierr; 2094d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 209554f21887SBarry Smith MatScalar *array = a->a; 209617ab2063SBarry Smith 20973a40ed3dSBarry Smith PetscFunctionBegin; 2098e32f2f54SBarry Smith if (reuse == MAT_REUSE_MATRIX && A == *B && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 2099fc4dec0aSBarry Smith 2100fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 21011795a4d1SJed Brown ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr); 2102bfeeae90SHong Zhang 2103bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 2104ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2105d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 2106a2f3521dSMark F. Adams ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr); 21077adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2108ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2109606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2110a541d17aSBarry Smith } else { 2111a541d17aSBarry Smith C = *B; 2112a541d17aSBarry Smith } 2113a541d17aSBarry Smith 211417ab2063SBarry Smith for (i=0; i<m; i++) { 211517ab2063SBarry Smith len = ai[i+1]-ai[i]; 211687d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2117b9b97703SBarry Smith array += len; 2118b9b97703SBarry Smith aj += len; 211917ab2063SBarry Smith } 21206d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21216d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 212217ab2063SBarry Smith 2123815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 2124416022c9SBarry Smith *B = C; 212517ab2063SBarry Smith } else { 2126eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 212717ab2063SBarry Smith } 21283a40ed3dSBarry Smith PetscFunctionReturn(0); 212917ab2063SBarry Smith } 213017ab2063SBarry Smith 2131cd0d46ebSvictorle #undef __FUNCT__ 21325fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 21337087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2134cd0d46ebSvictorle { 2135cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 213654f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 213754f21887SBarry Smith MatScalar *va,*vb; 21386849ba73SBarry Smith PetscErrorCode ierr; 213997f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2140cd0d46ebSvictorle 2141cd0d46ebSvictorle PetscFunctionBegin; 2142cd0d46ebSvictorle bij = (Mat_SeqAIJ*) B->data; 2143cd0d46ebSvictorle 2144cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2145cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 21465485867bSBarry Smith if (ma!=nb || na!=mb) { 21475485867bSBarry Smith *f = PETSC_FALSE; 21485485867bSBarry Smith PetscFunctionReturn(0); 21495485867bSBarry Smith } 2150cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2151cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2152cd0d46ebSvictorle va = aij->a; vb = bij->a; 2153785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2154785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2155cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2156cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2157cd0d46ebSvictorle 2158cd0d46ebSvictorle *f = PETSC_TRUE; 2159cd0d46ebSvictorle for (i=0; i<ma; i++) { 2160cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 216197f1f81fSBarry Smith PetscInt idc,idr; 21625485867bSBarry Smith PetscScalar vc,vr; 2163cd0d46ebSvictorle /* column/row index/value */ 21645485867bSBarry Smith idc = adx[aptr[i]]; 21655485867bSBarry Smith idr = bdx[bptr[idc]]; 21665485867bSBarry Smith vc = va[aptr[i]]; 21675485867bSBarry Smith vr = vb[bptr[idc]]; 21685485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 21695485867bSBarry Smith *f = PETSC_FALSE; 21705485867bSBarry Smith goto done; 2171cd0d46ebSvictorle } else { 21725485867bSBarry Smith aptr[i]++; 21735485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2174cd0d46ebSvictorle } 2175cd0d46ebSvictorle } 2176cd0d46ebSvictorle } 2177cd0d46ebSvictorle done: 2178cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 21793aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2180cd0d46ebSvictorle PetscFunctionReturn(0); 2181cd0d46ebSvictorle } 2182cd0d46ebSvictorle 21831cbb95d3SBarry Smith #undef __FUNCT__ 21841cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 21857087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 21861cbb95d3SBarry Smith { 21871cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 218854f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 218954f21887SBarry Smith MatScalar *va,*vb; 21901cbb95d3SBarry Smith PetscErrorCode ierr; 21911cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 21921cbb95d3SBarry Smith 21931cbb95d3SBarry Smith PetscFunctionBegin; 21941cbb95d3SBarry Smith bij = (Mat_SeqAIJ*) B->data; 21951cbb95d3SBarry Smith 21961cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 21971cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 21981cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 21991cbb95d3SBarry Smith *f = PETSC_FALSE; 22001cbb95d3SBarry Smith PetscFunctionReturn(0); 22011cbb95d3SBarry Smith } 22021cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 22031cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 22041cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2205785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2206785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 22071cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 22081cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 22091cbb95d3SBarry Smith 22101cbb95d3SBarry Smith *f = PETSC_TRUE; 22111cbb95d3SBarry Smith for (i=0; i<ma; i++) { 22121cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 22131cbb95d3SBarry Smith PetscInt idc,idr; 22141cbb95d3SBarry Smith PetscScalar vc,vr; 22151cbb95d3SBarry Smith /* column/row index/value */ 22161cbb95d3SBarry Smith idc = adx[aptr[i]]; 22171cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 22181cbb95d3SBarry Smith vc = va[aptr[i]]; 22191cbb95d3SBarry Smith vr = vb[bptr[idc]]; 22201cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 22211cbb95d3SBarry Smith *f = PETSC_FALSE; 22221cbb95d3SBarry Smith goto done; 22231cbb95d3SBarry Smith } else { 22241cbb95d3SBarry Smith aptr[i]++; 22251cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 22261cbb95d3SBarry Smith } 22271cbb95d3SBarry Smith } 22281cbb95d3SBarry Smith } 22291cbb95d3SBarry Smith done: 22301cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 22311cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 22321cbb95d3SBarry Smith PetscFunctionReturn(0); 22331cbb95d3SBarry Smith } 22341cbb95d3SBarry Smith 22359e29f15eSvictorle #undef __FUNCT__ 22369e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 2237ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 22389e29f15eSvictorle { 2239dfbe8321SBarry Smith PetscErrorCode ierr; 22406e111a19SKarl Rupp 22419e29f15eSvictorle PetscFunctionBegin; 22425485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 22439e29f15eSvictorle PetscFunctionReturn(0); 22449e29f15eSvictorle } 22459e29f15eSvictorle 22464a2ae208SSatish Balay #undef __FUNCT__ 22471cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 2248ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 22491cbb95d3SBarry Smith { 22501cbb95d3SBarry Smith PetscErrorCode ierr; 22516e111a19SKarl Rupp 22521cbb95d3SBarry Smith PetscFunctionBegin; 22531cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 22541cbb95d3SBarry Smith PetscFunctionReturn(0); 22551cbb95d3SBarry Smith } 22561cbb95d3SBarry Smith 22571cbb95d3SBarry Smith #undef __FUNCT__ 22584a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 2259dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 226017ab2063SBarry Smith { 2261416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 226254f21887SBarry Smith PetscScalar *l,*r,x; 226354f21887SBarry Smith MatScalar *v; 2264dfbe8321SBarry Smith PetscErrorCode ierr; 2265d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 226617ab2063SBarry Smith 22673a40ed3dSBarry Smith PetscFunctionBegin; 226817ab2063SBarry Smith if (ll) { 22693ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 22703ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2271e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2272e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 22731ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2274416022c9SBarry Smith v = a->a; 227517ab2063SBarry Smith for (i=0; i<m; i++) { 227617ab2063SBarry Smith x = l[i]; 2277416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 22782205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 227917ab2063SBarry Smith } 22801ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2281efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 228217ab2063SBarry Smith } 228317ab2063SBarry Smith if (rr) { 2284e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2285e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 22861ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2287416022c9SBarry Smith v = a->a; jj = a->j; 22882205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 22891ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2290efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 229117ab2063SBarry Smith } 2292acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 22933a40ed3dSBarry Smith PetscFunctionReturn(0); 229417ab2063SBarry Smith } 229517ab2063SBarry Smith 22964a2ae208SSatish Balay #undef __FUNCT__ 22974a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 229897f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 229917ab2063SBarry Smith { 2300db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 23016849ba73SBarry Smith PetscErrorCode ierr; 2302d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 230397f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 23045d0c19d7SBarry Smith const PetscInt *irow,*icol; 23055d0c19d7SBarry Smith PetscInt nrows,ncols; 230697f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 230754f21887SBarry Smith MatScalar *a_new,*mat_a; 2308416022c9SBarry Smith Mat C; 2309ace3abfcSBarry Smith PetscBool stride,sorted; 231017ab2063SBarry Smith 23113a40ed3dSBarry Smith PetscFunctionBegin; 231214ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 2313e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 231414ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2315e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 231699141d43SSatish Balay 231717ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2318b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2319b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 232017ab2063SBarry Smith 2321fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2322251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2323fee21e36SBarry Smith if (stride && step == 1) { 232402834360SBarry Smith /* special case of contiguous rows */ 2325dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 232602834360SBarry Smith /* loop over new rows determining lens and starting points */ 232702834360SBarry Smith for (i=0; i<nrows; i++) { 2328bfeeae90SHong Zhang kstart = ai[irow[i]]; 2329a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 233002834360SBarry Smith for (k=kstart; k<kend; k++) { 2331bfeeae90SHong Zhang if (aj[k] >= first) { 233202834360SBarry Smith starts[i] = k; 233302834360SBarry Smith break; 233402834360SBarry Smith } 233502834360SBarry Smith } 2336a2744918SBarry Smith sum = 0; 233702834360SBarry Smith while (k < kend) { 2338bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2339a2744918SBarry Smith sum++; 234002834360SBarry Smith } 2341a2744918SBarry Smith lens[i] = sum; 234202834360SBarry Smith } 234302834360SBarry Smith /* create submatrix */ 2344cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 234597f1f81fSBarry Smith PetscInt n_cols,n_rows; 234608480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2347e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2348d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 234908480c60SBarry Smith C = *B; 23503a40ed3dSBarry Smith } else { 23513bef6203SJed Brown PetscInt rbs,cbs; 2352ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2353f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 23543bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 23553bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 23563bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 23577adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2358ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 235908480c60SBarry Smith } 2360db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2361db02288aSLois Curfman McInnes 236202834360SBarry Smith /* loop over rows inserting into submatrix */ 2363db02288aSLois Curfman McInnes a_new = c->a; 2364db02288aSLois Curfman McInnes j_new = c->j; 2365db02288aSLois Curfman McInnes i_new = c->i; 2366bfeeae90SHong Zhang 236702834360SBarry Smith for (i=0; i<nrows; i++) { 2368a2744918SBarry Smith ii = starts[i]; 2369a2744918SBarry Smith lensi = lens[i]; 2370a2744918SBarry Smith for (k=0; k<lensi; k++) { 2371a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 237202834360SBarry Smith } 237387828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2374a2744918SBarry Smith a_new += lensi; 2375a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2376a2744918SBarry Smith c->ilen[i] = lensi; 237702834360SBarry Smith } 23780e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 23793a40ed3dSBarry Smith } else { 238002834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 23811795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2382785e854fSJed Brown ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr); 23834dcab191SBarry Smith for (i=0; i<ncols; i++) { 23844dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 23854dcab191SBarry 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); 23864dcab191SBarry Smith #endif 23874dcab191SBarry Smith smap[icol[i]] = i+1; 23884dcab191SBarry Smith } 23894dcab191SBarry Smith 239002834360SBarry Smith /* determine lens of each row */ 239102834360SBarry Smith for (i=0; i<nrows; i++) { 2392bfeeae90SHong Zhang kstart = ai[irow[i]]; 239302834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 239402834360SBarry Smith lens[i] = 0; 239502834360SBarry Smith for (k=kstart; k<kend; k++) { 2396bfeeae90SHong Zhang if (smap[aj[k]]) { 239702834360SBarry Smith lens[i]++; 239802834360SBarry Smith } 239902834360SBarry Smith } 240002834360SBarry Smith } 240117ab2063SBarry Smith /* Create and fill new matrix */ 2402a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2403ace3abfcSBarry Smith PetscBool equal; 24040f5bd95cSBarry Smith 240599141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2406e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2407d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2408f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2409d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 241008480c60SBarry Smith C = *B; 24113a40ed3dSBarry Smith } else { 24123bef6203SJed Brown PetscInt rbs,cbs; 2413ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2414f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24153bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 24163bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 24173bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 24187adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2419ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 242008480c60SBarry Smith } 242199141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 242217ab2063SBarry Smith for (i=0; i<nrows; i++) { 242399141d43SSatish Balay row = irow[i]; 2424bfeeae90SHong Zhang kstart = ai[row]; 242599141d43SSatish Balay kend = kstart + a->ilen[row]; 2426bfeeae90SHong Zhang mat_i = c->i[i]; 242799141d43SSatish Balay mat_j = c->j + mat_i; 242899141d43SSatish Balay mat_a = c->a + mat_i; 242999141d43SSatish Balay mat_ilen = c->ilen + i; 243017ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2431bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2432ed480e8bSBarry Smith *mat_j++ = tcol - 1; 243399141d43SSatish Balay *mat_a++ = a->a[k]; 243499141d43SSatish Balay (*mat_ilen)++; 243599141d43SSatish Balay 243617ab2063SBarry Smith } 243717ab2063SBarry Smith } 243817ab2063SBarry Smith } 243902834360SBarry Smith /* Free work space */ 244002834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2441606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2442606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 244302834360SBarry Smith } 24446d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24456d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 244617ab2063SBarry Smith 244717ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2448416022c9SBarry Smith *B = C; 24493a40ed3dSBarry Smith PetscFunctionReturn(0); 245017ab2063SBarry Smith } 245117ab2063SBarry Smith 24521df811f5SHong Zhang #undef __FUNCT__ 245382d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 2454fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 245582d44351SHong Zhang { 245682d44351SHong Zhang PetscErrorCode ierr; 245782d44351SHong Zhang Mat B; 245882d44351SHong Zhang 245982d44351SHong Zhang PetscFunctionBegin; 2460c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 246182d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 246282d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 2463a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr); 246482d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 246582d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 246682d44351SHong Zhang *subMat = B; 2467c2d650bdSHong Zhang } else { 2468c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2469c2d650bdSHong Zhang } 247082d44351SHong Zhang PetscFunctionReturn(0); 247182d44351SHong Zhang } 247282d44351SHong Zhang 247382d44351SHong Zhang #undef __FUNCT__ 24744a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 24750481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2476a871dcd8SBarry Smith { 247763b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2478dfbe8321SBarry Smith PetscErrorCode ierr; 247963b91edcSBarry Smith Mat outA; 2480ace3abfcSBarry Smith PetscBool row_identity,col_identity; 248163b91edcSBarry Smith 24823a40ed3dSBarry Smith PetscFunctionBegin; 2483e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 24841df811f5SHong Zhang 2485b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2486b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2487a871dcd8SBarry Smith 248863b91edcSBarry Smith outA = inA; 2489d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 24902205254eSKarl Rupp 2491c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 24926bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 24932205254eSKarl Rupp 2494c3122656SLisandro Dalcin a->row = row; 24952205254eSKarl Rupp 2496c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 24976bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 24982205254eSKarl Rupp 2499c3122656SLisandro Dalcin a->col = col; 250063b91edcSBarry Smith 250136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 25026bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 25034c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 25043bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2505f0ec6fceSSatish Balay 250694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2507785e854fSJed Brown ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr); 25083bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 250994a9d846SBarry Smith } 251063b91edcSBarry Smith 2511f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2512137fb511SHong Zhang if (row_identity && col_identity) { 2513ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2514137fb511SHong Zhang } else { 2515719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2516137fb511SHong Zhang } 25173a40ed3dSBarry Smith PetscFunctionReturn(0); 2518a871dcd8SBarry Smith } 2519a871dcd8SBarry Smith 25204a2ae208SSatish Balay #undef __FUNCT__ 25214a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2522f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2523f0b747eeSBarry Smith { 2524f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2525f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2526efee365bSSatish Balay PetscErrorCode ierr; 2527c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 25283a40ed3dSBarry Smith 25293a40ed3dSBarry Smith PetscFunctionBegin; 2530c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 25318b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2532efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2533acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 25343a40ed3dSBarry Smith PetscFunctionReturn(0); 2535f0b747eeSBarry Smith } 2536f0b747eeSBarry Smith 25374a2ae208SSatish Balay #undef __FUNCT__ 25384a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 253997f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2540cddf8d76SBarry Smith { 2541dfbe8321SBarry Smith PetscErrorCode ierr; 254297f1f81fSBarry Smith PetscInt i; 2543cddf8d76SBarry Smith 25443a40ed3dSBarry Smith PetscFunctionBegin; 2545cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2546785e854fSJed Brown ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr); 2547cddf8d76SBarry Smith } 2548cddf8d76SBarry Smith 2549cddf8d76SBarry Smith for (i=0; i<n; i++) { 25506a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2551cddf8d76SBarry Smith } 25523a40ed3dSBarry Smith PetscFunctionReturn(0); 2553cddf8d76SBarry Smith } 2554cddf8d76SBarry Smith 25554a2ae208SSatish Balay #undef __FUNCT__ 25564a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 255797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 25584dcbc457SBarry Smith { 2559e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25606849ba73SBarry Smith PetscErrorCode ierr; 25615d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 25625d0c19d7SBarry Smith const PetscInt *idx; 256397f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2564f1af5d2fSBarry Smith PetscBT table; 2565bbd702dbSSatish Balay 25663a40ed3dSBarry Smith PetscFunctionBegin; 2567d0f46423SBarry Smith m = A->rmap->n; 2568e4d965acSSatish Balay ai = a->i; 2569bfeeae90SHong Zhang aj = a->j; 25708a047759SSatish Balay 2571e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 257206763907SSatish Balay 2573785e854fSJed Brown ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr); 257453b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 257506763907SSatish Balay 2576e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2577b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2578e4d965acSSatish Balay isz = 0; 25796831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2580e4d965acSSatish Balay 2581e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25824dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2583b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2584e4d965acSSatish Balay 2585dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2586e4d965acSSatish Balay for (j=0; j<n; ++j) { 25872205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25884dcbc457SBarry Smith } 258906763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25906bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2591e4d965acSSatish Balay 259204a348a9SBarry Smith k = 0; 259304a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 259404a348a9SBarry Smith n = isz; 259506763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2596e4d965acSSatish Balay row = nidx[k]; 2597e4d965acSSatish Balay start = ai[row]; 2598e4d965acSSatish Balay end = ai[row+1]; 259904a348a9SBarry Smith for (l = start; l<end; l++) { 2600efb16452SHong Zhang val = aj[l]; 26012205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2602e4d965acSSatish Balay } 2603e4d965acSSatish Balay } 2604e4d965acSSatish Balay } 260570b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2606e4d965acSSatish Balay } 260794bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2608606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 26093a40ed3dSBarry Smith PetscFunctionReturn(0); 26104dcbc457SBarry Smith } 261117ab2063SBarry Smith 26120513a670SBarry Smith /* -------------------------------------------------------------- */ 26134a2ae208SSatish Balay #undef __FUNCT__ 26144a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2615dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 26160513a670SBarry Smith { 26170513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26186849ba73SBarry Smith PetscErrorCode ierr; 26193b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 26205d0c19d7SBarry Smith const PetscInt *row,*col; 26215d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 262256cd22aeSBarry Smith IS icolp,irowp; 26230298fd71SBarry Smith PetscInt *cwork = NULL; 26240298fd71SBarry Smith PetscScalar *vwork = NULL; 26250513a670SBarry Smith 26263a40ed3dSBarry Smith PetscFunctionBegin; 26274c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 262856cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 26294c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 263056cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 26310513a670SBarry Smith 26320513a670SBarry Smith /* determine lengths of permuted rows */ 2633785e854fSJed Brown ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr); 26342205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2635ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2636f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 2637a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 26387adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2639ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2640606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 26410513a670SBarry Smith 2642785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 26430513a670SBarry Smith for (i=0; i<m; i++) { 264432ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 26452205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2646cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 264732ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 26480513a670SBarry Smith } 2649606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 26502205254eSKarl Rupp 26513c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 26522205254eSKarl Rupp 26530513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26540513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 265556cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 265656cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 26576bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 26586bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 26593a40ed3dSBarry Smith PetscFunctionReturn(0); 26600513a670SBarry Smith } 26610513a670SBarry Smith 26624a2ae208SSatish Balay #undef __FUNCT__ 26634a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2664dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2665cb5b572fSBarry Smith { 2666dfbe8321SBarry Smith PetscErrorCode ierr; 2667cb5b572fSBarry Smith 2668cb5b572fSBarry Smith PetscFunctionBegin; 266933f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 267033f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2671be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2672be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2673be6bf707SBarry Smith 2674700c5bfcSBarry 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"); 2675d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2676cb5b572fSBarry Smith } else { 2677cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2678cb5b572fSBarry Smith } 2679cb5b572fSBarry Smith PetscFunctionReturn(0); 2680cb5b572fSBarry Smith } 2681cb5b572fSBarry Smith 26824a2ae208SSatish Balay #undef __FUNCT__ 26834994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ" 26844994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2685273d9f13SBarry Smith { 2686dfbe8321SBarry Smith PetscErrorCode ierr; 2687273d9f13SBarry Smith 2688273d9f13SBarry Smith PetscFunctionBegin; 2689ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2690273d9f13SBarry Smith PetscFunctionReturn(0); 2691273d9f13SBarry Smith } 2692273d9f13SBarry Smith 26934a2ae208SSatish Balay #undef __FUNCT__ 26948c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ" 26958c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 26966c0721eeSBarry Smith { 26976c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26986e111a19SKarl Rupp 26996c0721eeSBarry Smith PetscFunctionBegin; 27006c0721eeSBarry Smith *array = a->a; 27016c0721eeSBarry Smith PetscFunctionReturn(0); 27026c0721eeSBarry Smith } 27036c0721eeSBarry Smith 27044a2ae208SSatish Balay #undef __FUNCT__ 27058c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ" 27068c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 27076c0721eeSBarry Smith { 27086c0721eeSBarry Smith PetscFunctionBegin; 27096c0721eeSBarry Smith PetscFunctionReturn(0); 27106c0721eeSBarry Smith } 2711273d9f13SBarry Smith 27128229c054SShri Abhyankar /* 27138229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 27148229c054SShri Abhyankar have different nonzero structure. 27158229c054SShri Abhyankar */ 2716ac90fabeSBarry Smith #undef __FUNCT__ 27178229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 27188229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2719ec7775f6SShri Abhyankar { 27208229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 2721ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2722ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2723ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 2724ec7775f6SShri Abhyankar 2725ec7775f6SShri Abhyankar PetscFunctionBegin; 2726ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2727ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 27288af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 27298af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 27308af7cee1SJed Brown nnz[i] = 0; 27318af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 27328af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 27338af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 27348af7cee1SJed Brown nnz[i]++; 27358af7cee1SJed Brown } 27368af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2737ec7775f6SShri Abhyankar } 2738ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2739ec7775f6SShri Abhyankar } 2740ec7775f6SShri Abhyankar 2741ec7775f6SShri Abhyankar #undef __FUNCT__ 2742ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2743f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2744ac90fabeSBarry Smith { 2745dfbe8321SBarry Smith PetscErrorCode ierr; 274697f1f81fSBarry Smith PetscInt i; 2747ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2748c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2749ac90fabeSBarry Smith 2750ac90fabeSBarry Smith PetscFunctionBegin; 2751c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2752ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2753f4df32b1SMatthew Knepley PetscScalar alpha = a; 27548b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2755acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2756c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2757a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2758a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 27596bf464f9SBarry Smith ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr); 2760a30b2313SHong Zhang } 2761a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 27620298fd71SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr); 2763a30b2313SHong Zhang y->XtoY = X; 2764407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2765c537a176SHong Zhang } 2766f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 2767*6712e2f1SBarry Smith ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %D/%D = %g\n",x->nz,y->nz,(double)((PetscReal)(x->nz)/(y->nz+1)));CHKERRQ(ierr); 2768ac90fabeSBarry Smith } else { 27698229c054SShri Abhyankar Mat B; 27708229c054SShri Abhyankar PetscInt *nnz; 2771785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2772ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2773bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 27744aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 2775a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr); 2776176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 27778229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2778ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2779ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2780ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 27818229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2782ac90fabeSBarry Smith } 2783ac90fabeSBarry Smith PetscFunctionReturn(0); 2784ac90fabeSBarry Smith } 2785ac90fabeSBarry Smith 2786521d7252SBarry Smith #undef __FUNCT__ 2787354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 27887087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2789354c94deSBarry Smith { 2790354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2791354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2792354c94deSBarry Smith PetscInt i,nz; 2793354c94deSBarry Smith PetscScalar *a; 2794354c94deSBarry Smith 2795354c94deSBarry Smith PetscFunctionBegin; 2796354c94deSBarry Smith nz = aij->nz; 2797354c94deSBarry Smith a = aij->a; 27982205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2799354c94deSBarry Smith #else 2800354c94deSBarry Smith PetscFunctionBegin; 2801354c94deSBarry Smith #endif 2802354c94deSBarry Smith PetscFunctionReturn(0); 2803354c94deSBarry Smith } 2804354c94deSBarry Smith 2805e34fafa9SBarry Smith #undef __FUNCT__ 2806985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2807985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2808e34fafa9SBarry Smith { 2809e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2810e34fafa9SBarry Smith PetscErrorCode ierr; 2811d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2812e34fafa9SBarry Smith PetscReal atmp; 2813985db425SBarry Smith PetscScalar *x; 2814e34fafa9SBarry Smith MatScalar *aa; 2815e34fafa9SBarry Smith 2816e34fafa9SBarry Smith PetscFunctionBegin; 2817e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2818e34fafa9SBarry Smith aa = a->a; 2819e34fafa9SBarry Smith ai = a->i; 2820e34fafa9SBarry Smith aj = a->j; 2821e34fafa9SBarry Smith 2822985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2823e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2824e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2825e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2826e34fafa9SBarry Smith for (i=0; i<m; i++) { 2827e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 28289189402eSHong Zhang x[i] = 0.0; 2829e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2830985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2831985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2832985db425SBarry Smith aa++; aj++; 2833985db425SBarry Smith } 2834985db425SBarry Smith } 2835985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2836985db425SBarry Smith PetscFunctionReturn(0); 2837985db425SBarry Smith } 2838985db425SBarry Smith 2839985db425SBarry Smith #undef __FUNCT__ 2840985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2841985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2842985db425SBarry Smith { 2843985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2844985db425SBarry Smith PetscErrorCode ierr; 2845d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2846985db425SBarry Smith PetscScalar *x; 2847985db425SBarry Smith 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 maximum is 0.0 or higher */ 2864985db425SBarry Smith x[i] = 0.0; 2865985db425SBarry Smith if (idx) { 2866985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2867985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 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++; 2878985db425SBarry Smith } 2879985db425SBarry Smith } 2880985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2881985db425SBarry Smith PetscFunctionReturn(0); 2882985db425SBarry Smith } 2883985db425SBarry Smith 2884985db425SBarry Smith #undef __FUNCT__ 2885c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 2886c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2887c87e5d42SMatthew Knepley { 2888c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2889c87e5d42SMatthew Knepley PetscErrorCode ierr; 2890c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2891c87e5d42SMatthew Knepley PetscReal atmp; 2892c87e5d42SMatthew Knepley PetscScalar *x; 2893c87e5d42SMatthew Knepley MatScalar *aa; 2894c87e5d42SMatthew Knepley 2895c87e5d42SMatthew Knepley PetscFunctionBegin; 2896e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2897c87e5d42SMatthew Knepley aa = a->a; 2898c87e5d42SMatthew Knepley ai = a->i; 2899c87e5d42SMatthew Knepley aj = a->j; 2900c87e5d42SMatthew Knepley 2901c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2902c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2903c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 290460e0710aSBarry 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); 2905c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2906c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2907289a08f5SMatthew Knepley if (ncols) { 2908289a08f5SMatthew Knepley /* Get first nonzero */ 2909289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 2910289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 29112205254eSKarl Rupp if (atmp > 1.0e-12) { 29122205254eSKarl Rupp x[i] = atmp; 29132205254eSKarl Rupp if (idx) idx[i] = aj[j]; 29142205254eSKarl Rupp break; 29152205254eSKarl Rupp } 2916289a08f5SMatthew Knepley } 291712431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2918289a08f5SMatthew Knepley } else { 2919289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2920289a08f5SMatthew Knepley } 2921c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 2922c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2923289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2924c87e5d42SMatthew Knepley aa++; aj++; 2925c87e5d42SMatthew Knepley } 2926c87e5d42SMatthew Knepley } 2927c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2928c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2929c87e5d42SMatthew Knepley } 2930c87e5d42SMatthew Knepley 2931c87e5d42SMatthew Knepley #undef __FUNCT__ 2932985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 2933985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2934985db425SBarry Smith { 2935985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2936985db425SBarry Smith PetscErrorCode ierr; 2937d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2938985db425SBarry Smith PetscScalar *x; 2939985db425SBarry Smith MatScalar *aa; 2940985db425SBarry Smith 2941985db425SBarry Smith PetscFunctionBegin; 2942e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2943985db425SBarry Smith aa = a->a; 2944985db425SBarry Smith ai = a->i; 2945985db425SBarry Smith aj = a->j; 2946985db425SBarry Smith 2947985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2948985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2949985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2950e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2951985db425SBarry Smith for (i=0; i<m; i++) { 2952985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2953d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2954985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2955985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2956985db425SBarry Smith x[i] = 0.0; 2957985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2958985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2959985db425SBarry Smith for (j=0; j<ncols; j++) { 2960985db425SBarry Smith if (aj[j] > j) { 2961985db425SBarry Smith idx[i] = j; 2962985db425SBarry Smith break; 2963985db425SBarry Smith } 2964985db425SBarry Smith } 2965985db425SBarry Smith } 2966985db425SBarry Smith } 2967985db425SBarry Smith for (j=0; j<ncols; j++) { 2968985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2969985db425SBarry Smith aa++; aj++; 2970e34fafa9SBarry Smith } 2971e34fafa9SBarry Smith } 2972e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2973e34fafa9SBarry Smith PetscFunctionReturn(0); 2974e34fafa9SBarry Smith } 2975bbead8a2SBarry Smith 2976bbead8a2SBarry Smith #include <petscblaslapack.h> 297706873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h> 2978bbead8a2SBarry Smith 2979bbead8a2SBarry Smith #undef __FUNCT__ 2980bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ" 2981713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2982bbead8a2SBarry Smith { 2983bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2984bbead8a2SBarry Smith PetscErrorCode ierr; 298534fc4b71SJed Brown PetscInt i,bs = A->rmap->bs,mbs = A->rmap->n/A->rmap->bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2986bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2987bbead8a2SBarry Smith PetscReal shift = 0.0; 2988bbead8a2SBarry Smith 2989bbead8a2SBarry Smith PetscFunctionBegin; 29904a0d0026SBarry Smith if (a->ibdiagvalid) { 29914a0d0026SBarry Smith if (values) *values = a->ibdiag; 29924a0d0026SBarry Smith PetscFunctionReturn(0); 29934a0d0026SBarry Smith } 2994bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2995bbead8a2SBarry Smith if (!a->ibdiag) { 2996785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 29973bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2998bbead8a2SBarry Smith } 2999bbead8a2SBarry Smith diag = a->ibdiag; 3000bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3001bbead8a2SBarry Smith /* factor and invert each block */ 3002bbead8a2SBarry Smith switch (bs) { 3003bbead8a2SBarry Smith case 1: 3004bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3005bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3006bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3007bbead8a2SBarry Smith } 3008bbead8a2SBarry Smith break; 3009bbead8a2SBarry Smith case 2: 3010bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3011bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3012bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 301396b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr); 301496b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3015bbead8a2SBarry Smith diag += 4; 3016bbead8a2SBarry Smith } 3017bbead8a2SBarry Smith break; 3018bbead8a2SBarry Smith case 3: 3019bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3020bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3021bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 302296b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr); 302396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3024bbead8a2SBarry Smith diag += 9; 3025bbead8a2SBarry Smith } 3026bbead8a2SBarry Smith break; 3027bbead8a2SBarry Smith case 4: 3028bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3029bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3030bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 303196b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr); 303296b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3033bbead8a2SBarry Smith diag += 16; 3034bbead8a2SBarry Smith } 3035bbead8a2SBarry Smith break; 3036bbead8a2SBarry Smith case 5: 3037bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3038bbead8a2SBarry 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; 3039bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 304096b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr); 304196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3042bbead8a2SBarry Smith diag += 25; 3043bbead8a2SBarry Smith } 3044bbead8a2SBarry Smith break; 3045bbead8a2SBarry Smith case 6: 3046bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3047bbead8a2SBarry 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; 3048bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 304996b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr); 305096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3051bbead8a2SBarry Smith diag += 36; 3052bbead8a2SBarry Smith } 3053bbead8a2SBarry Smith break; 3054bbead8a2SBarry Smith case 7: 3055bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3056bbead8a2SBarry 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; 3057bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 305896b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr); 305996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3060bbead8a2SBarry Smith diag += 49; 3061bbead8a2SBarry Smith } 3062bbead8a2SBarry Smith break; 3063bbead8a2SBarry Smith default: 3064dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3065bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3066bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3067bbead8a2SBarry Smith IJ[j] = bs*i + j; 3068bbead8a2SBarry Smith } 3069bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 307096b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr); 307196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3072bbead8a2SBarry Smith diag += bs2; 3073bbead8a2SBarry Smith } 3074bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3075bbead8a2SBarry Smith } 3076bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3077bbead8a2SBarry Smith PetscFunctionReturn(0); 3078bbead8a2SBarry Smith } 3079bbead8a2SBarry Smith 308073a71a0fSBarry Smith #undef __FUNCT__ 308173a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ" 308273a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 308373a71a0fSBarry Smith { 308473a71a0fSBarry Smith PetscErrorCode ierr; 308573a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 308673a71a0fSBarry Smith PetscScalar a; 308773a71a0fSBarry Smith PetscInt m,n,i,j,col; 308873a71a0fSBarry Smith 308973a71a0fSBarry Smith PetscFunctionBegin; 309073a71a0fSBarry Smith if (!x->assembled) { 309173a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 309273a71a0fSBarry Smith for (i=0; i<m; i++) { 309373a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 309473a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 309573a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 309673a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 309773a71a0fSBarry Smith } 309873a71a0fSBarry Smith } 309973a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 310073a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 310173a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 310273a71a0fSBarry Smith PetscFunctionReturn(0); 310373a71a0fSBarry Smith } 310473a71a0fSBarry Smith 3105682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 31060a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3107cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3108cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3109cb5b572fSBarry Smith MatMult_SeqAIJ, 311097304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 31117c922b88SBarry Smith MatMultTranspose_SeqAIJ, 31127c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3113db4efbfdSBarry Smith 0, 3114db4efbfdSBarry Smith 0, 3115db4efbfdSBarry Smith 0, 3116db4efbfdSBarry Smith /* 10*/ 0, 3117cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3118cb5b572fSBarry Smith 0, 311941f059aeSBarry Smith MatSOR_SeqAIJ, 312017ab2063SBarry Smith MatTranspose_SeqAIJ, 312197304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3122cb5b572fSBarry Smith MatEqual_SeqAIJ, 3123cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3124cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3125cb5b572fSBarry Smith MatNorm_SeqAIJ, 312697304618SKris Buschelman /* 20*/ 0, 3127cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3128cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3129cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3130d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3131db4efbfdSBarry Smith 0, 3132db4efbfdSBarry Smith 0, 3133db4efbfdSBarry Smith 0, 3134db4efbfdSBarry Smith 0, 31354994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3136db4efbfdSBarry Smith 0, 3137db4efbfdSBarry Smith 0, 31388c778c55SBarry Smith 0, 31398c778c55SBarry Smith 0, 3140d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3141cb5b572fSBarry Smith 0, 3142cb5b572fSBarry Smith 0, 3143cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3144cb5b572fSBarry Smith 0, 3145d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 3146cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3147cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3148cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3149cb5b572fSBarry Smith MatCopy_SeqAIJ, 3150d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3151cb5b572fSBarry Smith MatScale_SeqAIJ, 3152cb5b572fSBarry Smith 0, 315379299369SBarry Smith MatDiagonalSet_SeqAIJ, 31546e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 315573a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 31563b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 31573b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 31583b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3159a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 316093dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3161b9617806SBarry Smith 0, 31620513a670SBarry Smith 0, 3163cda55fadSBarry Smith MatPermute_SeqAIJ, 3164cda55fadSBarry Smith 0, 3165d519adbfSMatthew Knepley /* 59*/ 0, 3166b9b97703SBarry Smith MatDestroy_SeqAIJ, 3167b9b97703SBarry Smith MatView_SeqAIJ, 3168357abbc8SBarry Smith 0, 3169321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3170321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3171321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3172ee4f033dSBarry Smith 0, 3173ee4f033dSBarry Smith 0, 3174ee4f033dSBarry Smith 0, 3175d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3176c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3177ee4f033dSBarry Smith 0, 3178ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 3179dcf5cc72SBarry Smith 0, 3180d519adbfSMatthew Knepley /* 74*/ MatSetValuesAdifor_SeqAIJ, 31813acb8795SBarry Smith MatFDColoringApply_AIJ, 318297304618SKris Buschelman 0, 318397304618SKris Buschelman 0, 318497304618SKris Buschelman 0, 31856ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 318697304618SKris Buschelman 0, 318797304618SKris Buschelman 0, 318897304618SKris Buschelman 0, 3189bc011b1eSHong Zhang MatLoad_SeqAIJ, 3190d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31911cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31926284ec50SHong Zhang 0, 31936284ec50SHong Zhang 0, 3194bc011b1eSHong Zhang 0, 3195d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 319626be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 319726be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 319865e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 31994a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 320065e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 32016fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 32026fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 32036fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 32042121bac1SHong Zhang 0, 32052121bac1SHong Zhang /* 99*/ 0, 3206609c6c4dSKris Buschelman 0, 3207609c6c4dSKris Buschelman 0, 320887d4246cSBarry Smith MatConjugate_SeqAIJ, 320987d4246cSBarry Smith 0, 3210d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 321199cafbc1SBarry Smith MatRealPart_SeqAIJ, 3212f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3213f5edf698SHong Zhang 0, 32142bebee5dSHong Zhang 0, 3215cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3216985db425SBarry Smith 0, 32172af78befSBarry Smith MatGetRowMin_SeqAIJ, 32182af78befSBarry Smith 0, 3219599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3220d519adbfSMatthew Knepley /*114*/ 0, 3221599ef60dSHong Zhang 0, 32223c2a7987SHong Zhang 0, 3223fe97e370SBarry Smith 0, 3224fbdbba38SShri Abhyankar 0, 3225fbdbba38SShri Abhyankar /*119*/ 0, 3226fbdbba38SShri Abhyankar 0, 3227fbdbba38SShri Abhyankar 0, 322882d44351SHong Zhang 0, 3229b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 32300716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3231bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 323237868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 323337868618SMatthew G Knepley 0, 323437868618SMatthew G Knepley 0, 32355df89d91SHong Zhang /*129*/ 0, 323675648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 323775648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 323875648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3239b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3240b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 32412b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 32422b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 32432b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 32443964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 32453964eb88SJed Brown /*139*/0, 3246f9426fe0SMark Adams 0, 32471919a2e2SJed Brown 0, 3248f86b9fbaSHong Zhang MatFDColoringSetUp_SeqXAIJ 32499e29f15eSvictorle }; 325017ab2063SBarry Smith 32514a2ae208SSatish Balay #undef __FUNCT__ 32524a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 32537087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3254bef8e0ddSBarry Smith { 3255bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 325697f1f81fSBarry Smith PetscInt i,nz,n; 3257bef8e0ddSBarry Smith 3258bef8e0ddSBarry Smith PetscFunctionBegin; 3259bef8e0ddSBarry Smith nz = aij->maxnz; 3260d0f46423SBarry Smith n = mat->rmap->n; 3261bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3262bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3263bef8e0ddSBarry Smith } 3264bef8e0ddSBarry Smith aij->nz = nz; 3265bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3266bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3267bef8e0ddSBarry Smith } 3268bef8e0ddSBarry Smith PetscFunctionReturn(0); 3269bef8e0ddSBarry Smith } 3270bef8e0ddSBarry Smith 32714a2ae208SSatish Balay #undef __FUNCT__ 32724a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3273bef8e0ddSBarry Smith /*@ 3274bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3275bef8e0ddSBarry Smith in the matrix. 3276bef8e0ddSBarry Smith 3277bef8e0ddSBarry Smith Input Parameters: 3278bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3279bef8e0ddSBarry Smith - indices - the column indices 3280bef8e0ddSBarry Smith 328115091d37SBarry Smith Level: advanced 328215091d37SBarry Smith 3283bef8e0ddSBarry Smith Notes: 3284bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3285bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3286bef8e0ddSBarry Smith of the MatSetValues() operation. 3287bef8e0ddSBarry Smith 3288bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3289d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3290bef8e0ddSBarry Smith 3291bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3292bef8e0ddSBarry Smith 3293b9617806SBarry Smith The indices should start with zero, not one. 3294b9617806SBarry Smith 3295bef8e0ddSBarry Smith @*/ 32967087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3297bef8e0ddSBarry Smith { 32984ac538c5SBarry Smith PetscErrorCode ierr; 3299bef8e0ddSBarry Smith 3300bef8e0ddSBarry Smith PetscFunctionBegin; 33010700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 33024482741eSBarry Smith PetscValidPointer(indices,2); 33034ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3304bef8e0ddSBarry Smith PetscFunctionReturn(0); 3305bef8e0ddSBarry Smith } 3306bef8e0ddSBarry Smith 3307be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3308be6bf707SBarry Smith 33094a2ae208SSatish Balay #undef __FUNCT__ 33104a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 33117087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3312be6bf707SBarry Smith { 3313be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33146849ba73SBarry Smith PetscErrorCode ierr; 3315d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3316be6bf707SBarry Smith 3317be6bf707SBarry Smith PetscFunctionBegin; 3318f23aa3ddSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3319be6bf707SBarry Smith 3320be6bf707SBarry Smith /* allocate space for values if not already there */ 3321be6bf707SBarry Smith if (!aij->saved_values) { 3322785e854fSJed Brown ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr); 33233bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3324be6bf707SBarry Smith } 3325be6bf707SBarry Smith 3326be6bf707SBarry Smith /* copy values over */ 332787828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3328be6bf707SBarry Smith PetscFunctionReturn(0); 3329be6bf707SBarry Smith } 3330be6bf707SBarry Smith 33314a2ae208SSatish Balay #undef __FUNCT__ 3332b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3333be6bf707SBarry Smith /*@ 3334be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3335be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3336be6bf707SBarry Smith nonlinear portion. 3337be6bf707SBarry Smith 3338be6bf707SBarry Smith Collect on Mat 3339be6bf707SBarry Smith 3340be6bf707SBarry Smith Input Parameters: 33410e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3342be6bf707SBarry Smith 334315091d37SBarry Smith Level: advanced 334415091d37SBarry Smith 3345be6bf707SBarry Smith Common Usage, with SNESSolve(): 3346be6bf707SBarry Smith $ Create Jacobian matrix 3347be6bf707SBarry Smith $ Set linear terms into matrix 3348be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3349be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3350be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3351512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3352be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3353be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3354be6bf707SBarry Smith $ In your Jacobian routine 3355be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3356be6bf707SBarry Smith $ Set nonlinear terms in matrix 3357be6bf707SBarry Smith 3358be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3359be6bf707SBarry Smith $ // build linear portion of Jacobian 3360512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3361be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3362be6bf707SBarry Smith $ loop over nonlinear iterations 3363be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3364be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3365be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3366be6bf707SBarry Smith $ Solve linear system with Jacobian 3367be6bf707SBarry Smith $ endloop 3368be6bf707SBarry Smith 3369be6bf707SBarry Smith Notes: 3370be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3371512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3372be6bf707SBarry Smith calling this routine. 3373be6bf707SBarry Smith 33740c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33750c468ba9SBarry Smith and does not allocated additional space. 33760c468ba9SBarry Smith 3377be6bf707SBarry Smith .seealso: MatRetrieveValues() 3378be6bf707SBarry Smith 3379be6bf707SBarry Smith @*/ 33807087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3381be6bf707SBarry Smith { 33824ac538c5SBarry Smith PetscErrorCode ierr; 3383be6bf707SBarry Smith 3384be6bf707SBarry Smith PetscFunctionBegin; 33850700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3386e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3387e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33884ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3389be6bf707SBarry Smith PetscFunctionReturn(0); 3390be6bf707SBarry Smith } 3391be6bf707SBarry Smith 33924a2ae208SSatish Balay #undef __FUNCT__ 33934a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 33947087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3395be6bf707SBarry Smith { 3396be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33976849ba73SBarry Smith PetscErrorCode ierr; 3398d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3399be6bf707SBarry Smith 3400be6bf707SBarry Smith PetscFunctionBegin; 3401f23aa3ddSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3402f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3403be6bf707SBarry Smith /* copy values over */ 340487828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3405be6bf707SBarry Smith PetscFunctionReturn(0); 3406be6bf707SBarry Smith } 3407be6bf707SBarry Smith 34084a2ae208SSatish Balay #undef __FUNCT__ 34094a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3410be6bf707SBarry Smith /*@ 3411be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3412be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3413be6bf707SBarry Smith nonlinear portion. 3414be6bf707SBarry Smith 3415be6bf707SBarry Smith Collect on Mat 3416be6bf707SBarry Smith 3417be6bf707SBarry Smith Input Parameters: 3418be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3419be6bf707SBarry Smith 342015091d37SBarry Smith Level: advanced 342115091d37SBarry Smith 3422be6bf707SBarry Smith .seealso: MatStoreValues() 3423be6bf707SBarry Smith 3424be6bf707SBarry Smith @*/ 34257087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3426be6bf707SBarry Smith { 34274ac538c5SBarry Smith PetscErrorCode ierr; 3428be6bf707SBarry Smith 3429be6bf707SBarry Smith PetscFunctionBegin; 34300700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3431e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3432e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 34334ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3434be6bf707SBarry Smith PetscFunctionReturn(0); 3435be6bf707SBarry Smith } 3436be6bf707SBarry Smith 3437f83d6046SBarry Smith 3438be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 34394a2ae208SSatish Balay #undef __FUNCT__ 34404a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 344117ab2063SBarry Smith /*@C 3442682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 34430d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 34446e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 344551c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 34462bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 344717ab2063SBarry Smith 3448db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3449db81eaa0SLois Curfman McInnes 345017ab2063SBarry Smith Input Parameters: 3451db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 345217ab2063SBarry Smith . m - number of rows 345317ab2063SBarry Smith . n - number of columns 345417ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 345551c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34560298fd71SBarry Smith (possibly different for each row) or NULL 345717ab2063SBarry Smith 345817ab2063SBarry Smith Output Parameter: 3459416022c9SBarry Smith . A - the matrix 346017ab2063SBarry Smith 3461175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3462ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3463175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3464175b88e8SBarry Smith 3465b259b22eSLois Curfman McInnes Notes: 346649a6f317SBarry Smith If nnz is given then nz is ignored 346749a6f317SBarry Smith 346817ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 346917ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 34700002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 347144cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 347217ab2063SBarry Smith 347317ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34740298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 34753d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 34766da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 347717ab2063SBarry Smith 3478682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 34794fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3480682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34816c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34826c7ebb05SLois Curfman McInnes 34836c7ebb05SLois Curfman McInnes Options Database Keys: 3484698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34859db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 348617ab2063SBarry Smith 3487027ccd11SLois Curfman McInnes Level: intermediate 3488027ccd11SLois Curfman McInnes 348969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 349036db0b34SBarry Smith 349117ab2063SBarry Smith @*/ 34927087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 349317ab2063SBarry Smith { 3494dfbe8321SBarry Smith PetscErrorCode ierr; 34956945ee14SBarry Smith 34963a40ed3dSBarry Smith PetscFunctionBegin; 3497f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3498117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3499c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3500d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3501273d9f13SBarry Smith PetscFunctionReturn(0); 3502273d9f13SBarry Smith } 3503273d9f13SBarry Smith 35044a2ae208SSatish Balay #undef __FUNCT__ 35054a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3506273d9f13SBarry Smith /*@C 3507273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3508273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3509273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3510273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3511273d9f13SBarry Smith 3512273d9f13SBarry Smith Collective on MPI_Comm 3513273d9f13SBarry Smith 3514273d9f13SBarry Smith Input Parameters: 3515117016b1SBarry Smith + B - The matrix-free 3516273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3517273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 35180298fd71SBarry Smith (possibly different for each row) or NULL 3519273d9f13SBarry Smith 3520273d9f13SBarry Smith Notes: 352149a6f317SBarry Smith If nnz is given then nz is ignored 352249a6f317SBarry Smith 3523273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3524273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3525273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3526273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3527273d9f13SBarry Smith 3528273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 35290298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3530273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3531273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3532273d9f13SBarry Smith 3533aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3534aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3535aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3536aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3537aa95bbe8SBarry Smith 3538a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3539a96a251dSBarry Smith entries or columns indices 3540a96a251dSBarry Smith 3541273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3542273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3543273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3544273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3545273d9f13SBarry Smith 3546273d9f13SBarry Smith Options Database Keys: 3547698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3548698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3549273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3550273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3551273d9f13SBarry Smith the user still MUST index entries starting at 0! 3552273d9f13SBarry Smith 3553273d9f13SBarry Smith Level: intermediate 3554273d9f13SBarry Smith 355569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3556273d9f13SBarry Smith 3557273d9f13SBarry Smith @*/ 35587087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3559273d9f13SBarry Smith { 35604ac538c5SBarry Smith PetscErrorCode ierr; 3561a23d5eceSKris Buschelman 3562a23d5eceSKris Buschelman PetscFunctionBegin; 35636ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35646ba663aaSJed Brown PetscValidType(B,1); 35654ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3566a23d5eceSKris Buschelman PetscFunctionReturn(0); 3567a23d5eceSKris Buschelman } 3568a23d5eceSKris Buschelman 3569a23d5eceSKris Buschelman #undef __FUNCT__ 3570a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 35717087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3572a23d5eceSKris Buschelman { 3573273d9f13SBarry Smith Mat_SeqAIJ *b; 35742576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 35756849ba73SBarry Smith PetscErrorCode ierr; 357697f1f81fSBarry Smith PetscInt i; 3577273d9f13SBarry Smith 3578273d9f13SBarry Smith PetscFunctionBegin; 35792576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3580a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3581c461c341SBarry Smith skipallocation = PETSC_TRUE; 3582c461c341SBarry Smith nz = 0; 3583c461c341SBarry Smith } 3584c461c341SBarry Smith 358526283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 358626283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3587899cda47SBarry Smith 3588435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 358960e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3590b73539f3SBarry Smith if (nnz) { 3591d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 359260e0710aSBarry 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]); 359360e0710aSBarry 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); 3594b73539f3SBarry Smith } 3595b73539f3SBarry Smith } 3596b73539f3SBarry Smith 3597273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35982205254eSKarl Rupp 3599273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3600273d9f13SBarry Smith 3601ab93d7beSBarry Smith if (!skipallocation) { 36022ee49352SLisandro Dalcin if (!b->imax) { 3603dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 36043bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 36052ee49352SLisandro Dalcin } 3606273d9f13SBarry Smith if (!nnz) { 3607435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3608c62bd62aSJed Brown else if (nz < 0) nz = 1; 3609d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3610d0f46423SBarry Smith nz = nz*B->rmap->n; 3611273d9f13SBarry Smith } else { 3612273d9f13SBarry Smith nz = 0; 3613d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3614273d9f13SBarry Smith } 3615ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 36162205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3617ab93d7beSBarry Smith 3618273d9f13SBarry Smith /* allocate the matrix space */ 36192ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3620dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 36213bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3622bfeeae90SHong Zhang b->i[0] = 0; 3623d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 36245da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 36255da197adSKris Buschelman } 3626273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3627e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3628e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3629b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 3630b31eba2aSShri Abhyankar ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr); 3631b31eba2aSShri Abhyankar #endif 3632c461c341SBarry Smith } else { 3633e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3634e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3635c461c341SBarry Smith } 3636273d9f13SBarry Smith 3637273d9f13SBarry Smith b->nz = 0; 3638273d9f13SBarry Smith b->maxnz = nz; 3639273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 36402205254eSKarl Rupp if (realalloc) { 36412205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 36422205254eSKarl Rupp } 3643273d9f13SBarry Smith PetscFunctionReturn(0); 3644273d9f13SBarry Smith } 3645273d9f13SBarry Smith 3646a1661176SMatthew Knepley #undef __FUNCT__ 3647a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 364858d36128SBarry Smith /*@ 3649a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3650a1661176SMatthew Knepley 3651a1661176SMatthew Knepley Input Parameters: 3652a1661176SMatthew Knepley + B - the matrix 3653a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3654a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3655a1661176SMatthew Knepley - v - optional values in the matrix 3656a1661176SMatthew Knepley 3657a1661176SMatthew Knepley Level: developer 3658a1661176SMatthew Knepley 365958d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 366058d36128SBarry Smith 3661a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3662a1661176SMatthew Knepley 3663a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3664a1661176SMatthew Knepley @*/ 3665a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3666a1661176SMatthew Knepley { 3667a1661176SMatthew Knepley PetscErrorCode ierr; 3668a1661176SMatthew Knepley 3669a1661176SMatthew Knepley PetscFunctionBegin; 36700700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 36716ba663aaSJed Brown PetscValidType(B,1); 36724ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3673a1661176SMatthew Knepley PetscFunctionReturn(0); 3674a1661176SMatthew Knepley } 3675a1661176SMatthew Knepley 3676a1661176SMatthew Knepley #undef __FUNCT__ 3677a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 36787087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3679a1661176SMatthew Knepley { 3680a1661176SMatthew Knepley PetscInt i; 3681a1661176SMatthew Knepley PetscInt m,n; 3682a1661176SMatthew Knepley PetscInt nz; 3683a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3684a1661176SMatthew Knepley PetscScalar *values; 3685a1661176SMatthew Knepley PetscErrorCode ierr; 3686a1661176SMatthew Knepley 3687a1661176SMatthew Knepley PetscFunctionBegin; 368865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3689779a8d59SSatish Balay 3690779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3691779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3692779a8d59SSatish Balay 3693779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3694785e854fSJed Brown ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr); 3695a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3696b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3697a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 369865e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3699a1661176SMatthew Knepley nnz[i] = nz; 3700a1661176SMatthew Knepley } 3701a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3702a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3703a1661176SMatthew Knepley 3704a1661176SMatthew Knepley if (v) { 3705a1661176SMatthew Knepley values = (PetscScalar*) v; 3706a1661176SMatthew Knepley } else { 37071795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3708a1661176SMatthew Knepley } 3709a1661176SMatthew Knepley 3710a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3711b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3712b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3713a1661176SMatthew Knepley } 3714a1661176SMatthew Knepley 3715a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3716a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3717a1661176SMatthew Knepley 3718a1661176SMatthew Knepley if (!v) { 3719a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3720a1661176SMatthew Knepley } 37217827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3722a1661176SMatthew Knepley PetscFunctionReturn(0); 3723a1661176SMatthew Knepley } 3724a1661176SMatthew Knepley 3725c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 372606873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h> 3727170fe5c8SBarry Smith 3728170fe5c8SBarry Smith #undef __FUNCT__ 3729170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 3730170fe5c8SBarry Smith /* 3731170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3732170fe5c8SBarry Smith 3733170fe5c8SBarry Smith n p p 3734170fe5c8SBarry Smith ( ) ( ) ( ) 3735170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3736170fe5c8SBarry Smith ( ) ( ) ( ) 3737170fe5c8SBarry Smith 3738170fe5c8SBarry Smith */ 3739170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3740170fe5c8SBarry Smith { 3741170fe5c8SBarry Smith PetscErrorCode ierr; 3742170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3743170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3744170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 37451de00fd4SBarry Smith PetscInt i,n,m,q,p; 3746170fe5c8SBarry Smith const PetscInt *ii,*idx; 3747170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3748170fe5c8SBarry Smith PetscScalar *c,*c_q; 3749170fe5c8SBarry Smith 3750170fe5c8SBarry Smith PetscFunctionBegin; 3751d0f46423SBarry Smith m = A->rmap->n; 3752d0f46423SBarry Smith n = A->cmap->n; 3753d0f46423SBarry Smith p = B->cmap->n; 3754170fe5c8SBarry Smith a = sub_a->v; 3755170fe5c8SBarry Smith b = sub_b->a; 3756170fe5c8SBarry Smith c = sub_c->v; 3757170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3758170fe5c8SBarry Smith 3759170fe5c8SBarry Smith ii = sub_b->i; 3760170fe5c8SBarry Smith idx = sub_b->j; 3761170fe5c8SBarry Smith for (i=0; i<n; i++) { 3762170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3763170fe5c8SBarry Smith while (q-->0) { 3764170fe5c8SBarry Smith c_q = c + m*(*idx); 3765170fe5c8SBarry Smith a_q = a + m*i; 3766854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3767170fe5c8SBarry Smith idx++; 3768170fe5c8SBarry Smith b++; 3769170fe5c8SBarry Smith } 3770170fe5c8SBarry Smith } 3771170fe5c8SBarry Smith PetscFunctionReturn(0); 3772170fe5c8SBarry Smith } 3773170fe5c8SBarry Smith 3774170fe5c8SBarry Smith #undef __FUNCT__ 3775170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 3776170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3777170fe5c8SBarry Smith { 3778170fe5c8SBarry Smith PetscErrorCode ierr; 3779d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3780170fe5c8SBarry Smith Mat Cmat; 3781170fe5c8SBarry Smith 3782170fe5c8SBarry Smith PetscFunctionBegin; 378360e0710aSBarry 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); 3784ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3785170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 3786a2f3521dSMark F. Adams ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr); 3787170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 37880298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3789d73949e8SHong Zhang 3790d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 37912205254eSKarl Rupp 3792170fe5c8SBarry Smith *C = Cmat; 3793170fe5c8SBarry Smith PetscFunctionReturn(0); 3794170fe5c8SBarry Smith } 3795170fe5c8SBarry Smith 3796170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3797170fe5c8SBarry Smith #undef __FUNCT__ 3798170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 3799170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3800170fe5c8SBarry Smith { 3801170fe5c8SBarry Smith PetscErrorCode ierr; 3802170fe5c8SBarry Smith 3803170fe5c8SBarry Smith PetscFunctionBegin; 3804170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 38053ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3806170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 38073ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3808170fe5c8SBarry Smith } 38093ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3810170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 38113ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3812170fe5c8SBarry Smith PetscFunctionReturn(0); 3813170fe5c8SBarry Smith } 3814170fe5c8SBarry Smith 3815170fe5c8SBarry Smith 38160bad9183SKris Buschelman /*MC 3817fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 38180bad9183SKris Buschelman based on compressed sparse row format. 38190bad9183SKris Buschelman 38200bad9183SKris Buschelman Options Database Keys: 38210bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 38220bad9183SKris Buschelman 38230bad9183SKris Buschelman Level: beginner 38240bad9183SKris Buschelman 3825f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 38260bad9183SKris Buschelman M*/ 38270bad9183SKris Buschelman 3828ccd284c7SBarry Smith /*MC 3829ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3830ccd284c7SBarry Smith 3831ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3832ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 3833ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 3834ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3835ccd284c7SBarry Smith the above preallocation routines for simplicity. 3836ccd284c7SBarry Smith 3837ccd284c7SBarry Smith Options Database Keys: 3838ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 3839ccd284c7SBarry Smith 3840ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 3841ccd284c7SBarry Smith enough exist. 3842ccd284c7SBarry Smith 3843ccd284c7SBarry Smith Level: beginner 3844ccd284c7SBarry Smith 3845ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 3846ccd284c7SBarry Smith M*/ 3847ccd284c7SBarry Smith 3848ccd284c7SBarry Smith /*MC 3849ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 3850ccd284c7SBarry Smith 3851ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 3852ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 3853ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 3854ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3855ccd284c7SBarry Smith the above preallocation routines for simplicity. 3856ccd284c7SBarry Smith 3857ccd284c7SBarry Smith Options Database Keys: 3858ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 3859ccd284c7SBarry Smith 3860ccd284c7SBarry Smith Level: beginner 3861ccd284c7SBarry Smith 3862ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 3863ccd284c7SBarry Smith M*/ 3864ccd284c7SBarry Smith 3865b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 38668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 3867b5e56a35SBarry Smith #endif 3868ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 38698cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*); 3870af1023dbSSatish Balay #endif 38718cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 38728cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 38738cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 38747087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*); 3875611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 38768cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 3877611f576cSBarry Smith #endif 3878611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 38798cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 3880611f576cSBarry Smith #endif 3881f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 38828cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 3883f3c0ef26SHong Zhang #endif 3884eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 38858cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 3886eb3b5408SSatish Balay #endif 3887586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 38888cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 3889586621ddSJed Brown #endif 3890719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 38918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 3892719d5645SBarry Smith #endif 3893b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 38948cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 38957087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 38967087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3897b3866ffcSBarry Smith #endif 389817f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE) 38998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*); 390017f1a0eaSHong Zhang #endif 390117667f90SBarry Smith 3902c0c8ee5eSDmitry Karpeev 39038c778c55SBarry Smith #undef __FUNCT__ 39048c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray" 39058c778c55SBarry Smith /*@C 39068c778c55SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored 39078c778c55SBarry Smith 39088c778c55SBarry Smith Not Collective 39098c778c55SBarry Smith 39108c778c55SBarry Smith Input Parameter: 39118c778c55SBarry Smith . mat - a MATSEQDENSE matrix 39128c778c55SBarry Smith 39138c778c55SBarry Smith Output Parameter: 39148c778c55SBarry Smith . array - pointer to the data 39158c778c55SBarry Smith 39168c778c55SBarry Smith Level: intermediate 39178c778c55SBarry Smith 3918774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 39198c778c55SBarry Smith @*/ 39208c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 39218c778c55SBarry Smith { 39228c778c55SBarry Smith PetscErrorCode ierr; 39238c778c55SBarry Smith 39248c778c55SBarry Smith PetscFunctionBegin; 39258c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 39268c778c55SBarry Smith PetscFunctionReturn(0); 39278c778c55SBarry Smith } 39288c778c55SBarry Smith 39298c778c55SBarry Smith #undef __FUNCT__ 39308c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray" 39318c778c55SBarry Smith /*@C 39328c778c55SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray() 39338c778c55SBarry Smith 39348c778c55SBarry Smith Not Collective 39358c778c55SBarry Smith 39368c778c55SBarry Smith Input Parameters: 39378c778c55SBarry Smith . mat - a MATSEQDENSE matrix 39388c778c55SBarry Smith . array - pointer to the data 39398c778c55SBarry Smith 39408c778c55SBarry Smith Level: intermediate 39418c778c55SBarry Smith 3942774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 39438c778c55SBarry Smith @*/ 39448c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 39458c778c55SBarry Smith { 39468c778c55SBarry Smith PetscErrorCode ierr; 39478c778c55SBarry Smith 39488c778c55SBarry Smith PetscFunctionBegin; 39498c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 39508c778c55SBarry Smith PetscFunctionReturn(0); 39518c778c55SBarry Smith } 39528c778c55SBarry Smith 39534a2ae208SSatish Balay #undef __FUNCT__ 39544a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 39558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 3956273d9f13SBarry Smith { 3957273d9f13SBarry Smith Mat_SeqAIJ *b; 3958dfbe8321SBarry Smith PetscErrorCode ierr; 395938baddfdSBarry Smith PetscMPIInt size; 3960273d9f13SBarry Smith 3961273d9f13SBarry Smith PetscFunctionBegin; 3962ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 3963e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3964273d9f13SBarry Smith 3965b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 39662205254eSKarl Rupp 3967b0a32e0cSBarry Smith B->data = (void*)b; 39682205254eSKarl Rupp 3969549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 39702205254eSKarl Rupp 3971416022c9SBarry Smith b->row = 0; 3972416022c9SBarry Smith b->col = 0; 397382bf6240SBarry Smith b->icol = 0; 3974b810aeb4SBarry Smith b->reallocs = 0; 397536db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3976f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3977416022c9SBarry Smith b->nonew = 0; 3978416022c9SBarry Smith b->diag = 0; 3979416022c9SBarry Smith b->solve_work = 0; 39802a1b7f2aSHong Zhang B->spptr = 0; 3981be6bf707SBarry Smith b->saved_values = 0; 3982d7f994e1SBarry Smith b->idiag = 0; 398371f1c65dSBarry Smith b->mdiag = 0; 398471f1c65dSBarry Smith b->ssor_work = 0; 398571f1c65dSBarry Smith b->omega = 1.0; 398671f1c65dSBarry Smith b->fshift = 0.0; 398771f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3988bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3989a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 3990a30b2313SHong Zhang b->xtoy = 0; 3991a30b2313SHong Zhang b->XtoY = 0; 399288e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 399317ab2063SBarry Smith 399435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3995bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 3996bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 39978c778c55SBarry Smith 3998b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3999bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 4000bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4001bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4002b3866ffcSBarry Smith #endif 4003b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 4004bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 4005b5e56a35SBarry Smith #endif 4006ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 4007bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 4008719d5645SBarry Smith #endif 4009611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 4010bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 4011611f576cSBarry Smith #endif 4012f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 4013bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 4014f3c0ef26SHong Zhang #endif 4015611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 4016bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr); 4017611f576cSBarry Smith #endif 4018eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 4019bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 4020eb3b5408SSatish Balay #endif 4021586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 4022bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 4023586621ddSJed Brown #endif 4024719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 4025bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 4026719d5645SBarry Smith #endif 402717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE) 4028bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr); 402917f1a0eaSHong Zhang #endif 403017f1a0eaSHong Zhang 4031bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 4032bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 4033bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 4034bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4035bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4036bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4037bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4038bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4039bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 4040bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4041bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4042bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4043bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4044bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4045bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 4046bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 4047bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 4048bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 40494108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 405017667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 40513a40ed3dSBarry Smith PetscFunctionReturn(0); 405217ab2063SBarry Smith } 405317ab2063SBarry Smith 40544a2ae208SSatish Balay #undef __FUNCT__ 4055b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 4056b24902e0SBarry Smith /* 4057b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4058b24902e0SBarry Smith */ 4059ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 406017ab2063SBarry Smith { 4061416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 40626849ba73SBarry Smith PetscErrorCode ierr; 4063d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 406417ab2063SBarry Smith 40653a40ed3dSBarry Smith PetscFunctionBegin; 4066273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 4067273d9f13SBarry Smith 4068d5f3da31SBarry Smith C->factortype = A->factortype; 4069416022c9SBarry Smith c->row = 0; 4070416022c9SBarry Smith c->col = 0; 407182bf6240SBarry Smith c->icol = 0; 40726ad4291fSHong Zhang c->reallocs = 0; 407317ab2063SBarry Smith 40746ad4291fSHong Zhang C->assembled = PETSC_TRUE; 407517ab2063SBarry Smith 4076aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4077aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4078eec197d1SBarry Smith 4079dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 40803bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 408117ab2063SBarry Smith for (i=0; i<m; i++) { 4082416022c9SBarry Smith c->imax[i] = a->imax[i]; 4083416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 408417ab2063SBarry Smith } 408517ab2063SBarry Smith 408617ab2063SBarry Smith /* allocate the matrix space */ 4087f77e22a1SHong Zhang if (mallocmatspace) { 4088dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 40893bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 40902205254eSKarl Rupp 4091f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 40922205254eSKarl Rupp 409397f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 409417ab2063SBarry Smith if (m > 0) { 409597f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 4096be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4097bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 4098be6bf707SBarry Smith } else { 4099bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 410017ab2063SBarry Smith } 410108480c60SBarry Smith } 4102f77e22a1SHong Zhang } 410317ab2063SBarry Smith 41046ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4105416022c9SBarry Smith c->roworiented = a->roworiented; 4106416022c9SBarry Smith c->nonew = a->nonew; 4107416022c9SBarry Smith if (a->diag) { 4108785e854fSJed Brown ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr); 41093bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 411017ab2063SBarry Smith for (i=0; i<m; i++) { 4111416022c9SBarry Smith c->diag[i] = a->diag[i]; 411217ab2063SBarry Smith } 41133a40ed3dSBarry Smith } else c->diag = 0; 41142205254eSKarl Rupp 41156ad4291fSHong Zhang c->solve_work = 0; 41166ad4291fSHong Zhang c->saved_values = 0; 41176ad4291fSHong Zhang c->idiag = 0; 411871f1c65dSBarry Smith c->ssor_work = 0; 4119a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4120e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4121e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 41226ad4291fSHong Zhang c->xtoy = 0; 41236ad4291fSHong Zhang c->XtoY = 0; 41246ad4291fSHong Zhang 4125893ad86cSHong Zhang c->rmax = a->rmax; 4126416022c9SBarry Smith c->nz = a->nz; 41278ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4128273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4129754ec7b1SSatish Balay 41306ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 41316ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4132cd6b891eSBarry Smith if (a->compressedrow.use) { 41336ad4291fSHong Zhang i = a->compressedrow.nrows; 4134dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 41356ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 41366ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 413727ea64f8SHong Zhang } else { 413827ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 41390298fd71SBarry Smith c->compressedrow.i = NULL; 41400298fd71SBarry Smith c->compressedrow.rindex = NULL; 41416ad4291fSHong Zhang } 414288e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 41434846f1f5SKris Buschelman 41442205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4145140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 41463a40ed3dSBarry Smith PetscFunctionReturn(0); 414717ab2063SBarry Smith } 414817ab2063SBarry Smith 41494a2ae208SSatish Balay #undef __FUNCT__ 4150b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 4151b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4152b24902e0SBarry Smith { 4153b24902e0SBarry Smith PetscErrorCode ierr; 4154b24902e0SBarry Smith 4155b24902e0SBarry Smith PetscFunctionBegin; 4156ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 41574b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4158a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 4159a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4160f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4161b24902e0SBarry Smith PetscFunctionReturn(0); 4162b24902e0SBarry Smith } 4163b24902e0SBarry Smith 4164b24902e0SBarry Smith #undef __FUNCT__ 41654a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 4166112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4167fbdbba38SShri Abhyankar { 4168fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4169fbdbba38SShri Abhyankar PetscErrorCode ierr; 4170fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4171fbdbba38SShri Abhyankar int fd; 4172fbdbba38SShri Abhyankar PetscMPIInt size; 4173fbdbba38SShri Abhyankar MPI_Comm comm; 4174bbead8a2SBarry Smith PetscInt bs = 1; 4175fbdbba38SShri Abhyankar 4176fbdbba38SShri Abhyankar PetscFunctionBegin; 4177fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4178fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4179fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4180bbead8a2SBarry Smith 41810298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 41820298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4183bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 41841814747fSJed Brown if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);} 4185bbead8a2SBarry Smith 4186fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4187fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4188fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4189fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4190fbdbba38SShri Abhyankar 4191bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4192fbdbba38SShri Abhyankar 4193fbdbba38SShri Abhyankar /* read in row lengths */ 4194785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4195fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4196fbdbba38SShri Abhyankar 4197fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4198fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 419960e0710aSBarry 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); 4200fbdbba38SShri Abhyankar 4201fbdbba38SShri Abhyankar /* set global size if not set already*/ 4202f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4203fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4204aabbc4fbSShri Abhyankar } else { 4205fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 4206fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 42074c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 42084c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 42094c5b953cSHong Zhang } 421060e0710aSBarry 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); 4211aabbc4fbSShri Abhyankar } 4212fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4213fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4214fbdbba38SShri Abhyankar 4215fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4216fbdbba38SShri Abhyankar 4217fbdbba38SShri Abhyankar /* read in nonzero values */ 4218fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4219fbdbba38SShri Abhyankar 4220fbdbba38SShri Abhyankar /* set matrix "i" values */ 4221fbdbba38SShri Abhyankar a->i[0] = 0; 4222fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4223fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4224fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4225fbdbba38SShri Abhyankar } 4226fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4227fbdbba38SShri Abhyankar 4228fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4229fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4230fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4231fbdbba38SShri Abhyankar } 4232fbdbba38SShri Abhyankar 4233fbdbba38SShri Abhyankar #undef __FUNCT__ 4234b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 4235ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 42367264ac53SSatish Balay { 42377264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4238dfbe8321SBarry Smith PetscErrorCode ierr; 4239eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4240eeffb40dSHong Zhang PetscInt k; 4241eeffb40dSHong Zhang #endif 42427264ac53SSatish Balay 42433a40ed3dSBarry Smith PetscFunctionBegin; 4244bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4245d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4246ca44d042SBarry Smith *flg = PETSC_FALSE; 4247ca44d042SBarry Smith PetscFunctionReturn(0); 4248bcd2baecSBarry Smith } 42497264ac53SSatish Balay 42507264ac53SSatish Balay /* if the a->i are the same */ 4251d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4252abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 42537264ac53SSatish Balay 42547264ac53SSatish Balay /* if a->j are the same */ 425597f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4256abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4257bcd2baecSBarry Smith 4258bcd2baecSBarry Smith /* if a->a are the same */ 4259eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4260eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4261eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4262eeffb40dSHong Zhang *flg = PETSC_FALSE; 42633a40ed3dSBarry Smith PetscFunctionReturn(0); 4264eeffb40dSHong Zhang } 4265eeffb40dSHong Zhang } 4266eeffb40dSHong Zhang #else 4267eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4268eeffb40dSHong Zhang #endif 4269eeffb40dSHong Zhang PetscFunctionReturn(0); 42707264ac53SSatish Balay } 427136db0b34SBarry Smith 42724a2ae208SSatish Balay #undef __FUNCT__ 42734a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 427405869f15SSatish Balay /*@ 427536db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 427636db0b34SBarry Smith provided by the user. 427736db0b34SBarry Smith 4278c75a6043SHong Zhang Collective on MPI_Comm 427936db0b34SBarry Smith 428036db0b34SBarry Smith Input Parameters: 428136db0b34SBarry Smith + comm - must be an MPI communicator of size 1 428236db0b34SBarry Smith . m - number of rows 428336db0b34SBarry Smith . n - number of columns 428436db0b34SBarry Smith . i - row indices 428536db0b34SBarry Smith . j - column indices 428636db0b34SBarry Smith - a - matrix values 428736db0b34SBarry Smith 428836db0b34SBarry Smith Output Parameter: 428936db0b34SBarry Smith . mat - the matrix 429036db0b34SBarry Smith 429136db0b34SBarry Smith Level: intermediate 429236db0b34SBarry Smith 429336db0b34SBarry Smith Notes: 42940551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4295292fb18eSBarry Smith once the matrix is destroyed and not before 429636db0b34SBarry Smith 429736db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 429836db0b34SBarry Smith 4299bfeeae90SHong Zhang The i and j indices are 0 based 430036db0b34SBarry Smith 4301a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4302a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4303a4552177SSatish Balay as shown: 4304a4552177SSatish Balay 4305a4552177SSatish Balay 1 0 0 4306a4552177SSatish Balay 2 0 3 4307a4552177SSatish Balay 4 5 6 4308a4552177SSatish Balay 4309a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 43109985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4311a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4312a4552177SSatish Balay 43139985e31cSBarry Smith 431469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 431536db0b34SBarry Smith 431636db0b34SBarry Smith @*/ 43177087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat) 431836db0b34SBarry Smith { 4319dfbe8321SBarry Smith PetscErrorCode ierr; 4320cbcfb4deSHong Zhang PetscInt ii; 432136db0b34SBarry Smith Mat_SeqAIJ *aij; 4322cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4323cbcfb4deSHong Zhang PetscInt jj; 4324cbcfb4deSHong Zhang #endif 432536db0b34SBarry Smith 432636db0b34SBarry Smith PetscFunctionBegin; 4327f23aa3ddSBarry Smith if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4328f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4329f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4330a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4331ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4332ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4333ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4334dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4335ab93d7beSBarry Smith 433636db0b34SBarry Smith aij->i = i; 433736db0b34SBarry Smith aij->j = j; 433836db0b34SBarry Smith aij->a = a; 433936db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 434036db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4341e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4342e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 434336db0b34SBarry Smith 434436db0b34SBarry Smith for (ii=0; ii<m; ii++) { 434536db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 43462515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 434760e0710aSBarry 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]); 43489985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4349e32f2f54SBarry 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); 4350e32f2f54SBarry 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); 43519985e31cSBarry Smith } 435236db0b34SBarry Smith #endif 435336db0b34SBarry Smith } 43542515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 435536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 435660e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 435760e0710aSBarry 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]); 435836db0b34SBarry Smith } 435936db0b34SBarry Smith #endif 436036db0b34SBarry Smith 4361b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4362b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 436336db0b34SBarry Smith PetscFunctionReturn(0); 436436db0b34SBarry Smith } 43658a0b0e6bSVictor Minden #undef __FUNCT__ 43668a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple" 436780ef6e79SMatthew G Knepley /*@C 4368d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 43698a0b0e6bSVictor Minden provided by the user. 43708a0b0e6bSVictor Minden 43718a0b0e6bSVictor Minden Collective on MPI_Comm 43728a0b0e6bSVictor Minden 43738a0b0e6bSVictor Minden Input Parameters: 43748a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 43758a0b0e6bSVictor Minden . m - number of rows 43768a0b0e6bSVictor Minden . n - number of columns 43778a0b0e6bSVictor Minden . i - row indices 43788a0b0e6bSVictor Minden . j - column indices 43791230e6d1SVictor Minden . a - matrix values 43801230e6d1SVictor Minden . nz - number of nonzeros 43811230e6d1SVictor Minden - idx - 0 or 1 based 43828a0b0e6bSVictor Minden 43838a0b0e6bSVictor Minden Output Parameter: 43848a0b0e6bSVictor Minden . mat - the matrix 43858a0b0e6bSVictor Minden 43868a0b0e6bSVictor Minden Level: intermediate 43878a0b0e6bSVictor Minden 43888a0b0e6bSVictor Minden Notes: 43898a0b0e6bSVictor Minden The i and j indices are 0 based 43908a0b0e6bSVictor Minden 43918a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 43928a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 43938a0b0e6bSVictor Minden as shown: 43948a0b0e6bSVictor Minden 43958a0b0e6bSVictor Minden 1 0 0 43968a0b0e6bSVictor Minden 2 0 3 43978a0b0e6bSVictor Minden 4 5 6 43988a0b0e6bSVictor Minden 43998a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 44008a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 44018a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 44028a0b0e6bSVictor Minden 44038a0b0e6bSVictor Minden 440469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 44058a0b0e6bSVictor Minden 44068a0b0e6bSVictor Minden @*/ 44071230e6d1SVictor Minden PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx) 44088a0b0e6bSVictor Minden { 44098a0b0e6bSVictor Minden PetscErrorCode ierr; 4410d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 44118a0b0e6bSVictor Minden 44128a0b0e6bSVictor Minden 44138a0b0e6bSVictor Minden PetscFunctionBegin; 44141795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 44151230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4416c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 44171230e6d1SVictor Minden } 44188a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 44198a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 44208a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 44211230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 44221230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 44231230e6d1SVictor Minden if (idx) { 44241230e6d1SVictor Minden row = i[ii] - 1; 44251230e6d1SVictor Minden col = j[ii] - 1; 44261230e6d1SVictor Minden } else { 44271230e6d1SVictor Minden row = i[ii]; 44281230e6d1SVictor Minden col = j[ii]; 44298a0b0e6bSVictor Minden } 44301230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 44318a0b0e6bSVictor Minden } 44328a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 44338a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4434d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 44358a0b0e6bSVictor Minden PetscFunctionReturn(0); 44368a0b0e6bSVictor Minden } 443736db0b34SBarry Smith 4438cc8ba8e1SBarry Smith #undef __FUNCT__ 4439ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4440dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4441cc8ba8e1SBarry Smith { 4442dfbe8321SBarry Smith PetscErrorCode ierr; 4443cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 444436db0b34SBarry Smith 4445cc8ba8e1SBarry Smith PetscFunctionBegin; 44468ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4447cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4448cc8ba8e1SBarry Smith a->coloring = coloring; 444912c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 445097f1f81fSBarry Smith PetscInt i,*larray; 445112c595b3SBarry Smith ISColoring ocoloring; 445208b6dcc0SBarry Smith ISColoringValue *colors; 445312c595b3SBarry Smith 445412c595b3SBarry Smith /* set coloring for diagonal portion */ 4455785e854fSJed Brown ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr); 44562205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) larray[i] = i; 44570298fd71SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr); 4458785e854fSJed Brown ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr); 44592205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]]; 446012c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4461d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 446212c595b3SBarry Smith a->coloring = ocoloring; 446312c595b3SBarry Smith } 4464cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4465cc8ba8e1SBarry Smith } 4466cc8ba8e1SBarry Smith 4467ee4f033dSBarry Smith #undef __FUNCT__ 4468ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 446997f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4470ee4f033dSBarry Smith { 4471ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4472d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 447354f21887SBarry Smith MatScalar *v = a->a; 447454f21887SBarry Smith PetscScalar *values = (PetscScalar*)advalues; 447508b6dcc0SBarry Smith ISColoringValue *color; 4476ee4f033dSBarry Smith 4477ee4f033dSBarry Smith PetscFunctionBegin; 4478e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4479ee4f033dSBarry Smith color = a->coloring->colors; 4480ee4f033dSBarry Smith /* loop over rows */ 4481ee4f033dSBarry Smith for (i=0; i<m; i++) { 4482ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4483ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 44842205254eSKarl Rupp for (j=0; j<nz; j++) *v++ = values[color[*jj++]]; 4485ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4486cc8ba8e1SBarry Smith } 4487cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4488cc8ba8e1SBarry Smith } 448936db0b34SBarry Smith 4490acf2f550SJed Brown #undef __FUNCT__ 4491acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal" 4492acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4493acf2f550SJed Brown { 4494acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4495acf2f550SJed Brown PetscErrorCode ierr; 4496acf2f550SJed Brown 4497acf2f550SJed Brown PetscFunctionBegin; 4498acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4499acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 45002205254eSKarl Rupp 4501acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4502acf2f550SJed Brown PetscFunctionReturn(0); 4503acf2f550SJed Brown } 4504acf2f550SJed Brown 450581824310SBarry Smith /* 450681824310SBarry Smith Special version for direct calls from Fortran 450781824310SBarry Smith */ 4508b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h> 450981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 451081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 451181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 451281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 451381824310SBarry Smith #endif 451481824310SBarry Smith 451581824310SBarry Smith /* Change these macros so can be used in void function */ 451681824310SBarry Smith #undef CHKERRQ 4517ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 451881824310SBarry Smith #undef SETERRQ2 4519e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 45204994cf47SJed Brown #undef SETERRQ3 45214994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 452281824310SBarry Smith 452381824310SBarry Smith #undef __FUNCT__ 452481824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 45258cc058d9SJed 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) 452681824310SBarry Smith { 452781824310SBarry Smith Mat A = *AA; 452881824310SBarry Smith PetscInt m = *mm, n = *nn; 452981824310SBarry Smith InsertMode is = *isis; 453081824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 453181824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 453281824310SBarry Smith PetscInt *imax,*ai,*ailen; 453381824310SBarry Smith PetscErrorCode ierr; 453481824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 453554f21887SBarry Smith MatScalar *ap,value,*aa; 4536ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4537ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 453881824310SBarry Smith 453981824310SBarry Smith PetscFunctionBegin; 45404994cf47SJed Brown MatCheckPreallocated(A,1); 454181824310SBarry Smith imax = a->imax; 454281824310SBarry Smith ai = a->i; 454381824310SBarry Smith ailen = a->ilen; 454481824310SBarry Smith aj = a->j; 454581824310SBarry Smith aa = a->a; 454681824310SBarry Smith 454781824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 454881824310SBarry Smith row = im[k]; 454981824310SBarry Smith if (row < 0) continue; 455081824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4551ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 455281824310SBarry Smith #endif 455381824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 455481824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 455581824310SBarry Smith low = 0; 455681824310SBarry Smith high = nrow; 455781824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 455881824310SBarry Smith if (in[l] < 0) continue; 455981824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4560ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 456181824310SBarry Smith #endif 456281824310SBarry Smith col = in[l]; 45632205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 45642205254eSKarl Rupp else value = v[k + l*m]; 45652205254eSKarl Rupp 456681824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 456781824310SBarry Smith 45682205254eSKarl Rupp if (col <= lastcol) low = 0; 45692205254eSKarl Rupp else high = nrow; 457081824310SBarry Smith lastcol = col; 457181824310SBarry Smith while (high-low > 5) { 457281824310SBarry Smith t = (low+high)/2; 457381824310SBarry Smith if (rp[t] > col) high = t; 457481824310SBarry Smith else low = t; 457581824310SBarry Smith } 457681824310SBarry Smith for (i=low; i<high; i++) { 457781824310SBarry Smith if (rp[i] > col) break; 457881824310SBarry Smith if (rp[i] == col) { 457981824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 458081824310SBarry Smith else ap[i] = value; 458181824310SBarry Smith goto noinsert; 458281824310SBarry Smith } 458381824310SBarry Smith } 458481824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 458581824310SBarry Smith if (nonew == 1) goto noinsert; 4586ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4587fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 458881824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 458981824310SBarry Smith /* shift up all the later entries in this row */ 459081824310SBarry Smith for (ii=N; ii>=i; ii--) { 459181824310SBarry Smith rp[ii+1] = rp[ii]; 459281824310SBarry Smith ap[ii+1] = ap[ii]; 459381824310SBarry Smith } 459481824310SBarry Smith rp[i] = col; 459581824310SBarry Smith ap[i] = value; 459681824310SBarry Smith noinsert:; 459781824310SBarry Smith low = i + 1; 459881824310SBarry Smith } 459981824310SBarry Smith ailen[row] = nrow; 460081824310SBarry Smith } 460181824310SBarry Smith A->same_nonzero = PETSC_FALSE; 460281824310SBarry Smith PetscFunctionReturnVoid(); 460381824310SBarry Smith } 46049f7953f8SBarry Smith 460562298a1eSBarry Smith 4606