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 } 666ce1633cSBarry Smith ierr = PetscMalloc(cnt*sizeof(PetscInt),&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); 120b3a44c85SBarry Smith ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&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 */ 1901a83f524SJed Brown ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),&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; 1951a83f524SJed Brown ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&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 { 23697f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 23797f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 23897f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 23997f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 2403b2fbd54SBarry Smith jj = a->j; 2413b2fbd54SBarry Smith for (i=0; i<nz; i++) { 242bfeeae90SHong Zhang collengths[jj[i]]++; 2433b2fbd54SBarry Smith } 2443b2fbd54SBarry Smith cia[0] = oshift; 2453b2fbd54SBarry Smith for (i=0; i<n; i++) { 2463b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2473b2fbd54SBarry Smith } 24897f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2493b2fbd54SBarry Smith jj = a->j; 250a93ec695SBarry Smith for (row=0; row<m; row++) { 251a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 252a93ec695SBarry Smith for (i=0; i<mr; i++) { 253bfeeae90SHong Zhang col = *jj++; 2542205254eSKarl Rupp 2553b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2563b2fbd54SBarry Smith } 2573b2fbd54SBarry Smith } 258606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2593b2fbd54SBarry Smith *ia = cia; *ja = cja; 2603b2fbd54SBarry Smith } 2613a40ed3dSBarry Smith PetscFunctionReturn(0); 2623b2fbd54SBarry Smith } 2633b2fbd54SBarry Smith 2644a2ae208SSatish Balay #undef __FUNCT__ 2654a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 2661a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2673b2fbd54SBarry Smith { 268dfbe8321SBarry Smith PetscErrorCode ierr; 269606d414cSSatish Balay 2703a40ed3dSBarry Smith PetscFunctionBegin; 2713a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2723b2fbd54SBarry Smith 273606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 274606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2753a40ed3dSBarry Smith PetscFunctionReturn(0); 2763b2fbd54SBarry Smith } 2773b2fbd54SBarry Smith 2787cee066cSHong Zhang /* 2797cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 2807cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 2817cee066cSHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqAIJ() 2827cee066cSHong Zhang */ 2837cee066cSHong Zhang #undef __FUNCT__ 2847cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color" 2857cee066cSHong 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) 2867cee066cSHong Zhang { 2877cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2887cee066cSHong Zhang PetscErrorCode ierr; 2897cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 2907cee066cSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 2917cee066cSHong Zhang PetscInt *cspidx; 2927cee066cSHong Zhang 2937cee066cSHong Zhang PetscFunctionBegin; 2947cee066cSHong Zhang *nn = n; 2957cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 2967cee066cSHong Zhang if (symmetric) { 2977cee066cSHong Zhang SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatGetColumnIJ_SeqAIJ_Color() not supported for the case symmetric"); 2987cee066cSHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2997cee066cSHong Zhang } else { 3007cee066cSHong Zhang ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 3017cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 3027cee066cSHong Zhang ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 3037cee066cSHong Zhang ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 3047cee066cSHong Zhang ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cspidx);CHKERRQ(ierr); 3057cee066cSHong Zhang jj = a->j; 3067cee066cSHong Zhang for (i=0; i<nz; i++) { 3077cee066cSHong Zhang collengths[jj[i]]++; 3087cee066cSHong Zhang } 3097cee066cSHong Zhang cia[0] = oshift; 3107cee066cSHong Zhang for (i=0; i<n; i++) { 3117cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3127cee066cSHong Zhang } 3137cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 3147cee066cSHong Zhang jj = a->j; 3157cee066cSHong Zhang for (row=0; row<m; row++) { 3167cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3177cee066cSHong Zhang for (i=0; i<mr; i++) { 3187cee066cSHong Zhang col = *jj++; 3197cee066cSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 3207cee066cSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 3217cee066cSHong Zhang } 3227cee066cSHong Zhang } 3237cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 3247cee066cSHong Zhang *ia = cia; *ja = cja; 3257cee066cSHong Zhang *spidx = cspidx; 3267cee066cSHong Zhang } 3277cee066cSHong Zhang PetscFunctionReturn(0); 3287cee066cSHong Zhang } 3297cee066cSHong Zhang 3307cee066cSHong Zhang #undef __FUNCT__ 3317cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color" 3327cee066cSHong 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) 3337cee066cSHong Zhang { 3347cee066cSHong Zhang PetscErrorCode ierr; 3357cee066cSHong Zhang 3367cee066cSHong Zhang PetscFunctionBegin; 337*5243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3387cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3397cee066cSHong Zhang PetscFunctionReturn(0); 3407cee066cSHong Zhang } 3417cee066cSHong Zhang 34287d4246cSBarry Smith #undef __FUNCT__ 34387d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 34487d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 34587d4246cSBarry Smith { 34687d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 34787d4246cSBarry Smith PetscInt *ai = a->i; 34887d4246cSBarry Smith PetscErrorCode ierr; 34987d4246cSBarry Smith 35087d4246cSBarry Smith PetscFunctionBegin; 35187d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 35287d4246cSBarry Smith PetscFunctionReturn(0); 35387d4246cSBarry Smith } 35487d4246cSBarry Smith 3554a2ae208SSatish Balay #undef __FUNCT__ 3564a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 35797f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 35817ab2063SBarry Smith { 359416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 360e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 36197f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 3626849ba73SBarry Smith PetscErrorCode ierr; 363e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 36454f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 365ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 366ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 36717ab2063SBarry Smith 3683a40ed3dSBarry Smith PetscFunctionBegin; 36971fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 37017ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 371416022c9SBarry Smith row = im[k]; 3725ef9f2a5SBarry Smith if (row < 0) continue; 3732515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 374e32f2f54SBarry 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); 3753b2fbd54SBarry Smith #endif 376bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 37717ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 378416022c9SBarry Smith low = 0; 379c71e6ed7SBarry Smith high = nrow; 38017ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 3815ef9f2a5SBarry Smith if (in[l] < 0) continue; 3822515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 383e32f2f54SBarry 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); 3843b2fbd54SBarry Smith #endif 385bfeeae90SHong Zhang col = in[l]; 38616371a99SBarry Smith if (v) { 3874b0e389bSBarry Smith if (roworiented) { 3885ef9f2a5SBarry Smith value = v[l + k*n]; 389bef8e0ddSBarry Smith } else { 3904b0e389bSBarry Smith value = v[k + l*m]; 3914b0e389bSBarry Smith } 39216371a99SBarry Smith } else { 39375567043SBarry Smith value = 0.; 39416371a99SBarry Smith } 395abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 39636db0b34SBarry Smith 3972205254eSKarl Rupp if (col <= lastcol) low = 0; 3982205254eSKarl Rupp else high = nrow; 399e2ee6c50SBarry Smith lastcol = col; 400416022c9SBarry Smith while (high-low > 5) { 401416022c9SBarry Smith t = (low+high)/2; 402416022c9SBarry Smith if (rp[t] > col) high = t; 403416022c9SBarry Smith else low = t; 40417ab2063SBarry Smith } 405416022c9SBarry Smith for (i=low; i<high; i++) { 40617ab2063SBarry Smith if (rp[i] > col) break; 40717ab2063SBarry Smith if (rp[i] == col) { 408416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 40917ab2063SBarry Smith else ap[i] = value; 410e44c0bd4SBarry Smith low = i + 1; 41117ab2063SBarry Smith goto noinsert; 41217ab2063SBarry Smith } 41317ab2063SBarry Smith } 414abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 415c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 416e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 417fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 418c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 419416022c9SBarry Smith /* shift up all the later entries in this row */ 420416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 42117ab2063SBarry Smith rp[ii+1] = rp[ii]; 42217ab2063SBarry Smith ap[ii+1] = ap[ii]; 42317ab2063SBarry Smith } 42417ab2063SBarry Smith rp[i] = col; 42517ab2063SBarry Smith ap[i] = value; 426416022c9SBarry Smith low = i + 1; 427e44c0bd4SBarry Smith noinsert:; 42817ab2063SBarry Smith } 42917ab2063SBarry Smith ailen[row] = nrow; 43017ab2063SBarry Smith } 43188e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 4323a40ed3dSBarry Smith PetscFunctionReturn(0); 43317ab2063SBarry Smith } 43417ab2063SBarry Smith 43581824310SBarry Smith 4364a2ae208SSatish Balay #undef __FUNCT__ 4374a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 438a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4397eb43aa7SLois Curfman McInnes { 4407eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 44197f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 44297f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 44354f21887SBarry Smith MatScalar *ap,*aa = a->a; 4447eb43aa7SLois Curfman McInnes 4453a40ed3dSBarry Smith PetscFunctionBegin; 4467eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 4477eb43aa7SLois Curfman McInnes row = im[k]; 448e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 449e32f2f54SBarry 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); 450bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 4517eb43aa7SLois Curfman McInnes nrow = ailen[row]; 4527eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 453e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 454e32f2f54SBarry 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); 455bfeeae90SHong Zhang col = in[l]; 4567eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 4577eb43aa7SLois Curfman McInnes while (high-low > 5) { 4587eb43aa7SLois Curfman McInnes t = (low+high)/2; 4597eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 4607eb43aa7SLois Curfman McInnes else low = t; 4617eb43aa7SLois Curfman McInnes } 4627eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 4637eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 4647eb43aa7SLois Curfman McInnes if (rp[i] == col) { 465b49de8d1SLois Curfman McInnes *v++ = ap[i]; 4667eb43aa7SLois Curfman McInnes goto finished; 4677eb43aa7SLois Curfman McInnes } 4687eb43aa7SLois Curfman McInnes } 46997e567efSBarry Smith *v++ = 0.0; 4707eb43aa7SLois Curfman McInnes finished:; 4717eb43aa7SLois Curfman McInnes } 4727eb43aa7SLois Curfman McInnes } 4733a40ed3dSBarry Smith PetscFunctionReturn(0); 4747eb43aa7SLois Curfman McInnes } 4757eb43aa7SLois Curfman McInnes 47617ab2063SBarry Smith 4774a2ae208SSatish Balay #undef __FUNCT__ 4784a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 479dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 48017ab2063SBarry Smith { 481416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4826849ba73SBarry Smith PetscErrorCode ierr; 4836f69ff64SBarry Smith PetscInt i,*col_lens; 4846f69ff64SBarry Smith int fd; 485b37d52dbSMark F. Adams FILE *file; 48617ab2063SBarry Smith 4873a40ed3dSBarry Smith PetscFunctionBegin; 488b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 489d0f46423SBarry Smith ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 4902205254eSKarl Rupp 4910700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 492d0f46423SBarry Smith col_lens[1] = A->rmap->n; 493d0f46423SBarry Smith col_lens[2] = A->cmap->n; 494416022c9SBarry Smith col_lens[3] = a->nz; 495416022c9SBarry Smith 496416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 497d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 498416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 49917ab2063SBarry Smith } 500d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 501606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 502416022c9SBarry Smith 503416022c9SBarry Smith /* store column indices (zero start index) */ 5046f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 505416022c9SBarry Smith 506416022c9SBarry Smith /* store nonzero values */ 5076f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 508b37d52dbSMark F. Adams 509b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 510b37d52dbSMark F. Adams if (file) { 511b37d52dbSMark F. Adams fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs); 512b37d52dbSMark F. Adams } 5133a40ed3dSBarry Smith PetscFunctionReturn(0); 51417ab2063SBarry Smith } 515416022c9SBarry Smith 51609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 517cd155464SBarry Smith 5184a2ae208SSatish Balay #undef __FUNCT__ 5194a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 520dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 521416022c9SBarry Smith { 522416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 523dfbe8321SBarry Smith PetscErrorCode ierr; 524d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,shift=0; 525e060cb09SBarry Smith const char *name; 526f3ef73ceSBarry Smith PetscViewerFormat format; 52717ab2063SBarry Smith 5283a40ed3dSBarry Smith PetscFunctionBegin; 529b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 53071c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 53197f1f81fSBarry Smith PetscInt nofinalvalue = 0; 532014b3a6eSMark Adams if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) { 533d00d2cf4SBarry Smith nofinalvalue = 1; 534d00d2cf4SBarry Smith } 535d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 536d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 53777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 53877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 539b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 54017ab2063SBarry Smith 54117ab2063SBarry Smith for (i=0; i<m; i++) { 542416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 543aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 54477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 54517ab2063SBarry Smith #else 54677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 54717ab2063SBarry Smith #endif 54817ab2063SBarry Smith } 54917ab2063SBarry Smith } 550d00d2cf4SBarry Smith if (nofinalvalue) { 551d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 552d00d2cf4SBarry Smith } 553317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 554fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 555d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 55668369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 557cd155464SBarry Smith PetscFunctionReturn(0); 558fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 559d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 560dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 56144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 56277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 56344cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 564aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 56536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 566ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 56736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 568ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 56936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 570ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 5716831982aSBarry Smith } 57244cd7ae7SLois Curfman McInnes #else 573ba0e910bSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);} 57444cd7ae7SLois Curfman McInnes #endif 57544cd7ae7SLois Curfman McInnes } 576b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 57744cd7ae7SLois Curfman McInnes } 578d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 579fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 58097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 581d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 582dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 58397f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 584496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 585496be53dSLois Curfman McInnes sptr[i] = nzd+1; 586496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 587496be53dSLois Curfman McInnes if (a->j[j] >= i) { 588aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 58936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 590496be53dSLois Curfman McInnes #else 591496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 592496be53dSLois Curfman McInnes #endif 593496be53dSLois Curfman McInnes } 594496be53dSLois Curfman McInnes } 595496be53dSLois Curfman McInnes } 5962e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 59777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 5982e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 5992205254eSKarl Rupp if (i+4<m) { 6002205254eSKarl 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); 6012205254eSKarl Rupp } else if (i+3<m) { 6022205254eSKarl 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); 6032205254eSKarl Rupp } else if (i+2<m) { 6042205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6052205254eSKarl Rupp } else if (i+1<m) { 6062205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6072205254eSKarl Rupp } else if (i<m) { 6082205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6092205254eSKarl Rupp } else { 6102205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6112205254eSKarl Rupp } 612496be53dSLois Curfman McInnes } 613b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 614606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 615496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 616496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 61777431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 618496be53dSLois Curfman McInnes } 619b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 620496be53dSLois Curfman McInnes } 621b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 622496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 623496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 624496be53dSLois Curfman McInnes if (a->j[j] >= i) { 625aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 62636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 627b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6286831982aSBarry Smith } 629496be53dSLois Curfman McInnes #else 630b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 631496be53dSLois Curfman McInnes #endif 632496be53dSLois Curfman McInnes } 633496be53dSLois Curfman McInnes } 634b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 635496be53dSLois Curfman McInnes } 636d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 637fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 63897f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 63987828ca2SBarry Smith PetscScalar value; 64002594712SBarry Smith 641d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 642dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 64302594712SBarry Smith for (i=0; i<m; i++) { 64402594712SBarry Smith jcnt = 0; 645d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 646e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 64702594712SBarry Smith value = a->a[cnt++]; 648e24b481bSBarry Smith jcnt++; 64902594712SBarry Smith } else { 65002594712SBarry Smith value = 0.0; 65102594712SBarry Smith } 652aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 653b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 65402594712SBarry Smith #else 655b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 65602594712SBarry Smith #endif 65702594712SBarry Smith } 658b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 65902594712SBarry Smith } 660d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6613c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 662d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 663dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 6643c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 6653c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 6663c215bfdSMatthew Knepley #else 6673c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 6683c215bfdSMatthew Knepley #endif 669d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 6703c215bfdSMatthew Knepley for (i=0; i<m; i++) { 6713c215bfdSMatthew Knepley for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 6723c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 6733c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 674ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6753c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 676ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6773c215bfdSMatthew Knepley } else { 678ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 6793c215bfdSMatthew Knepley } 6803c215bfdSMatthew Knepley #else 681ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr); 6823c215bfdSMatthew Knepley #endif 6833c215bfdSMatthew Knepley } 6843c215bfdSMatthew Knepley } 685d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6863a40ed3dSBarry Smith } else { 687d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 688dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 689d5f3da31SBarry Smith if (A->factortype) { 69016cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 69116cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 69216cd7e1dSShri Abhyankar /* L part */ 69316cd7e1dSShri Abhyankar for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 69416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 69516cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 696ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 69716cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 698ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 69916cd7e1dSShri Abhyankar } else { 700ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 70116cd7e1dSShri Abhyankar } 70216cd7e1dSShri Abhyankar #else 703ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 70416cd7e1dSShri Abhyankar #endif 70516cd7e1dSShri Abhyankar } 70616cd7e1dSShri Abhyankar /* diagonal */ 70716cd7e1dSShri Abhyankar j = a->diag[i]; 70816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 70916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 710ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 71116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 712ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),-PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 71316cd7e1dSShri Abhyankar } else { 714ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 71516cd7e1dSShri Abhyankar } 71616cd7e1dSShri Abhyankar #else 717ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr); 71816cd7e1dSShri Abhyankar #endif 71916cd7e1dSShri Abhyankar 72016cd7e1dSShri Abhyankar /* U part */ 72116cd7e1dSShri Abhyankar for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) { 72216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 72316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 724ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 72516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 726ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 72716cd7e1dSShri Abhyankar } else { 728ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 72916cd7e1dSShri Abhyankar } 73016cd7e1dSShri Abhyankar #else 731ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 73216cd7e1dSShri Abhyankar #endif 73316cd7e1dSShri Abhyankar } 73416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 73516cd7e1dSShri Abhyankar } 73616cd7e1dSShri Abhyankar } else { 73717ab2063SBarry Smith for (i=0; i<m; i++) { 73877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 739416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 740aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 74136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 742ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 74336db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 744ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7453a40ed3dSBarry Smith } else { 746ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 74717ab2063SBarry Smith } 74817ab2063SBarry Smith #else 749ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 75017ab2063SBarry Smith #endif 75117ab2063SBarry Smith } 752b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 75317ab2063SBarry Smith } 75416cd7e1dSShri Abhyankar } 755d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 75617ab2063SBarry Smith } 757b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7583a40ed3dSBarry Smith PetscFunctionReturn(0); 759416022c9SBarry Smith } 760416022c9SBarry Smith 7619804daf3SBarry Smith #include <petscdraw.h> 7624a2ae208SSatish Balay #undef __FUNCT__ 7634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 764dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 765416022c9SBarry Smith { 766480ef9eaSBarry Smith Mat A = (Mat) Aa; 767416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 768dfbe8321SBarry Smith PetscErrorCode ierr; 769d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 77036db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 771b0a32e0cSBarry Smith PetscViewer viewer; 772f3ef73ceSBarry Smith PetscViewerFormat format; 773cddf8d76SBarry Smith 7743a40ed3dSBarry Smith PetscFunctionBegin; 775480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 776b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 77719bcc07fSBarry Smith 778b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 779416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 7800513a670SBarry Smith 781fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 7820513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 783b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 784416022c9SBarry Smith for (i=0; i<m; i++) { 785cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 786bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 787bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 78836db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 789b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 790cddf8d76SBarry Smith } 791cddf8d76SBarry Smith } 792b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 793cddf8d76SBarry Smith for (i=0; i<m; i++) { 794cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 795bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 796bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 797cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 798b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 799cddf8d76SBarry Smith } 800cddf8d76SBarry Smith } 801b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 802cddf8d76SBarry Smith for (i=0; i<m; i++) { 803cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 804bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 805bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 80636db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 807b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 808416022c9SBarry Smith } 809416022c9SBarry Smith } 8100513a670SBarry Smith } else { 8110513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8120513a670SBarry Smith /* first determine max of all nonzero values */ 81397f1f81fSBarry Smith PetscInt nz = a->nz,count; 814b0a32e0cSBarry Smith PetscDraw popup; 81536db0b34SBarry Smith PetscReal scale; 8160513a670SBarry Smith 8170513a670SBarry Smith for (i=0; i<nz; i++) { 8180513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8190513a670SBarry Smith } 820b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 821b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 8222205254eSKarl Rupp if (popup) { 8232205254eSKarl Rupp ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr); 8242205254eSKarl Rupp } 8250513a670SBarry Smith count = 0; 8260513a670SBarry Smith for (i=0; i<m; i++) { 8270513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 828bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 829bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 83097f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 831b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8320513a670SBarry Smith count++; 8330513a670SBarry Smith } 8340513a670SBarry Smith } 8350513a670SBarry Smith } 836480ef9eaSBarry Smith PetscFunctionReturn(0); 837480ef9eaSBarry Smith } 838cddf8d76SBarry Smith 8399804daf3SBarry Smith #include <petscdraw.h> 8404a2ae208SSatish Balay #undef __FUNCT__ 8414a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 842dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 843480ef9eaSBarry Smith { 844dfbe8321SBarry Smith PetscErrorCode ierr; 845b0a32e0cSBarry Smith PetscDraw draw; 84636db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 847ace3abfcSBarry Smith PetscBool isnull; 848480ef9eaSBarry Smith 849480ef9eaSBarry Smith PetscFunctionBegin; 850b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 851b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 852480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 853480ef9eaSBarry Smith 854480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 855d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 856480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 857b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 858b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 8590298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 8603a40ed3dSBarry Smith PetscFunctionReturn(0); 861416022c9SBarry Smith } 862416022c9SBarry Smith 8634a2ae208SSatish Balay #undef __FUNCT__ 8644a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 865dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 866416022c9SBarry Smith { 867dfbe8321SBarry Smith PetscErrorCode ierr; 868ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 869416022c9SBarry Smith 8703a40ed3dSBarry Smith PetscFunctionBegin; 871251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 872251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 873251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 874c45a1595SBarry Smith if (iascii) { 8753a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 8760f5bd95cSBarry Smith } else if (isbinary) { 8773a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 8780f5bd95cSBarry Smith } else if (isdraw) { 8793a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 88011aeaf0aSBarry Smith } 8814108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 8823a40ed3dSBarry Smith PetscFunctionReturn(0); 88317ab2063SBarry Smith } 88419bcc07fSBarry Smith 8854a2ae208SSatish Balay #undef __FUNCT__ 8864a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 887dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 88817ab2063SBarry Smith { 889416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8906849ba73SBarry Smith PetscErrorCode ierr; 89197f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 892d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 89354f21887SBarry Smith MatScalar *aa = a->a,*ap; 8943447b6efSHong Zhang PetscReal ratio = 0.6; 89517ab2063SBarry Smith 8963a40ed3dSBarry Smith PetscFunctionBegin; 8973a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 89817ab2063SBarry Smith 89943ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 90017ab2063SBarry Smith for (i=1; i<m; i++) { 901416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 90217ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 90394a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 90417ab2063SBarry Smith if (fshift) { 905bfeeae90SHong Zhang ip = aj + ai[i]; 906bfeeae90SHong Zhang ap = aa + ai[i]; 90717ab2063SBarry Smith N = ailen[i]; 90817ab2063SBarry Smith for (j=0; j<N; j++) { 90917ab2063SBarry Smith ip[j-fshift] = ip[j]; 91017ab2063SBarry Smith ap[j-fshift] = ap[j]; 91117ab2063SBarry Smith } 91217ab2063SBarry Smith } 91317ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 91417ab2063SBarry Smith } 91517ab2063SBarry Smith if (m) { 91617ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 91717ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 91817ab2063SBarry Smith } 91917ab2063SBarry Smith /* reset ilen and imax for each row */ 92017ab2063SBarry Smith for (i=0; i<m; i++) { 92117ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 92217ab2063SBarry Smith } 923bfeeae90SHong Zhang a->nz = ai[m]; 92465e19b50SBarry 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); 92517ab2063SBarry Smith 92609f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 927d0f46423SBarry 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); 928ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 929ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9302205254eSKarl Rupp 9318e58a170SBarry Smith A->info.mallocs += a->reallocs; 932dd5f02e7SSatish Balay a->reallocs = 0; 9334e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 93436db0b34SBarry Smith a->rmax = rmax; 9354e220ebcSLois Curfman McInnes 936cd6b891eSBarry Smith ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 9372205254eSKarl Rupp 93888e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 93971c2f376SKris Buschelman 9404108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 94171f1c65dSBarry Smith 942acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9433a40ed3dSBarry Smith PetscFunctionReturn(0); 94417ab2063SBarry Smith } 94517ab2063SBarry Smith 9464a2ae208SSatish Balay #undef __FUNCT__ 94799cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 94899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 94999cafbc1SBarry Smith { 95099cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 95199cafbc1SBarry Smith PetscInt i,nz = a->nz; 95254f21887SBarry Smith MatScalar *aa = a->a; 953acf2f550SJed Brown PetscErrorCode ierr; 95499cafbc1SBarry Smith 95599cafbc1SBarry Smith PetscFunctionBegin; 95699cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 957acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 95899cafbc1SBarry Smith PetscFunctionReturn(0); 95999cafbc1SBarry Smith } 96099cafbc1SBarry Smith 96199cafbc1SBarry Smith #undef __FUNCT__ 96299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 96399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 96499cafbc1SBarry Smith { 96599cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 96699cafbc1SBarry Smith PetscInt i,nz = a->nz; 96754f21887SBarry Smith MatScalar *aa = a->a; 968acf2f550SJed Brown PetscErrorCode ierr; 96999cafbc1SBarry Smith 97099cafbc1SBarry Smith PetscFunctionBegin; 97199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 972acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 97399cafbc1SBarry Smith PetscFunctionReturn(0); 97499cafbc1SBarry Smith } 97599cafbc1SBarry Smith 97678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 97778b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A) 97878b84d54SShri Abhyankar { 97978b84d54SShri Abhyankar PetscErrorCode ierr; 98078b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 98178b84d54SShri Abhyankar PetscInt n,start,end; 98278b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 98378b84d54SShri Abhyankar 98478b84d54SShri Abhyankar start = trstarts[thread_id]; 98578b84d54SShri Abhyankar end = trstarts[thread_id+1]; 98619baf141SJed Brown n = a->i[end] - a->i[start]; 98719baf141SJed Brown ierr = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr); 98878b84d54SShri Abhyankar return 0; 98978b84d54SShri Abhyankar } 99078b84d54SShri Abhyankar 99178b84d54SShri Abhyankar #undef __FUNCT__ 99278b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ" 99378b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 99478b84d54SShri Abhyankar { 99578b84d54SShri Abhyankar PetscErrorCode ierr; 99678b84d54SShri Abhyankar 99778b84d54SShri Abhyankar PetscFunctionBegin; 998ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr); 999acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 100078b84d54SShri Abhyankar PetscFunctionReturn(0); 100178b84d54SShri Abhyankar } 100278b84d54SShri Abhyankar #else 100399cafbc1SBarry Smith #undef __FUNCT__ 10044a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 1005dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 100617ab2063SBarry Smith { 1007416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1008dfbe8321SBarry Smith PetscErrorCode ierr; 10093a40ed3dSBarry Smith 10103a40ed3dSBarry Smith PetscFunctionBegin; 1011d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1012acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10133a40ed3dSBarry Smith PetscFunctionReturn(0); 101417ab2063SBarry Smith } 101578b84d54SShri Abhyankar #endif 1016416022c9SBarry Smith 10174a2ae208SSatish Balay #undef __FUNCT__ 10184a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 1019dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 102017ab2063SBarry Smith { 1021416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1022dfbe8321SBarry Smith PetscErrorCode ierr; 1023d5d45c9bSBarry Smith 10243a40ed3dSBarry Smith PetscFunctionBegin; 1025aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1026d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 102717ab2063SBarry Smith #endif 1028e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10296bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10306bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 103105b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1032d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 103305b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 103471f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 103505b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10366bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 103705b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10386bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 103905b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 10406bf464f9SBarry Smith ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr); 1041cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10420b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1043a30b2313SHong Zhang 10444108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1045bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1046901853e0SKris Buschelman 1047dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1048bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1049bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1050bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1051bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1052bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1053bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1055bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10583a40ed3dSBarry Smith PetscFunctionReturn(0); 105917ab2063SBarry Smith } 106017ab2063SBarry Smith 10614a2ae208SSatish Balay #undef __FUNCT__ 10624a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 1063ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 106417ab2063SBarry Smith { 1065416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10664846f1f5SKris Buschelman PetscErrorCode ierr; 10673a40ed3dSBarry Smith 10683a40ed3dSBarry Smith PetscFunctionBegin; 1069a65d3064SKris Buschelman switch (op) { 1070a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 10714e0d8c25SBarry Smith a->roworiented = flg; 1072a65d3064SKris Buschelman break; 1073a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1074a9817697SBarry Smith a->keepnonzeropattern = flg; 1075a65d3064SKris Buschelman break; 1076512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1077512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1078a65d3064SKris Buschelman break; 1079a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 10804e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1081a65d3064SKris Buschelman break; 1082a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 10834e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1084a65d3064SKris Buschelman break; 108528b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 108628b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 108728b2fa4aSMatthew Knepley break; 1088a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 10894e0d8c25SBarry Smith a->ignorezeroentries = flg; 10900df259c2SBarry Smith break; 1091cd6b891eSBarry Smith case MAT_CHECK_COMPRESSED_ROW: 1092cd6b891eSBarry Smith a->compressedrow.check = flg; 1093d487561eSHong Zhang break; 10943d472b54SHong Zhang case MAT_SPD: 1095b1646e73SJed Brown case MAT_SYMMETRIC: 1096b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1097b1646e73SJed Brown case MAT_HERMITIAN: 1098b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 10995021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11005021d80fSJed Brown break; 11014e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1102a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1103a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1104290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1105a65d3064SKris Buschelman break; 1106b87ac2d8SJed Brown case MAT_USE_INODES: 1107b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1108b87ac2d8SJed Brown break; 1109a65d3064SKris Buschelman default: 1110e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1111a65d3064SKris Buschelman } 11124108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11133a40ed3dSBarry Smith PetscFunctionReturn(0); 111417ab2063SBarry Smith } 111517ab2063SBarry Smith 11164a2ae208SSatish Balay #undef __FUNCT__ 11174a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 1118dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 111917ab2063SBarry Smith { 1120416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11216849ba73SBarry Smith PetscErrorCode ierr; 1122d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 112335e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 112417ab2063SBarry Smith 11253a40ed3dSBarry Smith PetscFunctionBegin; 1126d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1127e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 112835e7444dSHong Zhang 1129d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1130d3e70bfaSHong Zhang PetscInt *diag=a->diag; 113135e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11322c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 113335e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 113435e7444dSHong Zhang PetscFunctionReturn(0); 113535e7444dSHong Zhang } 113635e7444dSHong Zhang 11372dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11381ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 113935e7444dSHong Zhang for (i=0; i<n; i++) { 114035e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11412f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 114235e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 114335e7444dSHong Zhang if (aj[j] == i) { 114435e7444dSHong Zhang x[i] = aa[j]; 114517ab2063SBarry Smith break; 114617ab2063SBarry Smith } 114717ab2063SBarry Smith } 114817ab2063SBarry Smith } 11491ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11503a40ed3dSBarry Smith PetscFunctionReturn(0); 115117ab2063SBarry Smith } 115217ab2063SBarry Smith 1153c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 11544a2ae208SSatish Balay #undef __FUNCT__ 11554a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 1156dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 115717ab2063SBarry Smith { 1158416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11595c897100SBarry Smith PetscScalar *x,*y; 1160dfbe8321SBarry Smith PetscErrorCode ierr; 1161d0f46423SBarry Smith PetscInt m = A->rmap->n; 11625c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1163a77337e4SBarry Smith MatScalar *v; 1164a77337e4SBarry Smith PetscScalar alpha; 11650298fd71SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=NULL; 11663447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1167ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11685c897100SBarry Smith #endif 116917ab2063SBarry Smith 11703a40ed3dSBarry Smith PetscFunctionBegin; 11712e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 11721ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 11731ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11745c897100SBarry Smith 11755c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1176bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 11775c897100SBarry Smith #else 11783447b6efSHong Zhang if (usecprow) { 11793447b6efSHong Zhang m = cprow.nrows; 11803447b6efSHong Zhang ii = cprow.i; 11817b2bb3b9SHong Zhang ridx = cprow.rindex; 11823447b6efSHong Zhang } else { 11833447b6efSHong Zhang ii = a->i; 11843447b6efSHong Zhang } 118517ab2063SBarry Smith for (i=0; i<m; i++) { 11863447b6efSHong Zhang idx = a->j + ii[i]; 11873447b6efSHong Zhang v = a->a + ii[i]; 11883447b6efSHong Zhang n = ii[i+1] - ii[i]; 11893447b6efSHong Zhang if (usecprow) { 11907b2bb3b9SHong Zhang alpha = x[ridx[i]]; 11913447b6efSHong Zhang } else { 119217ab2063SBarry Smith alpha = x[i]; 11933447b6efSHong Zhang } 119404fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 119517ab2063SBarry Smith } 11965c897100SBarry Smith #endif 1197dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 11981ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 11991ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12003a40ed3dSBarry Smith PetscFunctionReturn(0); 120117ab2063SBarry Smith } 120217ab2063SBarry Smith 12034a2ae208SSatish Balay #undef __FUNCT__ 12045c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 1205dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12065c897100SBarry Smith { 1207dfbe8321SBarry Smith PetscErrorCode ierr; 12085c897100SBarry Smith 12095c897100SBarry Smith PetscFunctionBegin; 1210170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12115c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12125c897100SBarry Smith PetscFunctionReturn(0); 12135c897100SBarry Smith } 12145c897100SBarry Smith 1215c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 121678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 121778b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy) 121878b84d54SShri Abhyankar { 121978b84d54SShri Abhyankar PetscErrorCode ierr; 122078b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122178b84d54SShri Abhyankar PetscScalar *y; 122278b84d54SShri Abhyankar const PetscScalar *x; 122378b84d54SShri Abhyankar const MatScalar *aa; 122478b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 122578b84d54SShri Abhyankar PetscInt n,start,end,i; 122678b84d54SShri Abhyankar const PetscInt *aj,*ai; 122778b84d54SShri Abhyankar PetscScalar sum; 122878b84d54SShri Abhyankar 122978b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 123078b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 123178b84d54SShri Abhyankar start = trstarts[thread_id]; 123278b84d54SShri Abhyankar end = trstarts[thread_id+1]; 123378b84d54SShri Abhyankar aj = a->j; 123478b84d54SShri Abhyankar aa = a->a; 123578b84d54SShri Abhyankar ai = a->i; 123678b84d54SShri Abhyankar for (i=start; i<end; i++) { 123778b84d54SShri Abhyankar n = ai[i+1] - ai[i]; 123878b84d54SShri Abhyankar aj = a->j + ai[i]; 123978b84d54SShri Abhyankar aa = a->a + ai[i]; 124078b84d54SShri Abhyankar sum = 0.0; 124178b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 124278b84d54SShri Abhyankar y[i] = sum; 124378b84d54SShri Abhyankar } 124478b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 124578b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 124678b84d54SShri Abhyankar return 0; 124778b84d54SShri Abhyankar } 124878b84d54SShri Abhyankar 124978b84d54SShri Abhyankar #undef __FUNCT__ 125078b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ" 125178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 125278b84d54SShri Abhyankar { 125378b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 125478b84d54SShri Abhyankar PetscScalar *y; 125578b84d54SShri Abhyankar const PetscScalar *x; 125678b84d54SShri Abhyankar const MatScalar *aa; 125778b84d54SShri Abhyankar PetscErrorCode ierr; 125878b84d54SShri Abhyankar PetscInt m=A->rmap->n; 12590298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 126078b84d54SShri Abhyankar PetscInt n,i,nonzerorow=0; 126178b84d54SShri Abhyankar PetscScalar sum; 126278b84d54SShri Abhyankar PetscBool usecprow=a->compressedrow.use; 126378b84d54SShri Abhyankar 126478b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 126578b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa) 126678b84d54SShri Abhyankar #endif 126778b84d54SShri Abhyankar 126878b84d54SShri Abhyankar PetscFunctionBegin; 126978b84d54SShri Abhyankar aj = a->j; 127078b84d54SShri Abhyankar aa = a->a; 127178b84d54SShri Abhyankar ii = a->i; 127278b84d54SShri Abhyankar if (usecprow) { /* use compressed row format */ 127378b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 127478b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 127578b84d54SShri Abhyankar m = a->compressedrow.nrows; 127678b84d54SShri Abhyankar ii = a->compressedrow.i; 127778b84d54SShri Abhyankar ridx = a->compressedrow.rindex; 127878b84d54SShri Abhyankar for (i=0; i<m; i++) { 127978b84d54SShri Abhyankar n = ii[i+1] - ii[i]; 128078b84d54SShri Abhyankar aj = a->j + ii[i]; 128178b84d54SShri Abhyankar aa = a->a + ii[i]; 128278b84d54SShri Abhyankar sum = 0.0; 128378b84d54SShri Abhyankar nonzerorow += (n>0); 128478b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 128578b84d54SShri Abhyankar /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 128678b84d54SShri Abhyankar y[*ridx++] = sum; 128778b84d54SShri Abhyankar } 128878b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 128978b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 129078b84d54SShri Abhyankar } else { /* do not use compressed row format */ 129178b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 129278b84d54SShri Abhyankar fortranmultaij_(&m,x,ii,aj,aa,y); 129378b84d54SShri Abhyankar #else 1294ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 129578b84d54SShri Abhyankar #endif 129678b84d54SShri Abhyankar } 129778b84d54SShri Abhyankar ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 129878b84d54SShri Abhyankar PetscFunctionReturn(0); 129978b84d54SShri Abhyankar } 130078b84d54SShri Abhyankar #else 13015c897100SBarry Smith #undef __FUNCT__ 13024a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 1303dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 130417ab2063SBarry Smith { 1305416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1306d9fead3dSBarry Smith PetscScalar *y; 130754f21887SBarry Smith const PetscScalar *x; 130854f21887SBarry Smith const MatScalar *aa; 1309dfbe8321SBarry Smith PetscErrorCode ierr; 1310003131ecSBarry Smith PetscInt m=A->rmap->n; 13110298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 13128aee2decSHong Zhang PetscInt n,i,nonzerorow=0; 1313362ced78SSatish Balay PetscScalar sum; 1314ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 131517ab2063SBarry Smith 1316b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 131797952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1318fee21e36SBarry Smith #endif 1319fee21e36SBarry Smith 13203a40ed3dSBarry Smith PetscFunctionBegin; 13213649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13221ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 132397952fefSHong Zhang aj = a->j; 132497952fefSHong Zhang aa = a->a; 1325416022c9SBarry Smith ii = a->i; 13264eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 132797952fefSHong Zhang m = a->compressedrow.nrows; 132897952fefSHong Zhang ii = a->compressedrow.i; 132997952fefSHong Zhang ridx = a->compressedrow.rindex; 133097952fefSHong Zhang for (i=0; i<m; i++) { 133197952fefSHong Zhang n = ii[i+1] - ii[i]; 133297952fefSHong Zhang aj = a->j + ii[i]; 133397952fefSHong Zhang aa = a->a + ii[i]; 133497952fefSHong Zhang sum = 0.0; 1335a46b3154SVictor Eijkhout nonzerorow += (n>0); 1336003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1337003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 133897952fefSHong Zhang y[*ridx++] = sum; 133997952fefSHong Zhang } 134097952fefSHong Zhang } else { /* do not use compressed row format */ 1341b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1342b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1343b05257ddSBarry Smith #else 134478b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 1345ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 134678b84d54SShri Abhyankar #else 134717ab2063SBarry Smith for (i=0; i<m; i++) { 1348003131ecSBarry Smith n = ii[i+1] - ii[i]; 1349003131ecSBarry Smith aj = a->j + ii[i]; 1350003131ecSBarry Smith aa = a->a + ii[i]; 135117ab2063SBarry Smith sum = 0.0; 1352a46b3154SVictor Eijkhout nonzerorow += (n>0); 1353003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 135417ab2063SBarry Smith y[i] = sum; 135517ab2063SBarry Smith } 13568d195f9aSBarry Smith #endif 135778b84d54SShri Abhyankar #endif 1358b05257ddSBarry Smith } 1359dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 13603649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13611ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13623a40ed3dSBarry Smith PetscFunctionReturn(0); 136317ab2063SBarry Smith } 136478b84d54SShri Abhyankar #endif 136517ab2063SBarry Smith 1366b434eb95SMatthew G. Knepley #undef __FUNCT__ 1367b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ" 1368b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1369b434eb95SMatthew G. Knepley { 1370b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1371b434eb95SMatthew G. Knepley PetscScalar *y; 1372b434eb95SMatthew G. Knepley const PetscScalar *x; 1373b434eb95SMatthew G. Knepley const MatScalar *aa; 1374b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1375b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1376b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1377b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1378b434eb95SMatthew G. Knepley PetscScalar sum; 1379b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1380b434eb95SMatthew G. Knepley 1381b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1382b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1383b434eb95SMatthew G. Knepley #endif 1384b434eb95SMatthew G. Knepley 1385b434eb95SMatthew G. Knepley PetscFunctionBegin; 1386b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1387b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1388b434eb95SMatthew G. Knepley aj = a->j; 1389b434eb95SMatthew G. Knepley aa = a->a; 1390b434eb95SMatthew G. Knepley ii = a->i; 1391b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1392b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1393b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1394b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1395b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1396b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1397b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1398b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1399b434eb95SMatthew G. Knepley sum = 0.0; 1400b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1401b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1402b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1403b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1404b434eb95SMatthew G. Knepley } 1405b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1406b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1407b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1408b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1409b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1410b434eb95SMatthew G. Knepley sum = 0.0; 1411b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1412b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1413b434eb95SMatthew G. Knepley y[i] = sum; 1414b434eb95SMatthew G. Knepley } 1415b434eb95SMatthew G. Knepley } 1416b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1417b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1418b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1419b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1420b434eb95SMatthew G. Knepley } 1421b434eb95SMatthew G. Knepley 1422b434eb95SMatthew G. Knepley #undef __FUNCT__ 1423b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ" 1424b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1425b434eb95SMatthew G. Knepley { 1426b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1427b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1428b434eb95SMatthew G. Knepley const PetscScalar *x; 1429b434eb95SMatthew G. Knepley const MatScalar *aa; 1430b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1431b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1432b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1433b434eb95SMatthew G. Knepley PetscScalar sum; 1434b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1435b434eb95SMatthew G. Knepley 1436b434eb95SMatthew G. Knepley PetscFunctionBegin; 1437b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1438b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1439b434eb95SMatthew G. Knepley if (zz != yy) { 1440b434eb95SMatthew G. Knepley ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 1441b434eb95SMatthew G. Knepley } else { 1442b434eb95SMatthew G. Knepley z = y; 1443b434eb95SMatthew G. Knepley } 1444b434eb95SMatthew G. Knepley 1445b434eb95SMatthew G. Knepley aj = a->j; 1446b434eb95SMatthew G. Knepley aa = a->a; 1447b434eb95SMatthew G. Knepley ii = a->i; 1448b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1449b434eb95SMatthew G. Knepley if (zz != yy) { 1450b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1451b434eb95SMatthew G. Knepley } 1452b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1453b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1454b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1455b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1456b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1457b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1458b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1459b434eb95SMatthew G. Knepley sum = y[*ridx]; 1460b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1461b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1462b434eb95SMatthew G. Knepley } 1463b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1464b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1465b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1466b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1467b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1468b434eb95SMatthew G. Knepley sum = y[i]; 1469b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1470b434eb95SMatthew G. Knepley z[i] = sum; 1471b434eb95SMatthew G. Knepley } 1472b434eb95SMatthew G. Knepley } 1473b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1474b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1475b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1476b434eb95SMatthew G. Knepley if (zz != yy) { 1477b434eb95SMatthew G. Knepley ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 1478b434eb95SMatthew G. Knepley } 1479b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1480b434eb95SMatthew G. Knepley } 1481b434eb95SMatthew G. Knepley 1482c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 14834a2ae208SSatish Balay #undef __FUNCT__ 14844a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1485dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 148617ab2063SBarry Smith { 1487416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1488f15663dcSBarry Smith PetscScalar *y,*z; 1489f15663dcSBarry Smith const PetscScalar *x; 149054f21887SBarry Smith const MatScalar *aa; 1491dfbe8321SBarry Smith PetscErrorCode ierr; 1492d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 14930298fd71SBarry Smith PetscInt n,i,*ridx=NULL; 1494362ced78SSatish Balay PetscScalar sum; 1495ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 14969ea0dfa2SSatish Balay 14973a40ed3dSBarry Smith PetscFunctionBegin; 1498f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14991ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 15002e8a6d31SBarry Smith if (zz != yy) { 15011ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 15022e8a6d31SBarry Smith } else { 15032e8a6d31SBarry Smith z = y; 15042e8a6d31SBarry Smith } 1505bfeeae90SHong Zhang 150697952fefSHong Zhang aj = a->j; 150797952fefSHong Zhang aa = a->a; 1508cddf8d76SBarry Smith ii = a->i; 15094eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 15104eb6d288SHong Zhang if (zz != yy) { 15114eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 15124eb6d288SHong Zhang } 151397952fefSHong Zhang m = a->compressedrow.nrows; 151497952fefSHong Zhang ii = a->compressedrow.i; 151597952fefSHong Zhang ridx = a->compressedrow.rindex; 151697952fefSHong Zhang for (i=0; i<m; i++) { 151797952fefSHong Zhang n = ii[i+1] - ii[i]; 151897952fefSHong Zhang aj = a->j + ii[i]; 151997952fefSHong Zhang aa = a->a + ii[i]; 152097952fefSHong Zhang sum = y[*ridx]; 1521f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 152297952fefSHong Zhang z[*ridx++] = sum; 152397952fefSHong Zhang } 152497952fefSHong Zhang } else { /* do not use compressed row format */ 1525f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1526f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1527f15663dcSBarry Smith #else 152817ab2063SBarry Smith for (i=0; i<m; i++) { 1529f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1530f15663dcSBarry Smith aj = a->j + ii[i]; 1531f15663dcSBarry Smith aa = a->a + ii[i]; 153217ab2063SBarry Smith sum = y[i]; 1533f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 153417ab2063SBarry Smith z[i] = sum; 153517ab2063SBarry Smith } 153602ab625aSSatish Balay #endif 1537f15663dcSBarry Smith } 1538dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1539f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15401ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15412e8a6d31SBarry Smith if (zz != yy) { 15421ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 15432e8a6d31SBarry Smith } 15448154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 15456b375ea7SVictor Minden /* 1546918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1547918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1548918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 15496b375ea7SVictor Minden */ 1550918e98c3SVictor Minden #endif 15513a40ed3dSBarry Smith PetscFunctionReturn(0); 155217ab2063SBarry Smith } 155317ab2063SBarry Smith 155417ab2063SBarry Smith /* 155517ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 155617ab2063SBarry Smith */ 15574a2ae208SSatish Balay #undef __FUNCT__ 15584a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1559dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 156017ab2063SBarry Smith { 1561416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15626849ba73SBarry Smith PetscErrorCode ierr; 1563d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 156417ab2063SBarry Smith 15653a40ed3dSBarry Smith PetscFunctionBegin; 156609f38230SBarry Smith if (!a->diag) { 156709f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 15683bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 156909f38230SBarry Smith } 1570d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 157109f38230SBarry Smith a->diag[i] = a->i[i+1]; 1572bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1573bfeeae90SHong Zhang if (a->j[j] == i) { 157409f38230SBarry Smith a->diag[i] = j; 157517ab2063SBarry Smith break; 157617ab2063SBarry Smith } 157717ab2063SBarry Smith } 157817ab2063SBarry Smith } 15793a40ed3dSBarry Smith PetscFunctionReturn(0); 158017ab2063SBarry Smith } 158117ab2063SBarry Smith 1582be5855fcSBarry Smith /* 1583be5855fcSBarry Smith Checks for missing diagonals 1584be5855fcSBarry Smith */ 15854a2ae208SSatish Balay #undef __FUNCT__ 15864a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1587ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1588be5855fcSBarry Smith { 1589be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 159097f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1591be5855fcSBarry Smith 1592be5855fcSBarry Smith PetscFunctionBegin; 159309f38230SBarry Smith *missing = PETSC_FALSE; 1594d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 159509f38230SBarry Smith *missing = PETSC_TRUE; 159609f38230SBarry Smith if (d) *d = 0; 1597358d2f5dSShri Abhyankar PetscInfo(A,"Matrix has no entries therefore is missing diagonal"); 159809f38230SBarry Smith } else { 1599f1e2ffcdSBarry Smith diag = a->diag; 1600d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1601bfeeae90SHong Zhang if (jj[diag[i]] != i) { 160209f38230SBarry Smith *missing = PETSC_TRUE; 160309f38230SBarry Smith if (d) *d = i; 160409f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 1605358d2f5dSShri Abhyankar break; 160609f38230SBarry Smith } 1607be5855fcSBarry Smith } 1608be5855fcSBarry Smith } 1609be5855fcSBarry Smith PetscFunctionReturn(0); 1610be5855fcSBarry Smith } 1611be5855fcSBarry Smith 161271f1c65dSBarry Smith #undef __FUNCT__ 161371f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 16147087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 161571f1c65dSBarry Smith { 161671f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 161771f1c65dSBarry Smith PetscErrorCode ierr; 1618d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 161954f21887SBarry Smith MatScalar *v = a->a; 162054f21887SBarry Smith PetscScalar *idiag,*mdiag; 162171f1c65dSBarry Smith 162271f1c65dSBarry Smith PetscFunctionBegin; 162371f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 162471f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 162571f1c65dSBarry Smith diag = a->diag; 162671f1c65dSBarry Smith if (!a->idiag) { 162771f1c65dSBarry Smith ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr); 16283bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 162971f1c65dSBarry Smith v = a->a; 163071f1c65dSBarry Smith } 163171f1c65dSBarry Smith mdiag = a->mdiag; 163271f1c65dSBarry Smith idiag = a->idiag; 163371f1c65dSBarry Smith 1634028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 163571f1c65dSBarry Smith for (i=0; i<m; i++) { 163671f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1637e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 163871f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 163971f1c65dSBarry Smith } 164071f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 164171f1c65dSBarry Smith } else { 164271f1c65dSBarry Smith for (i=0; i<m; i++) { 164371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 164471f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 164571f1c65dSBarry Smith } 1646dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 164771f1c65dSBarry Smith } 164871f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 164971f1c65dSBarry Smith PetscFunctionReturn(0); 165071f1c65dSBarry Smith } 165171f1c65dSBarry Smith 1652c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 16534a2ae208SSatish Balay #undef __FUNCT__ 165441f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 165541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 165617ab2063SBarry Smith { 1657416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1658e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1659e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 166054f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1661dfbe8321SBarry Smith PetscErrorCode ierr; 1662d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 166397f1f81fSBarry Smith const PetscInt *idx,*diag; 166417ab2063SBarry Smith 16653a40ed3dSBarry Smith PetscFunctionBegin; 1666b965ef7fSBarry Smith its = its*lits; 166791723122SBarry Smith 166871f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 166971f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 167071f1c65dSBarry Smith a->fshift = fshift; 167171f1c65dSBarry Smith a->omega = omega; 1672ed480e8bSBarry Smith 167371f1c65dSBarry Smith diag = a->diag; 167471f1c65dSBarry Smith t = a->ssor_work; 1675ed480e8bSBarry Smith idiag = a->idiag; 167671f1c65dSBarry Smith mdiag = a->mdiag; 1677ed480e8bSBarry Smith 16781ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 16793649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1680ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 168117ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 168217ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1683ed480e8bSBarry Smith bs = b; 168417ab2063SBarry Smith for (i=0; i<m; i++) { 168571f1c65dSBarry Smith d = fshift + mdiag[i]; 1686416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1687ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1688ed480e8bSBarry Smith v = a->a + diag[i] + 1; 168917ab2063SBarry Smith sum = b[i]*d/omega; 1690003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 169117ab2063SBarry Smith x[i] = sum; 169217ab2063SBarry Smith } 16931ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16943649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1695efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16963a40ed3dSBarry Smith PetscFunctionReturn(0); 169717ab2063SBarry Smith } 1698c783ea89SBarry Smith 16992205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 17002205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 170117ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1702887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 170317ab2063SBarry Smith 170417ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 170517ab2063SBarry Smith 1706887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 170717ab2063SBarry Smith */ 170817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 170917ab2063SBarry Smith 171017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 171117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1712416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1713ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1714ed480e8bSBarry Smith v = a->a + diag[i] + 1; 171517ab2063SBarry Smith sum = b[i]; 1716e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1717ed480e8bSBarry Smith x[i] = sum*idiag[i]; 171817ab2063SBarry Smith } 171917ab2063SBarry Smith 172017ab2063SBarry Smith /* t = b - (2*E - D)x */ 1721416022c9SBarry Smith v = a->a; 17222205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 172317ab2063SBarry Smith 172417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1725ed480e8bSBarry Smith ts = t; 1726416022c9SBarry Smith diag = a->diag; 172717ab2063SBarry Smith for (i=0; i<m; i++) { 1728416022c9SBarry Smith n = diag[i] - a->i[i]; 1729ed480e8bSBarry Smith idx = a->j + a->i[i]; 1730ed480e8bSBarry Smith v = a->a + a->i[i]; 173117ab2063SBarry Smith sum = t[i]; 1732003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1733ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1734733d66baSBarry Smith /* x = x + t */ 1735733d66baSBarry Smith x[i] += t[i]; 173617ab2063SBarry Smith } 173717ab2063SBarry Smith 1738dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 17391ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17403649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 17413a40ed3dSBarry Smith PetscFunctionReturn(0); 174217ab2063SBarry Smith } 174317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 174417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 174517ab2063SBarry Smith for (i=0; i<m; i++) { 1746416022c9SBarry Smith n = diag[i] - a->i[i]; 1747ed480e8bSBarry Smith idx = a->j + a->i[i]; 1748ed480e8bSBarry Smith v = a->a + a->i[i]; 174917ab2063SBarry Smith sum = b[i]; 1750e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 17515c99c7daSBarry Smith t[i] = sum; 1752ed480e8bSBarry Smith x[i] = sum*idiag[i]; 175317ab2063SBarry Smith } 17545c99c7daSBarry Smith xb = t; 1755efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17563a40ed3dSBarry Smith } else xb = b; 175717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 175817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1759416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1760ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1761ed480e8bSBarry Smith v = a->a + diag[i] + 1; 176217ab2063SBarry Smith sum = xb[i]; 1763e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 17645c99c7daSBarry Smith if (xb == b) { 1765ed480e8bSBarry Smith x[i] = sum*idiag[i]; 17665c99c7daSBarry Smith } else { 1767b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 176817ab2063SBarry Smith } 17695c99c7daSBarry Smith } 1770b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 177117ab2063SBarry Smith } 177217ab2063SBarry Smith its--; 177317ab2063SBarry Smith } 177417ab2063SBarry Smith while (its--) { 177517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 177617ab2063SBarry Smith for (i=0; i<m; i++) { 1777b19a5dc2SMark Adams /* lower */ 1778b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1779ed480e8bSBarry Smith idx = a->j + a->i[i]; 1780ed480e8bSBarry Smith v = a->a + a->i[i]; 178117ab2063SBarry Smith sum = b[i]; 1782e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1783b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1784b19a5dc2SMark Adams /* upper */ 1785b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1786b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1787b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1788b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1789b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 179017ab2063SBarry Smith } 1791b19a5dc2SMark Adams xb = t; 17929f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1793b19a5dc2SMark Adams } else xb = b; 179417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 179517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1796b19a5dc2SMark Adams sum = xb[i]; 1797b19a5dc2SMark Adams if (xb == b) { 1798b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1799416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1800ed480e8bSBarry Smith idx = a->j + a->i[i]; 1801ed480e8bSBarry Smith v = a->a + a->i[i]; 1802e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1803ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1804b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1805b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1806b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1807b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1808b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1809b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 181017ab2063SBarry Smith } 1811b19a5dc2SMark Adams } 1812b19a5dc2SMark Adams if (xb == b) { 18139f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1814b19a5dc2SMark Adams } else { 1815b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1816b19a5dc2SMark Adams } 181717ab2063SBarry Smith } 181817ab2063SBarry Smith } 18191ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18203649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1821365a8a9eSBarry Smith PetscFunctionReturn(0); 182217ab2063SBarry Smith } 182317ab2063SBarry Smith 18242af78befSBarry Smith 18254a2ae208SSatish Balay #undef __FUNCT__ 18264a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1827dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 182817ab2063SBarry Smith { 1829416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18304e220ebcSLois Curfman McInnes 18313a40ed3dSBarry Smith PetscFunctionBegin; 18324e220ebcSLois Curfman McInnes info->block_size = 1.0; 18334e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 18344e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 18354e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 18364e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 18378e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 18387adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1839d5f3da31SBarry Smith if (A->factortype) { 18404e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 18414e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 18424e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 18434e220ebcSLois Curfman McInnes } else { 18444e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 18454e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 18464e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 18474e220ebcSLois Curfman McInnes } 18483a40ed3dSBarry Smith PetscFunctionReturn(0); 184917ab2063SBarry Smith } 185017ab2063SBarry Smith 18514a2ae208SSatish Balay #undef __FUNCT__ 18524a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 18532b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 185417ab2063SBarry Smith { 1855416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18563b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 18576849ba73SBarry Smith PetscErrorCode ierr; 185897b48c8fSBarry Smith const PetscScalar *xx; 185997b48c8fSBarry Smith PetscScalar *bb; 1860ace3abfcSBarry Smith PetscBool missing; 186117ab2063SBarry Smith 18623a40ed3dSBarry Smith PetscFunctionBegin; 186397b48c8fSBarry Smith if (x && b) { 186497b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 186597b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 186697b48c8fSBarry Smith for (i=0; i<N; i++) { 186797b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 186897b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 186997b48c8fSBarry Smith } 187097b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 187197b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 187297b48c8fSBarry Smith } 187397b48c8fSBarry Smith 1874a9817697SBarry Smith if (a->keepnonzeropattern) { 1875f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1876e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1877bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1878f1e2ffcdSBarry Smith } 1879f4df32b1SMatthew Knepley if (diag != 0.0) { 188009f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1881e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1882f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1883f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1884f1e2ffcdSBarry Smith } 1885f1e2ffcdSBarry Smith } 188688e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1887f1e2ffcdSBarry Smith } else { 1888f4df32b1SMatthew Knepley if (diag != 0.0) { 188917ab2063SBarry Smith for (i=0; i<N; i++) { 1890e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18917ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1892416022c9SBarry Smith a->ilen[rows[i]] = 1; 1893f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1894bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 18957ae801bdSBarry Smith } else { /* in case row was completely empty */ 1896f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 189717ab2063SBarry Smith } 189817ab2063SBarry Smith } 18993a40ed3dSBarry Smith } else { 190017ab2063SBarry Smith for (i=0; i<N; i++) { 1901e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1902416022c9SBarry Smith a->ilen[rows[i]] = 0; 190317ab2063SBarry Smith } 190417ab2063SBarry Smith } 190588e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1906f1e2ffcdSBarry Smith } 190743a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19083a40ed3dSBarry Smith PetscFunctionReturn(0); 190917ab2063SBarry Smith } 191017ab2063SBarry Smith 19114a2ae208SSatish Balay #undef __FUNCT__ 19126e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 19136e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 19146e169961SBarry Smith { 19156e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19166e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 19176e169961SBarry Smith PetscErrorCode ierr; 19182b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 19196e169961SBarry Smith const PetscScalar *xx; 19206e169961SBarry Smith PetscScalar *bb; 19216e169961SBarry Smith 19226e169961SBarry Smith PetscFunctionBegin; 19236e169961SBarry Smith if (x && b) { 19246e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 19256e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 19262b40b63fSBarry Smith vecs = PETSC_TRUE; 19276e169961SBarry Smith } 19286e169961SBarry Smith ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr); 19296e169961SBarry Smith ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 19306e169961SBarry Smith for (i=0; i<N; i++) { 19316e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 19326e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 19332205254eSKarl Rupp 19346e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 19356e169961SBarry Smith } 19366e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 19376e169961SBarry Smith if (!zeroed[i]) { 19386e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 19396e169961SBarry Smith if (zeroed[a->j[j]]) { 19402b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 19416e169961SBarry Smith a->a[j] = 0.0; 19426e169961SBarry Smith } 19436e169961SBarry Smith } 19442b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 19456e169961SBarry Smith } 19466e169961SBarry Smith if (x && b) { 19476e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 19486e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 19496e169961SBarry Smith } 19506e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 19516e169961SBarry Smith if (diag != 0.0) { 19526e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 19536e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 19546e169961SBarry Smith for (i=0; i<N; i++) { 19556e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 19566e169961SBarry Smith } 19576e169961SBarry Smith } 19586e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 19596e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19606e169961SBarry Smith PetscFunctionReturn(0); 19616e169961SBarry Smith } 19626e169961SBarry Smith 19636e169961SBarry Smith #undef __FUNCT__ 19644a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1965a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 196617ab2063SBarry Smith { 1967416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 196897f1f81fSBarry Smith PetscInt *itmp; 196917ab2063SBarry Smith 19703a40ed3dSBarry Smith PetscFunctionBegin; 1971e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 197217ab2063SBarry Smith 1973416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1974bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 197517ab2063SBarry Smith if (idx) { 1976bfeeae90SHong Zhang itmp = a->j + a->i[row]; 197726fbe8dcSKarl Rupp if (*nz) *idx = itmp; 197817ab2063SBarry Smith else *idx = 0; 197917ab2063SBarry Smith } 19803a40ed3dSBarry Smith PetscFunctionReturn(0); 198117ab2063SBarry Smith } 198217ab2063SBarry Smith 1983bfeeae90SHong Zhang /* remove this function? */ 19844a2ae208SSatish Balay #undef __FUNCT__ 19854a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1986a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 198717ab2063SBarry Smith { 19883a40ed3dSBarry Smith PetscFunctionBegin; 19893a40ed3dSBarry Smith PetscFunctionReturn(0); 199017ab2063SBarry Smith } 199117ab2063SBarry Smith 19924a2ae208SSatish Balay #undef __FUNCT__ 19934a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1994dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 199517ab2063SBarry Smith { 1996416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 199754f21887SBarry Smith MatScalar *v = a->a; 199836db0b34SBarry Smith PetscReal sum = 0.0; 19996849ba73SBarry Smith PetscErrorCode ierr; 200097f1f81fSBarry Smith PetscInt i,j; 200117ab2063SBarry Smith 20023a40ed3dSBarry Smith PetscFunctionBegin; 200317ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2004416022c9SBarry Smith for (i=0; i<a->nz; i++) { 200536db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 200617ab2063SBarry Smith } 20078f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 20083a40ed3dSBarry Smith } else if (type == NORM_1) { 200936db0b34SBarry Smith PetscReal *tmp; 201097f1f81fSBarry Smith PetscInt *jj = a->j; 2011d0f46423SBarry Smith ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 2012d0f46423SBarry Smith ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr); 2013064f8208SBarry Smith *nrm = 0.0; 2014416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2015bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 201617ab2063SBarry Smith } 2017d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2018064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 201917ab2063SBarry Smith } 2020606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 20213a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2022064f8208SBarry Smith *nrm = 0.0; 2023d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2024bfeeae90SHong Zhang v = a->a + a->i[j]; 202517ab2063SBarry Smith sum = 0.0; 2026416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2027cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 202817ab2063SBarry Smith } 2029064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 203017ab2063SBarry Smith } 2031f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 20323a40ed3dSBarry Smith PetscFunctionReturn(0); 203317ab2063SBarry Smith } 203417ab2063SBarry Smith 20354e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 20364e938277SHong Zhang #undef __FUNCT__ 20374e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ" 20384e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 20394e938277SHong Zhang { 20404e938277SHong Zhang PetscErrorCode ierr; 20414e938277SHong Zhang PetscInt i,j,anzj; 20424e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 20434e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 20444e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 20454e938277SHong Zhang 20464e938277SHong Zhang PetscFunctionBegin; 20474e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 20484e938277SHong Zhang ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr); 20494e938277SHong Zhang ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr); 20504e938277SHong Zhang ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr); 20514e938277SHong Zhang ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr); 20524e938277SHong Zhang 20534e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 20544e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 205526fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 20564e938277SHong Zhang /* Form ati for csr format of A^T. */ 205726fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 20584e938277SHong Zhang 20594e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 20604e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 20614e938277SHong Zhang 20624e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 20634e938277SHong Zhang for (i=0;i<am;i++) { 20644e938277SHong Zhang anzj = ai[i+1] - ai[i]; 20654e938277SHong Zhang for (j=0;j<anzj;j++) { 20664e938277SHong Zhang atj[atfill[*aj]] = i; 20674e938277SHong Zhang atfill[*aj++] += 1; 20684e938277SHong Zhang } 20694e938277SHong Zhang } 20704e938277SHong Zhang 20714e938277SHong Zhang /* Clean up temporary space and complete requests. */ 20724e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2073ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 20742205254eSKarl Rupp 2075a2f3521dSMark F. Adams (*B)->rmap->bs = A->cmap->bs; 2076a2f3521dSMark F. Adams (*B)->cmap->bs = A->rmap->bs; 2077a2f3521dSMark F. Adams 20784e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 20794e938277SHong Zhang b->free_a = PETSC_FALSE; 20804e938277SHong Zhang b->free_ij = PETSC_TRUE; 20814e938277SHong Zhang b->nonew = 0; 20824e938277SHong Zhang PetscFunctionReturn(0); 20834e938277SHong Zhang } 20844e938277SHong Zhang 20854a2ae208SSatish Balay #undef __FUNCT__ 20864a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 2087fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 208817ab2063SBarry Smith { 2089416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2090416022c9SBarry Smith Mat C; 20916849ba73SBarry Smith PetscErrorCode ierr; 2092d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 209354f21887SBarry Smith MatScalar *array = a->a; 209417ab2063SBarry Smith 20953a40ed3dSBarry Smith PetscFunctionBegin; 2096e32f2f54SBarry 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"); 2097fc4dec0aSBarry Smith 2098fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 2099d0f46423SBarry Smith ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 2100d0f46423SBarry Smith ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr); 2101bfeeae90SHong Zhang 2102bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 2103ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2104d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 2105a2f3521dSMark F. Adams ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr); 21067adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2107ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2108606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2109a541d17aSBarry Smith } else { 2110a541d17aSBarry Smith C = *B; 2111a541d17aSBarry Smith } 2112a541d17aSBarry Smith 211317ab2063SBarry Smith for (i=0; i<m; i++) { 211417ab2063SBarry Smith len = ai[i+1]-ai[i]; 211587d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2116b9b97703SBarry Smith array += len; 2117b9b97703SBarry Smith aj += len; 211817ab2063SBarry Smith } 21196d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21206d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 212117ab2063SBarry Smith 2122815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 2123416022c9SBarry Smith *B = C; 212417ab2063SBarry Smith } else { 2125eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 212617ab2063SBarry Smith } 21273a40ed3dSBarry Smith PetscFunctionReturn(0); 212817ab2063SBarry Smith } 212917ab2063SBarry Smith 2130cd0d46ebSvictorle #undef __FUNCT__ 21315fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 21327087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2133cd0d46ebSvictorle { 2134cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 213554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 213654f21887SBarry Smith MatScalar *va,*vb; 21376849ba73SBarry Smith PetscErrorCode ierr; 213897f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2139cd0d46ebSvictorle 2140cd0d46ebSvictorle PetscFunctionBegin; 2141cd0d46ebSvictorle bij = (Mat_SeqAIJ*) B->data; 2142cd0d46ebSvictorle 2143cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2144cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 21455485867bSBarry Smith if (ma!=nb || na!=mb) { 21465485867bSBarry Smith *f = PETSC_FALSE; 21475485867bSBarry Smith PetscFunctionReturn(0); 21485485867bSBarry Smith } 2149cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2150cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2151cd0d46ebSvictorle va = aij->a; vb = bij->a; 215297f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 215397f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 2154cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2155cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2156cd0d46ebSvictorle 2157cd0d46ebSvictorle *f = PETSC_TRUE; 2158cd0d46ebSvictorle for (i=0; i<ma; i++) { 2159cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 216097f1f81fSBarry Smith PetscInt idc,idr; 21615485867bSBarry Smith PetscScalar vc,vr; 2162cd0d46ebSvictorle /* column/row index/value */ 21635485867bSBarry Smith idc = adx[aptr[i]]; 21645485867bSBarry Smith idr = bdx[bptr[idc]]; 21655485867bSBarry Smith vc = va[aptr[i]]; 21665485867bSBarry Smith vr = vb[bptr[idc]]; 21675485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 21685485867bSBarry Smith *f = PETSC_FALSE; 21695485867bSBarry Smith goto done; 2170cd0d46ebSvictorle } else { 21715485867bSBarry Smith aptr[i]++; 21725485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2173cd0d46ebSvictorle } 2174cd0d46ebSvictorle } 2175cd0d46ebSvictorle } 2176cd0d46ebSvictorle done: 2177cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 21783aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2179cd0d46ebSvictorle PetscFunctionReturn(0); 2180cd0d46ebSvictorle } 2181cd0d46ebSvictorle 21821cbb95d3SBarry Smith #undef __FUNCT__ 21831cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 21847087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 21851cbb95d3SBarry Smith { 21861cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 218754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 218854f21887SBarry Smith MatScalar *va,*vb; 21891cbb95d3SBarry Smith PetscErrorCode ierr; 21901cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 21911cbb95d3SBarry Smith 21921cbb95d3SBarry Smith PetscFunctionBegin; 21931cbb95d3SBarry Smith bij = (Mat_SeqAIJ*) B->data; 21941cbb95d3SBarry Smith 21951cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 21961cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 21971cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 21981cbb95d3SBarry Smith *f = PETSC_FALSE; 21991cbb95d3SBarry Smith PetscFunctionReturn(0); 22001cbb95d3SBarry Smith } 22011cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 22021cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 22031cbb95d3SBarry Smith va = aij->a; vb = bij->a; 22041cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 22051cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 22061cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 22071cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 22081cbb95d3SBarry Smith 22091cbb95d3SBarry Smith *f = PETSC_TRUE; 22101cbb95d3SBarry Smith for (i=0; i<ma; i++) { 22111cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 22121cbb95d3SBarry Smith PetscInt idc,idr; 22131cbb95d3SBarry Smith PetscScalar vc,vr; 22141cbb95d3SBarry Smith /* column/row index/value */ 22151cbb95d3SBarry Smith idc = adx[aptr[i]]; 22161cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 22171cbb95d3SBarry Smith vc = va[aptr[i]]; 22181cbb95d3SBarry Smith vr = vb[bptr[idc]]; 22191cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 22201cbb95d3SBarry Smith *f = PETSC_FALSE; 22211cbb95d3SBarry Smith goto done; 22221cbb95d3SBarry Smith } else { 22231cbb95d3SBarry Smith aptr[i]++; 22241cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 22251cbb95d3SBarry Smith } 22261cbb95d3SBarry Smith } 22271cbb95d3SBarry Smith } 22281cbb95d3SBarry Smith done: 22291cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 22301cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 22311cbb95d3SBarry Smith PetscFunctionReturn(0); 22321cbb95d3SBarry Smith } 22331cbb95d3SBarry Smith 22349e29f15eSvictorle #undef __FUNCT__ 22359e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 2236ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 22379e29f15eSvictorle { 2238dfbe8321SBarry Smith PetscErrorCode ierr; 22396e111a19SKarl Rupp 22409e29f15eSvictorle PetscFunctionBegin; 22415485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 22429e29f15eSvictorle PetscFunctionReturn(0); 22439e29f15eSvictorle } 22449e29f15eSvictorle 22454a2ae208SSatish Balay #undef __FUNCT__ 22461cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 2247ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 22481cbb95d3SBarry Smith { 22491cbb95d3SBarry Smith PetscErrorCode ierr; 22506e111a19SKarl Rupp 22511cbb95d3SBarry Smith PetscFunctionBegin; 22521cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 22531cbb95d3SBarry Smith PetscFunctionReturn(0); 22541cbb95d3SBarry Smith } 22551cbb95d3SBarry Smith 22561cbb95d3SBarry Smith #undef __FUNCT__ 22574a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 2258dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 225917ab2063SBarry Smith { 2260416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 226154f21887SBarry Smith PetscScalar *l,*r,x; 226254f21887SBarry Smith MatScalar *v; 2263dfbe8321SBarry Smith PetscErrorCode ierr; 2264d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 226517ab2063SBarry Smith 22663a40ed3dSBarry Smith PetscFunctionBegin; 226717ab2063SBarry Smith if (ll) { 22683ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 22693ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2270e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2271e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 22721ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2273416022c9SBarry Smith v = a->a; 227417ab2063SBarry Smith for (i=0; i<m; i++) { 227517ab2063SBarry Smith x = l[i]; 2276416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 22772205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 227817ab2063SBarry Smith } 22791ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2280efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 228117ab2063SBarry Smith } 228217ab2063SBarry Smith if (rr) { 2283e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2284e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 22851ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2286416022c9SBarry Smith v = a->a; jj = a->j; 22872205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 22881ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2289efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 229017ab2063SBarry Smith } 2291acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 22923a40ed3dSBarry Smith PetscFunctionReturn(0); 229317ab2063SBarry Smith } 229417ab2063SBarry Smith 22954a2ae208SSatish Balay #undef __FUNCT__ 22964a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 229797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 229817ab2063SBarry Smith { 2299db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 23006849ba73SBarry Smith PetscErrorCode ierr; 2301d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 230297f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 23035d0c19d7SBarry Smith const PetscInt *irow,*icol; 23045d0c19d7SBarry Smith PetscInt nrows,ncols; 230597f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 230654f21887SBarry Smith MatScalar *a_new,*mat_a; 2307416022c9SBarry Smith Mat C; 2308ace3abfcSBarry Smith PetscBool stride,sorted; 230917ab2063SBarry Smith 23103a40ed3dSBarry Smith PetscFunctionBegin; 231114ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 2312e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 231314ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2314e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 231599141d43SSatish Balay 231617ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2317b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2318b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 231917ab2063SBarry Smith 2320fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2321251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2322fee21e36SBarry Smith if (stride && step == 1) { 232302834360SBarry Smith /* special case of contiguous rows */ 23240e83c824SBarry Smith ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr); 232502834360SBarry Smith /* loop over new rows determining lens and starting points */ 232602834360SBarry Smith for (i=0; i<nrows; i++) { 2327bfeeae90SHong Zhang kstart = ai[irow[i]]; 2328a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 232902834360SBarry Smith for (k=kstart; k<kend; k++) { 2330bfeeae90SHong Zhang if (aj[k] >= first) { 233102834360SBarry Smith starts[i] = k; 233202834360SBarry Smith break; 233302834360SBarry Smith } 233402834360SBarry Smith } 2335a2744918SBarry Smith sum = 0; 233602834360SBarry Smith while (k < kend) { 2337bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2338a2744918SBarry Smith sum++; 233902834360SBarry Smith } 2340a2744918SBarry Smith lens[i] = sum; 234102834360SBarry Smith } 234202834360SBarry Smith /* create submatrix */ 2343cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 234497f1f81fSBarry Smith PetscInt n_cols,n_rows; 234508480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2346e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2347d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 234808480c60SBarry Smith C = *B; 23493a40ed3dSBarry Smith } else { 23503bef6203SJed Brown PetscInt rbs,cbs; 2351ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2352f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 23533bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 23543bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 23553bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 23567adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2357ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 235808480c60SBarry Smith } 2359db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2360db02288aSLois Curfman McInnes 236102834360SBarry Smith /* loop over rows inserting into submatrix */ 2362db02288aSLois Curfman McInnes a_new = c->a; 2363db02288aSLois Curfman McInnes j_new = c->j; 2364db02288aSLois Curfman McInnes i_new = c->i; 2365bfeeae90SHong Zhang 236602834360SBarry Smith for (i=0; i<nrows; i++) { 2367a2744918SBarry Smith ii = starts[i]; 2368a2744918SBarry Smith lensi = lens[i]; 2369a2744918SBarry Smith for (k=0; k<lensi; k++) { 2370a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 237102834360SBarry Smith } 237287828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2373a2744918SBarry Smith a_new += lensi; 2374a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2375a2744918SBarry Smith c->ilen[i] = lensi; 237602834360SBarry Smith } 23770e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 23783a40ed3dSBarry Smith } else { 237902834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 23800e83c824SBarry Smith ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr); 238197f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 23820e83c824SBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&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 */ 2507d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&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) { 2546b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),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 257397f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&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 */ 263397f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&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 264297f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&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]); 2767ba0e910bSBarry 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; 277116b2e9dcSShri Abhyankar ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&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); 29043bb78c5cSMatthew G Knepley 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) { 2996bbead8a2SBarry Smith ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&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: 3064bbead8a2SBarry Smith ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&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 31057087cfbeSBarry Smith extern PetscErrorCode MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*); 3106682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 31070a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3108cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3109cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3110cb5b572fSBarry Smith MatMult_SeqAIJ, 311197304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 31127c922b88SBarry Smith MatMultTranspose_SeqAIJ, 31137c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3114db4efbfdSBarry Smith 0, 3115db4efbfdSBarry Smith 0, 3116db4efbfdSBarry Smith 0, 3117db4efbfdSBarry Smith /* 10*/ 0, 3118cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3119cb5b572fSBarry Smith 0, 312041f059aeSBarry Smith MatSOR_SeqAIJ, 312117ab2063SBarry Smith MatTranspose_SeqAIJ, 312297304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3123cb5b572fSBarry Smith MatEqual_SeqAIJ, 3124cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3125cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3126cb5b572fSBarry Smith MatNorm_SeqAIJ, 312797304618SKris Buschelman /* 20*/ 0, 3128cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3129cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3130cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3131d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3132db4efbfdSBarry Smith 0, 3133db4efbfdSBarry Smith 0, 3134db4efbfdSBarry Smith 0, 3135db4efbfdSBarry Smith 0, 31364994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3137db4efbfdSBarry Smith 0, 3138db4efbfdSBarry Smith 0, 31398c778c55SBarry Smith 0, 31408c778c55SBarry Smith 0, 3141d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3142cb5b572fSBarry Smith 0, 3143cb5b572fSBarry Smith 0, 3144cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3145cb5b572fSBarry Smith 0, 3146d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 3147cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3148cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3149cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3150cb5b572fSBarry Smith MatCopy_SeqAIJ, 3151d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3152cb5b572fSBarry Smith MatScale_SeqAIJ, 3153cb5b572fSBarry Smith 0, 315479299369SBarry Smith MatDiagonalSet_SeqAIJ, 31556e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 315673a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 31573b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 31583b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 31593b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3160a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 3161d519adbfSMatthew Knepley /* 54*/ MatFDColoringCreate_SeqAIJ, 3162b9617806SBarry Smith 0, 31630513a670SBarry Smith 0, 3164cda55fadSBarry Smith MatPermute_SeqAIJ, 3165cda55fadSBarry Smith 0, 3166d519adbfSMatthew Knepley /* 59*/ 0, 3167b9b97703SBarry Smith MatDestroy_SeqAIJ, 3168b9b97703SBarry Smith MatView_SeqAIJ, 3169357abbc8SBarry Smith 0, 3170321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3171321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3172321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3173ee4f033dSBarry Smith 0, 3174ee4f033dSBarry Smith 0, 3175ee4f033dSBarry Smith 0, 3176d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3177c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3178ee4f033dSBarry Smith 0, 3179ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 3180dcf5cc72SBarry Smith 0, 3181d519adbfSMatthew Knepley /* 74*/ MatSetValuesAdifor_SeqAIJ, 31823acb8795SBarry Smith MatFDColoringApply_AIJ, 318397304618SKris Buschelman 0, 318497304618SKris Buschelman 0, 318597304618SKris Buschelman 0, 31866ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 318797304618SKris Buschelman 0, 318897304618SKris Buschelman 0, 318997304618SKris Buschelman 0, 3190bc011b1eSHong Zhang MatLoad_SeqAIJ, 3191d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31921cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31936284ec50SHong Zhang 0, 31946284ec50SHong Zhang 0, 3195bc011b1eSHong Zhang 0, 3196d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 319726be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 319826be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 319965e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 32004a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 320165e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 32026fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 32036fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 32046fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 32052121bac1SHong Zhang 0, 32062121bac1SHong Zhang /* 99*/ 0, 3207609c6c4dSKris Buschelman 0, 3208609c6c4dSKris Buschelman 0, 320987d4246cSBarry Smith MatConjugate_SeqAIJ, 321087d4246cSBarry Smith 0, 3211d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 321299cafbc1SBarry Smith MatRealPart_SeqAIJ, 3213f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3214f5edf698SHong Zhang 0, 32152bebee5dSHong Zhang 0, 3216cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3217985db425SBarry Smith 0, 32182af78befSBarry Smith MatGetRowMin_SeqAIJ, 32192af78befSBarry Smith 0, 3220599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3221d519adbfSMatthew Knepley /*114*/ 0, 3222599ef60dSHong Zhang 0, 32233c2a7987SHong Zhang 0, 3224fe97e370SBarry Smith 0, 3225fbdbba38SShri Abhyankar 0, 3226fbdbba38SShri Abhyankar /*119*/ 0, 3227fbdbba38SShri Abhyankar 0, 3228fbdbba38SShri Abhyankar 0, 322982d44351SHong Zhang 0, 3230b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 32310716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3232bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 323337868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 323437868618SMatthew G Knepley 0, 323537868618SMatthew G Knepley 0, 32365df89d91SHong Zhang /*129*/ 0, 323775648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 323875648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 323975648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3240b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3241b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 32422b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 32432b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 32442b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 32453964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 32463964eb88SJed Brown /*139*/0, 32473964eb88SJed Brown 0 32489e29f15eSvictorle }; 324917ab2063SBarry Smith 32504a2ae208SSatish Balay #undef __FUNCT__ 32514a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 32527087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3253bef8e0ddSBarry Smith { 3254bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 325597f1f81fSBarry Smith PetscInt i,nz,n; 3256bef8e0ddSBarry Smith 3257bef8e0ddSBarry Smith PetscFunctionBegin; 3258bef8e0ddSBarry Smith nz = aij->maxnz; 3259d0f46423SBarry Smith n = mat->rmap->n; 3260bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3261bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3262bef8e0ddSBarry Smith } 3263bef8e0ddSBarry Smith aij->nz = nz; 3264bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3265bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3266bef8e0ddSBarry Smith } 3267bef8e0ddSBarry Smith PetscFunctionReturn(0); 3268bef8e0ddSBarry Smith } 3269bef8e0ddSBarry Smith 32704a2ae208SSatish Balay #undef __FUNCT__ 32714a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3272bef8e0ddSBarry Smith /*@ 3273bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3274bef8e0ddSBarry Smith in the matrix. 3275bef8e0ddSBarry Smith 3276bef8e0ddSBarry Smith Input Parameters: 3277bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3278bef8e0ddSBarry Smith - indices - the column indices 3279bef8e0ddSBarry Smith 328015091d37SBarry Smith Level: advanced 328115091d37SBarry Smith 3282bef8e0ddSBarry Smith Notes: 3283bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3284bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3285bef8e0ddSBarry Smith of the MatSetValues() operation. 3286bef8e0ddSBarry Smith 3287bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3288d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3289bef8e0ddSBarry Smith 3290bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3291bef8e0ddSBarry Smith 3292b9617806SBarry Smith The indices should start with zero, not one. 3293b9617806SBarry Smith 3294bef8e0ddSBarry Smith @*/ 32957087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3296bef8e0ddSBarry Smith { 32974ac538c5SBarry Smith PetscErrorCode ierr; 3298bef8e0ddSBarry Smith 3299bef8e0ddSBarry Smith PetscFunctionBegin; 33000700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 33014482741eSBarry Smith PetscValidPointer(indices,2); 33024ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3303bef8e0ddSBarry Smith PetscFunctionReturn(0); 3304bef8e0ddSBarry Smith } 3305bef8e0ddSBarry Smith 3306be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3307be6bf707SBarry Smith 33084a2ae208SSatish Balay #undef __FUNCT__ 33094a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 33107087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3311be6bf707SBarry Smith { 3312be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33136849ba73SBarry Smith PetscErrorCode ierr; 3314d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3315be6bf707SBarry Smith 3316be6bf707SBarry Smith PetscFunctionBegin; 3317f23aa3ddSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3318be6bf707SBarry Smith 3319be6bf707SBarry Smith /* allocate space for values if not already there */ 3320be6bf707SBarry Smith if (!aij->saved_values) { 332187828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 33223bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3323be6bf707SBarry Smith } 3324be6bf707SBarry Smith 3325be6bf707SBarry Smith /* copy values over */ 332687828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3327be6bf707SBarry Smith PetscFunctionReturn(0); 3328be6bf707SBarry Smith } 3329be6bf707SBarry Smith 33304a2ae208SSatish Balay #undef __FUNCT__ 3331b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3332be6bf707SBarry Smith /*@ 3333be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3334be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3335be6bf707SBarry Smith nonlinear portion. 3336be6bf707SBarry Smith 3337be6bf707SBarry Smith Collect on Mat 3338be6bf707SBarry Smith 3339be6bf707SBarry Smith Input Parameters: 33400e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3341be6bf707SBarry Smith 334215091d37SBarry Smith Level: advanced 334315091d37SBarry Smith 3344be6bf707SBarry Smith Common Usage, with SNESSolve(): 3345be6bf707SBarry Smith $ Create Jacobian matrix 3346be6bf707SBarry Smith $ Set linear terms into matrix 3347be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3348be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3349be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3350512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3351be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3352be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3353be6bf707SBarry Smith $ In your Jacobian routine 3354be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3355be6bf707SBarry Smith $ Set nonlinear terms in matrix 3356be6bf707SBarry Smith 3357be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3358be6bf707SBarry Smith $ // build linear portion of Jacobian 3359512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3360be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3361be6bf707SBarry Smith $ loop over nonlinear iterations 3362be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3363be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3364be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3365be6bf707SBarry Smith $ Solve linear system with Jacobian 3366be6bf707SBarry Smith $ endloop 3367be6bf707SBarry Smith 3368be6bf707SBarry Smith Notes: 3369be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3370512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3371be6bf707SBarry Smith calling this routine. 3372be6bf707SBarry Smith 33730c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33740c468ba9SBarry Smith and does not allocated additional space. 33750c468ba9SBarry Smith 3376be6bf707SBarry Smith .seealso: MatRetrieveValues() 3377be6bf707SBarry Smith 3378be6bf707SBarry Smith @*/ 33797087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3380be6bf707SBarry Smith { 33814ac538c5SBarry Smith PetscErrorCode ierr; 3382be6bf707SBarry Smith 3383be6bf707SBarry Smith PetscFunctionBegin; 33840700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3385e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3386e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33874ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3388be6bf707SBarry Smith PetscFunctionReturn(0); 3389be6bf707SBarry Smith } 3390be6bf707SBarry Smith 33914a2ae208SSatish Balay #undef __FUNCT__ 33924a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 33937087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3394be6bf707SBarry Smith { 3395be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33966849ba73SBarry Smith PetscErrorCode ierr; 3397d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3398be6bf707SBarry Smith 3399be6bf707SBarry Smith PetscFunctionBegin; 3400f23aa3ddSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3401f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3402be6bf707SBarry Smith /* copy values over */ 340387828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3404be6bf707SBarry Smith PetscFunctionReturn(0); 3405be6bf707SBarry Smith } 3406be6bf707SBarry Smith 34074a2ae208SSatish Balay #undef __FUNCT__ 34084a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3409be6bf707SBarry Smith /*@ 3410be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3411be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3412be6bf707SBarry Smith nonlinear portion. 3413be6bf707SBarry Smith 3414be6bf707SBarry Smith Collect on Mat 3415be6bf707SBarry Smith 3416be6bf707SBarry Smith Input Parameters: 3417be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3418be6bf707SBarry Smith 341915091d37SBarry Smith Level: advanced 342015091d37SBarry Smith 3421be6bf707SBarry Smith .seealso: MatStoreValues() 3422be6bf707SBarry Smith 3423be6bf707SBarry Smith @*/ 34247087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3425be6bf707SBarry Smith { 34264ac538c5SBarry Smith PetscErrorCode ierr; 3427be6bf707SBarry Smith 3428be6bf707SBarry Smith PetscFunctionBegin; 34290700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3430e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3431e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 34324ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3433be6bf707SBarry Smith PetscFunctionReturn(0); 3434be6bf707SBarry Smith } 3435be6bf707SBarry Smith 3436f83d6046SBarry Smith 3437be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 34384a2ae208SSatish Balay #undef __FUNCT__ 34394a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 344017ab2063SBarry Smith /*@C 3441682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 34420d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 34436e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 344451c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 34452bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 344617ab2063SBarry Smith 3447db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3448db81eaa0SLois Curfman McInnes 344917ab2063SBarry Smith Input Parameters: 3450db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 345117ab2063SBarry Smith . m - number of rows 345217ab2063SBarry Smith . n - number of columns 345317ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 345451c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34550298fd71SBarry Smith (possibly different for each row) or NULL 345617ab2063SBarry Smith 345717ab2063SBarry Smith Output Parameter: 3458416022c9SBarry Smith . A - the matrix 345917ab2063SBarry Smith 3460175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3461ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3462175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3463175b88e8SBarry Smith 3464b259b22eSLois Curfman McInnes Notes: 346549a6f317SBarry Smith If nnz is given then nz is ignored 346649a6f317SBarry Smith 346717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 346817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 34690002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 347044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 347117ab2063SBarry Smith 347217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34730298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 34743d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 34756da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 347617ab2063SBarry Smith 3477682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 34784fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3479682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34806c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34816c7ebb05SLois Curfman McInnes 34826c7ebb05SLois Curfman McInnes Options Database Keys: 3483698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34849db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 348517ab2063SBarry Smith 3486027ccd11SLois Curfman McInnes Level: intermediate 3487027ccd11SLois Curfman McInnes 348869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 348936db0b34SBarry Smith 349017ab2063SBarry Smith @*/ 34917087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 349217ab2063SBarry Smith { 3493dfbe8321SBarry Smith PetscErrorCode ierr; 34946945ee14SBarry Smith 34953a40ed3dSBarry Smith PetscFunctionBegin; 3496f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3497117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3498c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3499d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3500273d9f13SBarry Smith PetscFunctionReturn(0); 3501273d9f13SBarry Smith } 3502273d9f13SBarry Smith 35034a2ae208SSatish Balay #undef __FUNCT__ 35044a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3505273d9f13SBarry Smith /*@C 3506273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3507273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3508273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3509273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3510273d9f13SBarry Smith 3511273d9f13SBarry Smith Collective on MPI_Comm 3512273d9f13SBarry Smith 3513273d9f13SBarry Smith Input Parameters: 3514117016b1SBarry Smith + B - The matrix-free 3515273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3516273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 35170298fd71SBarry Smith (possibly different for each row) or NULL 3518273d9f13SBarry Smith 3519273d9f13SBarry Smith Notes: 352049a6f317SBarry Smith If nnz is given then nz is ignored 352149a6f317SBarry Smith 3522273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3523273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3524273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3525273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3526273d9f13SBarry Smith 3527273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 35280298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3529273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3530273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3531273d9f13SBarry Smith 3532aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3533aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3534aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3535aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3536aa95bbe8SBarry Smith 3537a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3538a96a251dSBarry Smith entries or columns indices 3539a96a251dSBarry Smith 3540273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3541273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3542273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3543273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3544273d9f13SBarry Smith 3545273d9f13SBarry Smith Options Database Keys: 3546698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3547698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3548273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3549273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3550273d9f13SBarry Smith the user still MUST index entries starting at 0! 3551273d9f13SBarry Smith 3552273d9f13SBarry Smith Level: intermediate 3553273d9f13SBarry Smith 355469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3555273d9f13SBarry Smith 3556273d9f13SBarry Smith @*/ 35577087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3558273d9f13SBarry Smith { 35594ac538c5SBarry Smith PetscErrorCode ierr; 3560a23d5eceSKris Buschelman 3561a23d5eceSKris Buschelman PetscFunctionBegin; 35626ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35636ba663aaSJed Brown PetscValidType(B,1); 35644ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3565a23d5eceSKris Buschelman PetscFunctionReturn(0); 3566a23d5eceSKris Buschelman } 3567a23d5eceSKris Buschelman 3568a23d5eceSKris Buschelman #undef __FUNCT__ 3569a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 35707087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3571a23d5eceSKris Buschelman { 3572273d9f13SBarry Smith Mat_SeqAIJ *b; 35732576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 35746849ba73SBarry Smith PetscErrorCode ierr; 357597f1f81fSBarry Smith PetscInt i; 3576273d9f13SBarry Smith 3577273d9f13SBarry Smith PetscFunctionBegin; 35782576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3579a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3580c461c341SBarry Smith skipallocation = PETSC_TRUE; 3581c461c341SBarry Smith nz = 0; 3582c461c341SBarry Smith } 3583c461c341SBarry Smith 358426283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 358526283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3586899cda47SBarry Smith 3587435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3588e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3589b73539f3SBarry Smith if (nnz) { 3590d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3591e32f2f54SBarry 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]); 3592e32f2f54SBarry 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); 3593b73539f3SBarry Smith } 3594b73539f3SBarry Smith } 3595b73539f3SBarry Smith 3596273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35972205254eSKarl Rupp 3598273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3599273d9f13SBarry Smith 3600ab93d7beSBarry Smith if (!skipallocation) { 36012ee49352SLisandro Dalcin if (!b->imax) { 3602d0f46423SBarry Smith ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr); 36033bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 36042ee49352SLisandro Dalcin } 3605273d9f13SBarry Smith if (!nnz) { 3606435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3607c62bd62aSJed Brown else if (nz < 0) nz = 1; 3608d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3609d0f46423SBarry Smith nz = nz*B->rmap->n; 3610273d9f13SBarry Smith } else { 3611273d9f13SBarry Smith nz = 0; 3612d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3613273d9f13SBarry Smith } 3614ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 36152205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3616ab93d7beSBarry Smith 3617273d9f13SBarry Smith /* allocate the matrix space */ 36182ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3619d0f46423SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr); 36203bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3621bfeeae90SHong Zhang b->i[0] = 0; 3622d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 36235da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 36245da197adSKris Buschelman } 3625273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3626e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3627e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3628b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 3629b31eba2aSShri Abhyankar ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr); 3630b31eba2aSShri Abhyankar #endif 3631c461c341SBarry Smith } else { 3632e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3633e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3634c461c341SBarry Smith } 3635273d9f13SBarry Smith 3636273d9f13SBarry Smith b->nz = 0; 3637273d9f13SBarry Smith b->maxnz = nz; 3638273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 36392205254eSKarl Rupp if (realalloc) { 36402205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 36412205254eSKarl Rupp } 3642273d9f13SBarry Smith PetscFunctionReturn(0); 3643273d9f13SBarry Smith } 3644273d9f13SBarry Smith 3645a1661176SMatthew Knepley #undef __FUNCT__ 3646a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 364758d36128SBarry Smith /*@ 3648a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3649a1661176SMatthew Knepley 3650a1661176SMatthew Knepley Input Parameters: 3651a1661176SMatthew Knepley + B - the matrix 3652a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3653a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3654a1661176SMatthew Knepley - v - optional values in the matrix 3655a1661176SMatthew Knepley 3656a1661176SMatthew Knepley Level: developer 3657a1661176SMatthew Knepley 365858d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 365958d36128SBarry Smith 3660a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3661a1661176SMatthew Knepley 3662a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3663a1661176SMatthew Knepley @*/ 3664a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3665a1661176SMatthew Knepley { 3666a1661176SMatthew Knepley PetscErrorCode ierr; 3667a1661176SMatthew Knepley 3668a1661176SMatthew Knepley PetscFunctionBegin; 36690700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 36706ba663aaSJed Brown PetscValidType(B,1); 36714ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3672a1661176SMatthew Knepley PetscFunctionReturn(0); 3673a1661176SMatthew Knepley } 3674a1661176SMatthew Knepley 3675a1661176SMatthew Knepley #undef __FUNCT__ 3676a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 36777087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3678a1661176SMatthew Knepley { 3679a1661176SMatthew Knepley PetscInt i; 3680a1661176SMatthew Knepley PetscInt m,n; 3681a1661176SMatthew Knepley PetscInt nz; 3682a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3683a1661176SMatthew Knepley PetscScalar *values; 3684a1661176SMatthew Knepley PetscErrorCode ierr; 3685a1661176SMatthew Knepley 3686a1661176SMatthew Knepley PetscFunctionBegin; 368765e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3688779a8d59SSatish Balay 3689779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3690779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3691779a8d59SSatish Balay 3692779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3693a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 3694a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3695b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3696a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 369765e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3698a1661176SMatthew Knepley nnz[i] = nz; 3699a1661176SMatthew Knepley } 3700a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3701a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3702a1661176SMatthew Knepley 3703a1661176SMatthew Knepley if (v) { 3704a1661176SMatthew Knepley values = (PetscScalar*) v; 3705a1661176SMatthew Knepley } else { 37060e83c824SBarry Smith ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr); 3707a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));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; 3783e32f2f54SBarry 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 396538f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&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 407933b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&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) { 4088a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&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) { 410897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&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 c->compressedrow.check = a->compressedrow.check; 4133cd6b891eSBarry Smith if (a->compressedrow.use) { 41346ad4291fSHong Zhang i = a->compressedrow.nrows; 41350e83c824SBarry Smith ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr); 41366ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 41376ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 413827ea64f8SHong Zhang } else { 413927ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 41400298fd71SBarry Smith c->compressedrow.i = NULL; 41410298fd71SBarry Smith c->compressedrow.rindex = NULL; 41426ad4291fSHong Zhang } 414388e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 41444846f1f5SKris Buschelman 41452205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4146140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 41473a40ed3dSBarry Smith PetscFunctionReturn(0); 414817ab2063SBarry Smith } 414917ab2063SBarry Smith 41504a2ae208SSatish Balay #undef __FUNCT__ 4151b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 4152b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4153b24902e0SBarry Smith { 4154b24902e0SBarry Smith PetscErrorCode ierr; 4155b24902e0SBarry Smith 4156b24902e0SBarry Smith PetscFunctionBegin; 4157ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 41584b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4159a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 4160a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4161f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4162b24902e0SBarry Smith PetscFunctionReturn(0); 4163b24902e0SBarry Smith } 4164b24902e0SBarry Smith 4165b24902e0SBarry Smith #undef __FUNCT__ 41664a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 4167112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4168fbdbba38SShri Abhyankar { 4169fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4170fbdbba38SShri Abhyankar PetscErrorCode ierr; 4171fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4172fbdbba38SShri Abhyankar int fd; 4173fbdbba38SShri Abhyankar PetscMPIInt size; 4174fbdbba38SShri Abhyankar MPI_Comm comm; 4175bbead8a2SBarry Smith PetscInt bs = 1; 4176fbdbba38SShri Abhyankar 4177fbdbba38SShri Abhyankar PetscFunctionBegin; 4178fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4179fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4180fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4181bbead8a2SBarry Smith 41820298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 41830298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4184bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 41851814747fSJed Brown if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);} 4186bbead8a2SBarry Smith 4187fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4188fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4189fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4190fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4191fbdbba38SShri Abhyankar 4192bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4193fbdbba38SShri Abhyankar 4194fbdbba38SShri Abhyankar /* read in row lengths */ 4195fbdbba38SShri Abhyankar ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 4196fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4197fbdbba38SShri Abhyankar 4198fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4199fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 4200fbdbba38SShri Abhyankar if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum); 4201fbdbba38SShri Abhyankar 4202fbdbba38SShri Abhyankar /* set global size if not set already*/ 4203f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4204fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4205aabbc4fbSShri Abhyankar } else { 4206fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 4207fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 42084c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 42094c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 42104c5b953cSHong Zhang } 4211f501eaabSShri Abhyankar 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); 4212aabbc4fbSShri Abhyankar } 4213fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4214fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4215fbdbba38SShri Abhyankar 4216fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4217fbdbba38SShri Abhyankar 4218fbdbba38SShri Abhyankar /* read in nonzero values */ 4219fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4220fbdbba38SShri Abhyankar 4221fbdbba38SShri Abhyankar /* set matrix "i" values */ 4222fbdbba38SShri Abhyankar a->i[0] = 0; 4223fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4224fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4225fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4226fbdbba38SShri Abhyankar } 4227fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4228fbdbba38SShri Abhyankar 4229fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4230fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4231fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4232fbdbba38SShri Abhyankar } 4233fbdbba38SShri Abhyankar 4234fbdbba38SShri Abhyankar #undef __FUNCT__ 4235b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 4236ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 42377264ac53SSatish Balay { 42387264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4239dfbe8321SBarry Smith PetscErrorCode ierr; 4240eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4241eeffb40dSHong Zhang PetscInt k; 4242eeffb40dSHong Zhang #endif 42437264ac53SSatish Balay 42443a40ed3dSBarry Smith PetscFunctionBegin; 4245bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4246d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4247ca44d042SBarry Smith *flg = PETSC_FALSE; 4248ca44d042SBarry Smith PetscFunctionReturn(0); 4249bcd2baecSBarry Smith } 42507264ac53SSatish Balay 42517264ac53SSatish Balay /* if the a->i are the same */ 4252d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4253abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 42547264ac53SSatish Balay 42557264ac53SSatish Balay /* if a->j are the same */ 425697f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4257abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4258bcd2baecSBarry Smith 4259bcd2baecSBarry Smith /* if a->a are the same */ 4260eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4261eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4262eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4263eeffb40dSHong Zhang *flg = PETSC_FALSE; 42643a40ed3dSBarry Smith PetscFunctionReturn(0); 4265eeffb40dSHong Zhang } 4266eeffb40dSHong Zhang } 4267eeffb40dSHong Zhang #else 4268eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4269eeffb40dSHong Zhang #endif 4270eeffb40dSHong Zhang PetscFunctionReturn(0); 42717264ac53SSatish Balay } 427236db0b34SBarry Smith 42734a2ae208SSatish Balay #undef __FUNCT__ 42744a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 427505869f15SSatish Balay /*@ 427636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 427736db0b34SBarry Smith provided by the user. 427836db0b34SBarry Smith 4279c75a6043SHong Zhang Collective on MPI_Comm 428036db0b34SBarry Smith 428136db0b34SBarry Smith Input Parameters: 428236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 428336db0b34SBarry Smith . m - number of rows 428436db0b34SBarry Smith . n - number of columns 428536db0b34SBarry Smith . i - row indices 428636db0b34SBarry Smith . j - column indices 428736db0b34SBarry Smith - a - matrix values 428836db0b34SBarry Smith 428936db0b34SBarry Smith Output Parameter: 429036db0b34SBarry Smith . mat - the matrix 429136db0b34SBarry Smith 429236db0b34SBarry Smith Level: intermediate 429336db0b34SBarry Smith 429436db0b34SBarry Smith Notes: 42950551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4296292fb18eSBarry Smith once the matrix is destroyed and not before 429736db0b34SBarry Smith 429836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 429936db0b34SBarry Smith 4300bfeeae90SHong Zhang The i and j indices are 0 based 430136db0b34SBarry Smith 4302a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4303a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4304a4552177SSatish Balay as shown: 4305a4552177SSatish Balay 4306a4552177SSatish Balay 1 0 0 4307a4552177SSatish Balay 2 0 3 4308a4552177SSatish Balay 4 5 6 4309a4552177SSatish Balay 4310a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 43119985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4312a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4313a4552177SSatish Balay 43149985e31cSBarry Smith 431569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 431636db0b34SBarry Smith 431736db0b34SBarry Smith @*/ 43187087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat) 431936db0b34SBarry Smith { 4320dfbe8321SBarry Smith PetscErrorCode ierr; 4321cbcfb4deSHong Zhang PetscInt ii; 432236db0b34SBarry Smith Mat_SeqAIJ *aij; 4323cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4324cbcfb4deSHong Zhang PetscInt jj; 4325cbcfb4deSHong Zhang #endif 432636db0b34SBarry Smith 432736db0b34SBarry Smith PetscFunctionBegin; 4328f23aa3ddSBarry Smith if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4329f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4330f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4331a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4332ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4333ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4334ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4335ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 4336ab93d7beSBarry Smith 433736db0b34SBarry Smith aij->i = i; 433836db0b34SBarry Smith aij->j = j; 433936db0b34SBarry Smith aij->a = a; 434036db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 434136db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4342e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4343e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 434436db0b34SBarry Smith 434536db0b34SBarry Smith for (ii=0; ii<m; ii++) { 434636db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 43472515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 4348e32f2f54SBarry 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]); 43499985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 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 not sorted",jj-i[ii],j[jj],ii); 4351e32f2f54SBarry 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); 43529985e31cSBarry Smith } 435336db0b34SBarry Smith #endif 435436db0b34SBarry Smith } 43552515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 435636db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 4357e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 4358e32f2f54SBarry 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]); 435936db0b34SBarry Smith } 436036db0b34SBarry Smith #endif 436136db0b34SBarry Smith 4362b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4363b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 436436db0b34SBarry Smith PetscFunctionReturn(0); 436536db0b34SBarry Smith } 43668a0b0e6bSVictor Minden #undef __FUNCT__ 43678a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple" 436880ef6e79SMatthew G Knepley /*@C 4369d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 43708a0b0e6bSVictor Minden provided by the user. 43718a0b0e6bSVictor Minden 43728a0b0e6bSVictor Minden Collective on MPI_Comm 43738a0b0e6bSVictor Minden 43748a0b0e6bSVictor Minden Input Parameters: 43758a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 43768a0b0e6bSVictor Minden . m - number of rows 43778a0b0e6bSVictor Minden . n - number of columns 43788a0b0e6bSVictor Minden . i - row indices 43798a0b0e6bSVictor Minden . j - column indices 43801230e6d1SVictor Minden . a - matrix values 43811230e6d1SVictor Minden . nz - number of nonzeros 43821230e6d1SVictor Minden - idx - 0 or 1 based 43838a0b0e6bSVictor Minden 43848a0b0e6bSVictor Minden Output Parameter: 43858a0b0e6bSVictor Minden . mat - the matrix 43868a0b0e6bSVictor Minden 43878a0b0e6bSVictor Minden Level: intermediate 43888a0b0e6bSVictor Minden 43898a0b0e6bSVictor Minden Notes: 43908a0b0e6bSVictor Minden The i and j indices are 0 based 43918a0b0e6bSVictor Minden 43928a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 43938a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 43948a0b0e6bSVictor Minden as shown: 43958a0b0e6bSVictor Minden 43968a0b0e6bSVictor Minden 1 0 0 43978a0b0e6bSVictor Minden 2 0 3 43988a0b0e6bSVictor Minden 4 5 6 43998a0b0e6bSVictor Minden 44008a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 44018a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 44028a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 44038a0b0e6bSVictor Minden 44048a0b0e6bSVictor Minden 440569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 44068a0b0e6bSVictor Minden 44078a0b0e6bSVictor Minden @*/ 44081230e6d1SVictor Minden PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx) 44098a0b0e6bSVictor Minden { 44108a0b0e6bSVictor Minden PetscErrorCode ierr; 4411d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 44128a0b0e6bSVictor Minden 44138a0b0e6bSVictor Minden 44148a0b0e6bSVictor Minden PetscFunctionBegin; 4415d021a1c5SVictor Minden ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 44161230e6d1SVictor Minden ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr); 44171230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 44181230e6d1SVictor Minden nnz[i[ii]] += 1; 44191230e6d1SVictor Minden } 44208a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 44218a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4422a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 44238a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 44241230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 44251230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 44261230e6d1SVictor Minden if (idx) { 44271230e6d1SVictor Minden row = i[ii] - 1; 44281230e6d1SVictor Minden col = j[ii] - 1; 44291230e6d1SVictor Minden } else { 44301230e6d1SVictor Minden row = i[ii]; 44311230e6d1SVictor Minden col = j[ii]; 44328a0b0e6bSVictor Minden } 44331230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 44348a0b0e6bSVictor Minden } 44358a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 44368a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4437d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 44388a0b0e6bSVictor Minden PetscFunctionReturn(0); 44398a0b0e6bSVictor Minden } 444036db0b34SBarry Smith 4441cc8ba8e1SBarry Smith #undef __FUNCT__ 4442ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4443dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4444cc8ba8e1SBarry Smith { 4445dfbe8321SBarry Smith PetscErrorCode ierr; 4446cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 444736db0b34SBarry Smith 4448cc8ba8e1SBarry Smith PetscFunctionBegin; 44498ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4450cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4451cc8ba8e1SBarry Smith a->coloring = coloring; 445212c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 445397f1f81fSBarry Smith PetscInt i,*larray; 445412c595b3SBarry Smith ISColoring ocoloring; 445508b6dcc0SBarry Smith ISColoringValue *colors; 445612c595b3SBarry Smith 445712c595b3SBarry Smith /* set coloring for diagonal portion */ 44580e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr); 44592205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) larray[i] = i; 44600298fd71SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr); 44610e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 44622205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]]; 446312c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4464d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 446512c595b3SBarry Smith a->coloring = ocoloring; 446612c595b3SBarry Smith } 4467cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4468cc8ba8e1SBarry Smith } 4469cc8ba8e1SBarry Smith 4470ee4f033dSBarry Smith #undef __FUNCT__ 4471ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 447297f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4473ee4f033dSBarry Smith { 4474ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4475d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 447654f21887SBarry Smith MatScalar *v = a->a; 447754f21887SBarry Smith PetscScalar *values = (PetscScalar*)advalues; 447808b6dcc0SBarry Smith ISColoringValue *color; 4479ee4f033dSBarry Smith 4480ee4f033dSBarry Smith PetscFunctionBegin; 4481e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4482ee4f033dSBarry Smith color = a->coloring->colors; 4483ee4f033dSBarry Smith /* loop over rows */ 4484ee4f033dSBarry Smith for (i=0; i<m; i++) { 4485ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4486ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 44872205254eSKarl Rupp for (j=0; j<nz; j++) *v++ = values[color[*jj++]]; 4488ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4489cc8ba8e1SBarry Smith } 4490cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4491cc8ba8e1SBarry Smith } 449236db0b34SBarry Smith 4493acf2f550SJed Brown #undef __FUNCT__ 4494acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal" 4495acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4496acf2f550SJed Brown { 4497acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4498acf2f550SJed Brown PetscErrorCode ierr; 4499acf2f550SJed Brown 4500acf2f550SJed Brown PetscFunctionBegin; 4501acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4502acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 45032205254eSKarl Rupp 4504acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4505acf2f550SJed Brown PetscFunctionReturn(0); 4506acf2f550SJed Brown } 4507acf2f550SJed Brown 450881824310SBarry Smith /* 450981824310SBarry Smith Special version for direct calls from Fortran 451081824310SBarry Smith */ 4511b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h> 451281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 451381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 451481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 451581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 451681824310SBarry Smith #endif 451781824310SBarry Smith 451881824310SBarry Smith /* Change these macros so can be used in void function */ 451981824310SBarry Smith #undef CHKERRQ 4520ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 452181824310SBarry Smith #undef SETERRQ2 4522e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 45234994cf47SJed Brown #undef SETERRQ3 45244994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 452581824310SBarry Smith 452681824310SBarry Smith #undef __FUNCT__ 452781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 45288cc058d9SJed 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) 452981824310SBarry Smith { 453081824310SBarry Smith Mat A = *AA; 453181824310SBarry Smith PetscInt m = *mm, n = *nn; 453281824310SBarry Smith InsertMode is = *isis; 453381824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 453481824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 453581824310SBarry Smith PetscInt *imax,*ai,*ailen; 453681824310SBarry Smith PetscErrorCode ierr; 453781824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 453854f21887SBarry Smith MatScalar *ap,value,*aa; 4539ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4540ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 454181824310SBarry Smith 454281824310SBarry Smith PetscFunctionBegin; 45434994cf47SJed Brown MatCheckPreallocated(A,1); 454481824310SBarry Smith imax = a->imax; 454581824310SBarry Smith ai = a->i; 454681824310SBarry Smith ailen = a->ilen; 454781824310SBarry Smith aj = a->j; 454881824310SBarry Smith aa = a->a; 454981824310SBarry Smith 455081824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 455181824310SBarry Smith row = im[k]; 455281824310SBarry Smith if (row < 0) continue; 455381824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4554ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 455581824310SBarry Smith #endif 455681824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 455781824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 455881824310SBarry Smith low = 0; 455981824310SBarry Smith high = nrow; 456081824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 456181824310SBarry Smith if (in[l] < 0) continue; 456281824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4563ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 456481824310SBarry Smith #endif 456581824310SBarry Smith col = in[l]; 45662205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 45672205254eSKarl Rupp else value = v[k + l*m]; 45682205254eSKarl Rupp 456981824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 457081824310SBarry Smith 45712205254eSKarl Rupp if (col <= lastcol) low = 0; 45722205254eSKarl Rupp else high = nrow; 457381824310SBarry Smith lastcol = col; 457481824310SBarry Smith while (high-low > 5) { 457581824310SBarry Smith t = (low+high)/2; 457681824310SBarry Smith if (rp[t] > col) high = t; 457781824310SBarry Smith else low = t; 457881824310SBarry Smith } 457981824310SBarry Smith for (i=low; i<high; i++) { 458081824310SBarry Smith if (rp[i] > col) break; 458181824310SBarry Smith if (rp[i] == col) { 458281824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 458381824310SBarry Smith else ap[i] = value; 458481824310SBarry Smith goto noinsert; 458581824310SBarry Smith } 458681824310SBarry Smith } 458781824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 458881824310SBarry Smith if (nonew == 1) goto noinsert; 4589ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4590fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 459181824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 459281824310SBarry Smith /* shift up all the later entries in this row */ 459381824310SBarry Smith for (ii=N; ii>=i; ii--) { 459481824310SBarry Smith rp[ii+1] = rp[ii]; 459581824310SBarry Smith ap[ii+1] = ap[ii]; 459681824310SBarry Smith } 459781824310SBarry Smith rp[i] = col; 459881824310SBarry Smith ap[i] = value; 459981824310SBarry Smith noinsert:; 460081824310SBarry Smith low = i + 1; 460181824310SBarry Smith } 460281824310SBarry Smith ailen[row] = nrow; 460381824310SBarry Smith } 460481824310SBarry Smith A->same_nonzero = PETSC_FALSE; 460581824310SBarry Smith PetscFunctionReturnVoid(); 460681824310SBarry Smith } 46079f7953f8SBarry Smith 460862298a1eSBarry Smith 4609