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 278*7cee066cSHong Zhang /* 279*7cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 280*7cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 281*7cee066cSHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqAIJ() 282*7cee066cSHong Zhang */ 283*7cee066cSHong Zhang #undef __FUNCT__ 284*7cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color" 285*7cee066cSHong 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) 286*7cee066cSHong Zhang { 287*7cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 288*7cee066cSHong Zhang PetscErrorCode ierr; 289*7cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 290*7cee066cSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 291*7cee066cSHong Zhang PetscInt *cspidx; 292*7cee066cSHong Zhang 293*7cee066cSHong Zhang PetscFunctionBegin; 294*7cee066cSHong Zhang *nn = n; 295*7cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 296*7cee066cSHong Zhang if (symmetric) { 297*7cee066cSHong Zhang SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatGetColumnIJ_SeqAIJ_Color() not supported for the case symmetric"); 298*7cee066cSHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 299*7cee066cSHong Zhang } else { 300*7cee066cSHong Zhang ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 301*7cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 302*7cee066cSHong Zhang ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 303*7cee066cSHong Zhang ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 304*7cee066cSHong Zhang ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cspidx);CHKERRQ(ierr); 305*7cee066cSHong Zhang jj = a->j; 306*7cee066cSHong Zhang for (i=0; i<nz; i++) { 307*7cee066cSHong Zhang collengths[jj[i]]++; 308*7cee066cSHong Zhang } 309*7cee066cSHong Zhang cia[0] = oshift; 310*7cee066cSHong Zhang for (i=0; i<n; i++) { 311*7cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 312*7cee066cSHong Zhang } 313*7cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 314*7cee066cSHong Zhang jj = a->j; 315*7cee066cSHong Zhang for (row=0; row<m; row++) { 316*7cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 317*7cee066cSHong Zhang for (i=0; i<mr; i++) { 318*7cee066cSHong Zhang col = *jj++; 319*7cee066cSHong Zhang 320*7cee066cSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 321*7cee066cSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 322*7cee066cSHong Zhang } 323*7cee066cSHong Zhang } 324*7cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 325*7cee066cSHong Zhang *ia = cia; *ja = cja; 326*7cee066cSHong Zhang *spidx = cspidx; 327*7cee066cSHong Zhang } 328*7cee066cSHong Zhang PetscFunctionReturn(0); 329*7cee066cSHong Zhang } 330*7cee066cSHong Zhang 331*7cee066cSHong Zhang #undef __FUNCT__ 332*7cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color" 333*7cee066cSHong 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) 334*7cee066cSHong Zhang { 335*7cee066cSHong Zhang PetscErrorCode ierr; 336*7cee066cSHong Zhang 337*7cee066cSHong Zhang PetscFunctionBegin; 338*7cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 339*7cee066cSHong Zhang 340*7cee066cSHong Zhang ierr = PetscFree(*ia);CHKERRQ(ierr); 341*7cee066cSHong Zhang ierr = PetscFree(*ja);CHKERRQ(ierr); 342*7cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 343*7cee066cSHong Zhang PetscFunctionReturn(0); 344*7cee066cSHong Zhang } 345*7cee066cSHong Zhang 34687d4246cSBarry Smith #undef __FUNCT__ 34787d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 34887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 34987d4246cSBarry Smith { 35087d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 35187d4246cSBarry Smith PetscInt *ai = a->i; 35287d4246cSBarry Smith PetscErrorCode ierr; 35387d4246cSBarry Smith 35487d4246cSBarry Smith PetscFunctionBegin; 35587d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 35687d4246cSBarry Smith PetscFunctionReturn(0); 35787d4246cSBarry Smith } 35887d4246cSBarry Smith 3594a2ae208SSatish Balay #undef __FUNCT__ 3604a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 36197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 36217ab2063SBarry Smith { 363416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 364e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 36597f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 3666849ba73SBarry Smith PetscErrorCode ierr; 367e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 36854f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 369ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 370ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 37117ab2063SBarry Smith 3723a40ed3dSBarry Smith PetscFunctionBegin; 37371fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 37417ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 375416022c9SBarry Smith row = im[k]; 3765ef9f2a5SBarry Smith if (row < 0) continue; 3772515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 378e32f2f54SBarry 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); 3793b2fbd54SBarry Smith #endif 380bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 38117ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 382416022c9SBarry Smith low = 0; 383c71e6ed7SBarry Smith high = nrow; 38417ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 3855ef9f2a5SBarry Smith if (in[l] < 0) continue; 3862515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 387e32f2f54SBarry 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); 3883b2fbd54SBarry Smith #endif 389bfeeae90SHong Zhang col = in[l]; 39016371a99SBarry Smith if (v) { 3914b0e389bSBarry Smith if (roworiented) { 3925ef9f2a5SBarry Smith value = v[l + k*n]; 393bef8e0ddSBarry Smith } else { 3944b0e389bSBarry Smith value = v[k + l*m]; 3954b0e389bSBarry Smith } 39616371a99SBarry Smith } else { 39775567043SBarry Smith value = 0.; 39816371a99SBarry Smith } 399abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 40036db0b34SBarry Smith 4012205254eSKarl Rupp if (col <= lastcol) low = 0; 4022205254eSKarl Rupp else high = nrow; 403e2ee6c50SBarry Smith lastcol = col; 404416022c9SBarry Smith while (high-low > 5) { 405416022c9SBarry Smith t = (low+high)/2; 406416022c9SBarry Smith if (rp[t] > col) high = t; 407416022c9SBarry Smith else low = t; 40817ab2063SBarry Smith } 409416022c9SBarry Smith for (i=low; i<high; i++) { 41017ab2063SBarry Smith if (rp[i] > col) break; 41117ab2063SBarry Smith if (rp[i] == col) { 412416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 41317ab2063SBarry Smith else ap[i] = value; 414e44c0bd4SBarry Smith low = i + 1; 41517ab2063SBarry Smith goto noinsert; 41617ab2063SBarry Smith } 41717ab2063SBarry Smith } 418abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 419c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 420e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 421fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 422c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 423416022c9SBarry Smith /* shift up all the later entries in this row */ 424416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 42517ab2063SBarry Smith rp[ii+1] = rp[ii]; 42617ab2063SBarry Smith ap[ii+1] = ap[ii]; 42717ab2063SBarry Smith } 42817ab2063SBarry Smith rp[i] = col; 42917ab2063SBarry Smith ap[i] = value; 430416022c9SBarry Smith low = i + 1; 431e44c0bd4SBarry Smith noinsert:; 43217ab2063SBarry Smith } 43317ab2063SBarry Smith ailen[row] = nrow; 43417ab2063SBarry Smith } 43588e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 4363a40ed3dSBarry Smith PetscFunctionReturn(0); 43717ab2063SBarry Smith } 43817ab2063SBarry Smith 43981824310SBarry Smith 4404a2ae208SSatish Balay #undef __FUNCT__ 4414a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 442a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4437eb43aa7SLois Curfman McInnes { 4447eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 44597f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 44697f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 44754f21887SBarry Smith MatScalar *ap,*aa = a->a; 4487eb43aa7SLois Curfman McInnes 4493a40ed3dSBarry Smith PetscFunctionBegin; 4507eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 4517eb43aa7SLois Curfman McInnes row = im[k]; 452e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 453e32f2f54SBarry 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); 454bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 4557eb43aa7SLois Curfman McInnes nrow = ailen[row]; 4567eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 457e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 458e32f2f54SBarry 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); 459bfeeae90SHong Zhang col = in[l]; 4607eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 4617eb43aa7SLois Curfman McInnes while (high-low > 5) { 4627eb43aa7SLois Curfman McInnes t = (low+high)/2; 4637eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 4647eb43aa7SLois Curfman McInnes else low = t; 4657eb43aa7SLois Curfman McInnes } 4667eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 4677eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 4687eb43aa7SLois Curfman McInnes if (rp[i] == col) { 469b49de8d1SLois Curfman McInnes *v++ = ap[i]; 4707eb43aa7SLois Curfman McInnes goto finished; 4717eb43aa7SLois Curfman McInnes } 4727eb43aa7SLois Curfman McInnes } 47397e567efSBarry Smith *v++ = 0.0; 4747eb43aa7SLois Curfman McInnes finished:; 4757eb43aa7SLois Curfman McInnes } 4767eb43aa7SLois Curfman McInnes } 4773a40ed3dSBarry Smith PetscFunctionReturn(0); 4787eb43aa7SLois Curfman McInnes } 4797eb43aa7SLois Curfman McInnes 48017ab2063SBarry Smith 4814a2ae208SSatish Balay #undef __FUNCT__ 4824a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 483dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 48417ab2063SBarry Smith { 485416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4866849ba73SBarry Smith PetscErrorCode ierr; 4876f69ff64SBarry Smith PetscInt i,*col_lens; 4886f69ff64SBarry Smith int fd; 489b37d52dbSMark F. Adams FILE *file; 49017ab2063SBarry Smith 4913a40ed3dSBarry Smith PetscFunctionBegin; 492b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 493d0f46423SBarry Smith ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 4942205254eSKarl Rupp 4950700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 496d0f46423SBarry Smith col_lens[1] = A->rmap->n; 497d0f46423SBarry Smith col_lens[2] = A->cmap->n; 498416022c9SBarry Smith col_lens[3] = a->nz; 499416022c9SBarry Smith 500416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 501d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 502416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 50317ab2063SBarry Smith } 504d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 505606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 506416022c9SBarry Smith 507416022c9SBarry Smith /* store column indices (zero start index) */ 5086f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 509416022c9SBarry Smith 510416022c9SBarry Smith /* store nonzero values */ 5116f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 512b37d52dbSMark F. Adams 513b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 514b37d52dbSMark F. Adams if (file) { 515b37d52dbSMark F. Adams fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs); 516b37d52dbSMark F. Adams } 5173a40ed3dSBarry Smith PetscFunctionReturn(0); 51817ab2063SBarry Smith } 519416022c9SBarry Smith 52009573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 521cd155464SBarry Smith 5224a2ae208SSatish Balay #undef __FUNCT__ 5234a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 524dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 525416022c9SBarry Smith { 526416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 527dfbe8321SBarry Smith PetscErrorCode ierr; 528d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,shift=0; 529e060cb09SBarry Smith const char *name; 530f3ef73ceSBarry Smith PetscViewerFormat format; 53117ab2063SBarry Smith 5323a40ed3dSBarry Smith PetscFunctionBegin; 533b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 53471c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 53597f1f81fSBarry Smith PetscInt nofinalvalue = 0; 536014b3a6eSMark Adams if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) { 537d00d2cf4SBarry Smith nofinalvalue = 1; 538d00d2cf4SBarry Smith } 539d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 540d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 54177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 54277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 543b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 54417ab2063SBarry Smith 54517ab2063SBarry Smith for (i=0; i<m; i++) { 546416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 547aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 54877431f27SBarry 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); 54917ab2063SBarry Smith #else 55077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 55117ab2063SBarry Smith #endif 55217ab2063SBarry Smith } 55317ab2063SBarry Smith } 554d00d2cf4SBarry Smith if (nofinalvalue) { 555d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 556d00d2cf4SBarry Smith } 557317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 558fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 559d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 56068369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 561cd155464SBarry Smith PetscFunctionReturn(0); 562fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 563d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 564dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 56544cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 56677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 56744cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 568aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 56936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 570ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 57136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 572ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 57336db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 574ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 5756831982aSBarry Smith } 57644cd7ae7SLois Curfman McInnes #else 577ba0e910bSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);} 57844cd7ae7SLois Curfman McInnes #endif 57944cd7ae7SLois Curfman McInnes } 580b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 58144cd7ae7SLois Curfman McInnes } 582d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 583fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 58497f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 585d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 586dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 58797f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 588496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 589496be53dSLois Curfman McInnes sptr[i] = nzd+1; 590496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 591496be53dSLois Curfman McInnes if (a->j[j] >= i) { 592aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 59336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 594496be53dSLois Curfman McInnes #else 595496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 596496be53dSLois Curfman McInnes #endif 597496be53dSLois Curfman McInnes } 598496be53dSLois Curfman McInnes } 599496be53dSLois Curfman McInnes } 6002e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 60177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 6022e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 6032205254eSKarl Rupp if (i+4<m) { 6042205254eSKarl 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); 6052205254eSKarl Rupp } else if (i+3<m) { 6062205254eSKarl 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); 6072205254eSKarl Rupp } else if (i+2<m) { 6082205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6092205254eSKarl Rupp } else if (i+1<m) { 6102205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6112205254eSKarl Rupp } else if (i<m) { 6122205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6132205254eSKarl Rupp } else { 6142205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6152205254eSKarl Rupp } 616496be53dSLois Curfman McInnes } 617b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 618606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 619496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 620496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 62177431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 622496be53dSLois Curfman McInnes } 623b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 624496be53dSLois Curfman McInnes } 625b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 626496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 627496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 628496be53dSLois Curfman McInnes if (a->j[j] >= i) { 629aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 63036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 631b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6326831982aSBarry Smith } 633496be53dSLois Curfman McInnes #else 634b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 635496be53dSLois Curfman McInnes #endif 636496be53dSLois Curfman McInnes } 637496be53dSLois Curfman McInnes } 638b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 639496be53dSLois Curfman McInnes } 640d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 641fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 64297f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 64387828ca2SBarry Smith PetscScalar value; 64402594712SBarry Smith 645d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 646dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 64702594712SBarry Smith for (i=0; i<m; i++) { 64802594712SBarry Smith jcnt = 0; 649d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 650e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 65102594712SBarry Smith value = a->a[cnt++]; 652e24b481bSBarry Smith jcnt++; 65302594712SBarry Smith } else { 65402594712SBarry Smith value = 0.0; 65502594712SBarry Smith } 656aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 657b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 65802594712SBarry Smith #else 659b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 66002594712SBarry Smith #endif 66102594712SBarry Smith } 662b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 66302594712SBarry Smith } 664d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6653c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 666d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 667dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 6683c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 6693c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 6703c215bfdSMatthew Knepley #else 6713c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 6723c215bfdSMatthew Knepley #endif 673d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 6743c215bfdSMatthew Knepley for (i=0; i<m; i++) { 6753c215bfdSMatthew Knepley for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 6763c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 6773c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 678ba0e910bSBarry 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); 6793c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 680ba0e910bSBarry 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); 6813c215bfdSMatthew Knepley } else { 682ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 6833c215bfdSMatthew Knepley } 6843c215bfdSMatthew Knepley #else 685ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+shift, a->j[j]+shift, (double)a->a[j]);CHKERRQ(ierr); 6863c215bfdSMatthew Knepley #endif 6873c215bfdSMatthew Knepley } 6883c215bfdSMatthew Knepley } 689d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6903a40ed3dSBarry Smith } else { 691d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 692dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 693d5f3da31SBarry Smith if (A->factortype) { 69416cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 69516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 69616cd7e1dSShri Abhyankar /* L part */ 69716cd7e1dSShri Abhyankar for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 69816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 69916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 700ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 70116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 702ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 70316cd7e1dSShri Abhyankar } else { 704ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 70516cd7e1dSShri Abhyankar } 70616cd7e1dSShri Abhyankar #else 707ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 70816cd7e1dSShri Abhyankar #endif 70916cd7e1dSShri Abhyankar } 71016cd7e1dSShri Abhyankar /* diagonal */ 71116cd7e1dSShri Abhyankar j = a->diag[i]; 71216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 71316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 714ba0e910bSBarry 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); 71516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 716ba0e910bSBarry 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); 71716cd7e1dSShri Abhyankar } else { 718ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 71916cd7e1dSShri Abhyankar } 72016cd7e1dSShri Abhyankar #else 721ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr); 72216cd7e1dSShri Abhyankar #endif 72316cd7e1dSShri Abhyankar 72416cd7e1dSShri Abhyankar /* U part */ 72516cd7e1dSShri Abhyankar for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) { 72616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 72716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 728ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 72916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 730ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 73116cd7e1dSShri Abhyankar } else { 732ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 73316cd7e1dSShri Abhyankar } 73416cd7e1dSShri Abhyankar #else 735ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 73616cd7e1dSShri Abhyankar #endif 73716cd7e1dSShri Abhyankar } 73816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 73916cd7e1dSShri Abhyankar } 74016cd7e1dSShri Abhyankar } else { 74117ab2063SBarry Smith for (i=0; i<m; i++) { 74277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 743416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 744aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 74536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 746ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 74736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 748ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7493a40ed3dSBarry Smith } else { 750ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 75117ab2063SBarry Smith } 75217ab2063SBarry Smith #else 753ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 75417ab2063SBarry Smith #endif 75517ab2063SBarry Smith } 756b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 75717ab2063SBarry Smith } 75816cd7e1dSShri Abhyankar } 759d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 76017ab2063SBarry Smith } 761b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 7623a40ed3dSBarry Smith PetscFunctionReturn(0); 763416022c9SBarry Smith } 764416022c9SBarry Smith 7659804daf3SBarry Smith #include <petscdraw.h> 7664a2ae208SSatish Balay #undef __FUNCT__ 7674a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 768dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 769416022c9SBarry Smith { 770480ef9eaSBarry Smith Mat A = (Mat) Aa; 771416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 772dfbe8321SBarry Smith PetscErrorCode ierr; 773d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 77436db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 775b0a32e0cSBarry Smith PetscViewer viewer; 776f3ef73ceSBarry Smith PetscViewerFormat format; 777cddf8d76SBarry Smith 7783a40ed3dSBarry Smith PetscFunctionBegin; 779480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 780b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 78119bcc07fSBarry Smith 782b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 783416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 7840513a670SBarry Smith 785fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 7860513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 787b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 788416022c9SBarry Smith for (i=0; i<m; i++) { 789cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 790bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 791bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 79236db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 793b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 794cddf8d76SBarry Smith } 795cddf8d76SBarry Smith } 796b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 797cddf8d76SBarry Smith for (i=0; i<m; i++) { 798cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 799bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 800bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 801cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 802b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 803cddf8d76SBarry Smith } 804cddf8d76SBarry Smith } 805b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 806cddf8d76SBarry Smith for (i=0; i<m; i++) { 807cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 808bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 809bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 81036db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 811b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 812416022c9SBarry Smith } 813416022c9SBarry Smith } 8140513a670SBarry Smith } else { 8150513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8160513a670SBarry Smith /* first determine max of all nonzero values */ 81797f1f81fSBarry Smith PetscInt nz = a->nz,count; 818b0a32e0cSBarry Smith PetscDraw popup; 81936db0b34SBarry Smith PetscReal scale; 8200513a670SBarry Smith 8210513a670SBarry Smith for (i=0; i<nz; i++) { 8220513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8230513a670SBarry Smith } 824b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 825b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 8262205254eSKarl Rupp if (popup) { 8272205254eSKarl Rupp ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr); 8282205254eSKarl Rupp } 8290513a670SBarry Smith count = 0; 8300513a670SBarry Smith for (i=0; i<m; i++) { 8310513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 832bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 833bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 83497f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 835b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8360513a670SBarry Smith count++; 8370513a670SBarry Smith } 8380513a670SBarry Smith } 8390513a670SBarry Smith } 840480ef9eaSBarry Smith PetscFunctionReturn(0); 841480ef9eaSBarry Smith } 842cddf8d76SBarry Smith 8439804daf3SBarry Smith #include <petscdraw.h> 8444a2ae208SSatish Balay #undef __FUNCT__ 8454a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 846dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 847480ef9eaSBarry Smith { 848dfbe8321SBarry Smith PetscErrorCode ierr; 849b0a32e0cSBarry Smith PetscDraw draw; 85036db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 851ace3abfcSBarry Smith PetscBool isnull; 852480ef9eaSBarry Smith 853480ef9eaSBarry Smith PetscFunctionBegin; 854b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 855b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 856480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 857480ef9eaSBarry Smith 858480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 859d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 860480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 861b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 862b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 8630298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 8643a40ed3dSBarry Smith PetscFunctionReturn(0); 865416022c9SBarry Smith } 866416022c9SBarry Smith 8674a2ae208SSatish Balay #undef __FUNCT__ 8684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 869dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 870416022c9SBarry Smith { 871dfbe8321SBarry Smith PetscErrorCode ierr; 872ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 873416022c9SBarry Smith 8743a40ed3dSBarry Smith PetscFunctionBegin; 875251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 876251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 877251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 878c45a1595SBarry Smith if (iascii) { 8793a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 8800f5bd95cSBarry Smith } else if (isbinary) { 8813a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 8820f5bd95cSBarry Smith } else if (isdraw) { 8833a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 88411aeaf0aSBarry Smith } 8854108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 8863a40ed3dSBarry Smith PetscFunctionReturn(0); 88717ab2063SBarry Smith } 88819bcc07fSBarry Smith 8894a2ae208SSatish Balay #undef __FUNCT__ 8904a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 891dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 89217ab2063SBarry Smith { 893416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8946849ba73SBarry Smith PetscErrorCode ierr; 89597f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 896d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 89754f21887SBarry Smith MatScalar *aa = a->a,*ap; 8983447b6efSHong Zhang PetscReal ratio = 0.6; 89917ab2063SBarry Smith 9003a40ed3dSBarry Smith PetscFunctionBegin; 9013a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 90217ab2063SBarry Smith 90343ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 90417ab2063SBarry Smith for (i=1; i<m; i++) { 905416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 90617ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 90794a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 90817ab2063SBarry Smith if (fshift) { 909bfeeae90SHong Zhang ip = aj + ai[i]; 910bfeeae90SHong Zhang ap = aa + ai[i]; 91117ab2063SBarry Smith N = ailen[i]; 91217ab2063SBarry Smith for (j=0; j<N; j++) { 91317ab2063SBarry Smith ip[j-fshift] = ip[j]; 91417ab2063SBarry Smith ap[j-fshift] = ap[j]; 91517ab2063SBarry Smith } 91617ab2063SBarry Smith } 91717ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 91817ab2063SBarry Smith } 91917ab2063SBarry Smith if (m) { 92017ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 92117ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 92217ab2063SBarry Smith } 92317ab2063SBarry Smith /* reset ilen and imax for each row */ 92417ab2063SBarry Smith for (i=0; i<m; i++) { 92517ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 92617ab2063SBarry Smith } 927bfeeae90SHong Zhang a->nz = ai[m]; 92865e19b50SBarry 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); 92917ab2063SBarry Smith 93009f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 931d0f46423SBarry 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); 932ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 933ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9342205254eSKarl Rupp 9358e58a170SBarry Smith A->info.mallocs += a->reallocs; 936dd5f02e7SSatish Balay a->reallocs = 0; 9374e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 93836db0b34SBarry Smith a->rmax = rmax; 9394e220ebcSLois Curfman McInnes 940cd6b891eSBarry Smith ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 9412205254eSKarl Rupp 94288e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 94371c2f376SKris Buschelman 9444108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 94571f1c65dSBarry Smith 946acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9473a40ed3dSBarry Smith PetscFunctionReturn(0); 94817ab2063SBarry Smith } 94917ab2063SBarry Smith 9504a2ae208SSatish Balay #undef __FUNCT__ 95199cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 95299cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 95399cafbc1SBarry Smith { 95499cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 95599cafbc1SBarry Smith PetscInt i,nz = a->nz; 95654f21887SBarry Smith MatScalar *aa = a->a; 957acf2f550SJed Brown PetscErrorCode ierr; 95899cafbc1SBarry Smith 95999cafbc1SBarry Smith PetscFunctionBegin; 96099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 961acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 96299cafbc1SBarry Smith PetscFunctionReturn(0); 96399cafbc1SBarry Smith } 96499cafbc1SBarry Smith 96599cafbc1SBarry Smith #undef __FUNCT__ 96699cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 96799cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 96899cafbc1SBarry Smith { 96999cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 97099cafbc1SBarry Smith PetscInt i,nz = a->nz; 97154f21887SBarry Smith MatScalar *aa = a->a; 972acf2f550SJed Brown PetscErrorCode ierr; 97399cafbc1SBarry Smith 97499cafbc1SBarry Smith PetscFunctionBegin; 97599cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 976acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 97799cafbc1SBarry Smith PetscFunctionReturn(0); 97899cafbc1SBarry Smith } 97999cafbc1SBarry Smith 98078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 98178b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A) 98278b84d54SShri Abhyankar { 98378b84d54SShri Abhyankar PetscErrorCode ierr; 98478b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 98578b84d54SShri Abhyankar PetscInt n,start,end; 98678b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 98778b84d54SShri Abhyankar 98878b84d54SShri Abhyankar start = trstarts[thread_id]; 98978b84d54SShri Abhyankar end = trstarts[thread_id+1]; 99019baf141SJed Brown n = a->i[end] - a->i[start]; 99119baf141SJed Brown ierr = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr); 99278b84d54SShri Abhyankar return 0; 99378b84d54SShri Abhyankar } 99478b84d54SShri Abhyankar 99578b84d54SShri Abhyankar #undef __FUNCT__ 99678b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ" 99778b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 99878b84d54SShri Abhyankar { 99978b84d54SShri Abhyankar PetscErrorCode ierr; 100078b84d54SShri Abhyankar 100178b84d54SShri Abhyankar PetscFunctionBegin; 1002ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr); 1003acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 100478b84d54SShri Abhyankar PetscFunctionReturn(0); 100578b84d54SShri Abhyankar } 100678b84d54SShri Abhyankar #else 100799cafbc1SBarry Smith #undef __FUNCT__ 10084a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 1009dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 101017ab2063SBarry Smith { 1011416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1012dfbe8321SBarry Smith PetscErrorCode ierr; 10133a40ed3dSBarry Smith 10143a40ed3dSBarry Smith PetscFunctionBegin; 1015d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1016acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10173a40ed3dSBarry Smith PetscFunctionReturn(0); 101817ab2063SBarry Smith } 101978b84d54SShri Abhyankar #endif 1020416022c9SBarry Smith 10214a2ae208SSatish Balay #undef __FUNCT__ 10224a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 1023dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 102417ab2063SBarry Smith { 1025416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1026dfbe8321SBarry Smith PetscErrorCode ierr; 1027d5d45c9bSBarry Smith 10283a40ed3dSBarry Smith PetscFunctionBegin; 1029aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1030d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 103117ab2063SBarry Smith #endif 1032e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10336bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10346bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 103505b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1036d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 103705b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 103871f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 103905b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10406bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 104105b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10426bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 104305b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 10446bf464f9SBarry Smith ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr); 1045cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10460b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1047a30b2313SHong Zhang 10484108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1049bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1050901853e0SKris Buschelman 1051dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1052bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1053bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1054bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1055bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1056bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1057bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1058bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1059bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1060bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1061bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10623a40ed3dSBarry Smith PetscFunctionReturn(0); 106317ab2063SBarry Smith } 106417ab2063SBarry Smith 10654a2ae208SSatish Balay #undef __FUNCT__ 10664a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 1067ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 106817ab2063SBarry Smith { 1069416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10704846f1f5SKris Buschelman PetscErrorCode ierr; 10713a40ed3dSBarry Smith 10723a40ed3dSBarry Smith PetscFunctionBegin; 1073a65d3064SKris Buschelman switch (op) { 1074a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 10754e0d8c25SBarry Smith a->roworiented = flg; 1076a65d3064SKris Buschelman break; 1077a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1078a9817697SBarry Smith a->keepnonzeropattern = flg; 1079a65d3064SKris Buschelman break; 1080512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1081512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1082a65d3064SKris Buschelman break; 1083a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 10844e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1085a65d3064SKris Buschelman break; 1086a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 10874e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1088a65d3064SKris Buschelman break; 108928b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 109028b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 109128b2fa4aSMatthew Knepley break; 1092a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 10934e0d8c25SBarry Smith a->ignorezeroentries = flg; 10940df259c2SBarry Smith break; 1095cd6b891eSBarry Smith case MAT_CHECK_COMPRESSED_ROW: 1096cd6b891eSBarry Smith a->compressedrow.check = flg; 1097d487561eSHong Zhang break; 10983d472b54SHong Zhang case MAT_SPD: 1099b1646e73SJed Brown case MAT_SYMMETRIC: 1100b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1101b1646e73SJed Brown case MAT_HERMITIAN: 1102b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 11035021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11045021d80fSJed Brown break; 11054e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1106a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1107a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1108290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1109a65d3064SKris Buschelman break; 1110b87ac2d8SJed Brown case MAT_USE_INODES: 1111b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1112b87ac2d8SJed Brown break; 1113a65d3064SKris Buschelman default: 1114e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1115a65d3064SKris Buschelman } 11164108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11173a40ed3dSBarry Smith PetscFunctionReturn(0); 111817ab2063SBarry Smith } 111917ab2063SBarry Smith 11204a2ae208SSatish Balay #undef __FUNCT__ 11214a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 1122dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 112317ab2063SBarry Smith { 1124416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11256849ba73SBarry Smith PetscErrorCode ierr; 1126d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 112735e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 112817ab2063SBarry Smith 11293a40ed3dSBarry Smith PetscFunctionBegin; 1130d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1131e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 113235e7444dSHong Zhang 1133d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1134d3e70bfaSHong Zhang PetscInt *diag=a->diag; 113535e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11362c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 113735e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 113835e7444dSHong Zhang PetscFunctionReturn(0); 113935e7444dSHong Zhang } 114035e7444dSHong Zhang 11412dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11421ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 114335e7444dSHong Zhang for (i=0; i<n; i++) { 114435e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11452f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 114635e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 114735e7444dSHong Zhang if (aj[j] == i) { 114835e7444dSHong Zhang x[i] = aa[j]; 114917ab2063SBarry Smith break; 115017ab2063SBarry Smith } 115117ab2063SBarry Smith } 115217ab2063SBarry Smith } 11531ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11543a40ed3dSBarry Smith PetscFunctionReturn(0); 115517ab2063SBarry Smith } 115617ab2063SBarry Smith 1157c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 11584a2ae208SSatish Balay #undef __FUNCT__ 11594a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 1160dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 116117ab2063SBarry Smith { 1162416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11635c897100SBarry Smith PetscScalar *x,*y; 1164dfbe8321SBarry Smith PetscErrorCode ierr; 1165d0f46423SBarry Smith PetscInt m = A->rmap->n; 11665c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1167a77337e4SBarry Smith MatScalar *v; 1168a77337e4SBarry Smith PetscScalar alpha; 11690298fd71SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=NULL; 11703447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1171ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11725c897100SBarry Smith #endif 117317ab2063SBarry Smith 11743a40ed3dSBarry Smith PetscFunctionBegin; 11752e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 11761ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 11771ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11785c897100SBarry Smith 11795c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1180bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 11815c897100SBarry Smith #else 11823447b6efSHong Zhang if (usecprow) { 11833447b6efSHong Zhang m = cprow.nrows; 11843447b6efSHong Zhang ii = cprow.i; 11857b2bb3b9SHong Zhang ridx = cprow.rindex; 11863447b6efSHong Zhang } else { 11873447b6efSHong Zhang ii = a->i; 11883447b6efSHong Zhang } 118917ab2063SBarry Smith for (i=0; i<m; i++) { 11903447b6efSHong Zhang idx = a->j + ii[i]; 11913447b6efSHong Zhang v = a->a + ii[i]; 11923447b6efSHong Zhang n = ii[i+1] - ii[i]; 11933447b6efSHong Zhang if (usecprow) { 11947b2bb3b9SHong Zhang alpha = x[ridx[i]]; 11953447b6efSHong Zhang } else { 119617ab2063SBarry Smith alpha = x[i]; 11973447b6efSHong Zhang } 119804fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 119917ab2063SBarry Smith } 12005c897100SBarry Smith #endif 1201dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 12021ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 12031ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12043a40ed3dSBarry Smith PetscFunctionReturn(0); 120517ab2063SBarry Smith } 120617ab2063SBarry Smith 12074a2ae208SSatish Balay #undef __FUNCT__ 12085c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 1209dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12105c897100SBarry Smith { 1211dfbe8321SBarry Smith PetscErrorCode ierr; 12125c897100SBarry Smith 12135c897100SBarry Smith PetscFunctionBegin; 1214170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12155c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12165c897100SBarry Smith PetscFunctionReturn(0); 12175c897100SBarry Smith } 12185c897100SBarry Smith 1219c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 122078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 122178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy) 122278b84d54SShri Abhyankar { 122378b84d54SShri Abhyankar PetscErrorCode ierr; 122478b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122578b84d54SShri Abhyankar PetscScalar *y; 122678b84d54SShri Abhyankar const PetscScalar *x; 122778b84d54SShri Abhyankar const MatScalar *aa; 122878b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 122978b84d54SShri Abhyankar PetscInt n,start,end,i; 123078b84d54SShri Abhyankar const PetscInt *aj,*ai; 123178b84d54SShri Abhyankar PetscScalar sum; 123278b84d54SShri Abhyankar 123378b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 123478b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 123578b84d54SShri Abhyankar start = trstarts[thread_id]; 123678b84d54SShri Abhyankar end = trstarts[thread_id+1]; 123778b84d54SShri Abhyankar aj = a->j; 123878b84d54SShri Abhyankar aa = a->a; 123978b84d54SShri Abhyankar ai = a->i; 124078b84d54SShri Abhyankar for (i=start; i<end; i++) { 124178b84d54SShri Abhyankar n = ai[i+1] - ai[i]; 124278b84d54SShri Abhyankar aj = a->j + ai[i]; 124378b84d54SShri Abhyankar aa = a->a + ai[i]; 124478b84d54SShri Abhyankar sum = 0.0; 124578b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 124678b84d54SShri Abhyankar y[i] = sum; 124778b84d54SShri Abhyankar } 124878b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 124978b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 125078b84d54SShri Abhyankar return 0; 125178b84d54SShri Abhyankar } 125278b84d54SShri Abhyankar 125378b84d54SShri Abhyankar #undef __FUNCT__ 125478b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ" 125578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 125678b84d54SShri Abhyankar { 125778b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 125878b84d54SShri Abhyankar PetscScalar *y; 125978b84d54SShri Abhyankar const PetscScalar *x; 126078b84d54SShri Abhyankar const MatScalar *aa; 126178b84d54SShri Abhyankar PetscErrorCode ierr; 126278b84d54SShri Abhyankar PetscInt m=A->rmap->n; 12630298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 126478b84d54SShri Abhyankar PetscInt n,i,nonzerorow=0; 126578b84d54SShri Abhyankar PetscScalar sum; 126678b84d54SShri Abhyankar PetscBool usecprow=a->compressedrow.use; 126778b84d54SShri Abhyankar 126878b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 126978b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa) 127078b84d54SShri Abhyankar #endif 127178b84d54SShri Abhyankar 127278b84d54SShri Abhyankar PetscFunctionBegin; 127378b84d54SShri Abhyankar aj = a->j; 127478b84d54SShri Abhyankar aa = a->a; 127578b84d54SShri Abhyankar ii = a->i; 127678b84d54SShri Abhyankar if (usecprow) { /* use compressed row format */ 127778b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 127878b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 127978b84d54SShri Abhyankar m = a->compressedrow.nrows; 128078b84d54SShri Abhyankar ii = a->compressedrow.i; 128178b84d54SShri Abhyankar ridx = a->compressedrow.rindex; 128278b84d54SShri Abhyankar for (i=0; i<m; i++) { 128378b84d54SShri Abhyankar n = ii[i+1] - ii[i]; 128478b84d54SShri Abhyankar aj = a->j + ii[i]; 128578b84d54SShri Abhyankar aa = a->a + ii[i]; 128678b84d54SShri Abhyankar sum = 0.0; 128778b84d54SShri Abhyankar nonzerorow += (n>0); 128878b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 128978b84d54SShri Abhyankar /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 129078b84d54SShri Abhyankar y[*ridx++] = sum; 129178b84d54SShri Abhyankar } 129278b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 129378b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 129478b84d54SShri Abhyankar } else { /* do not use compressed row format */ 129578b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 129678b84d54SShri Abhyankar fortranmultaij_(&m,x,ii,aj,aa,y); 129778b84d54SShri Abhyankar #else 1298ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 129978b84d54SShri Abhyankar #endif 130078b84d54SShri Abhyankar } 130178b84d54SShri Abhyankar ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 130278b84d54SShri Abhyankar PetscFunctionReturn(0); 130378b84d54SShri Abhyankar } 130478b84d54SShri Abhyankar #else 13055c897100SBarry Smith #undef __FUNCT__ 13064a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 1307dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 130817ab2063SBarry Smith { 1309416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1310d9fead3dSBarry Smith PetscScalar *y; 131154f21887SBarry Smith const PetscScalar *x; 131254f21887SBarry Smith const MatScalar *aa; 1313dfbe8321SBarry Smith PetscErrorCode ierr; 1314003131ecSBarry Smith PetscInt m=A->rmap->n; 13150298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 13168aee2decSHong Zhang PetscInt n,i,nonzerorow=0; 1317362ced78SSatish Balay PetscScalar sum; 1318ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 131917ab2063SBarry Smith 1320b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 132197952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1322fee21e36SBarry Smith #endif 1323fee21e36SBarry Smith 13243a40ed3dSBarry Smith PetscFunctionBegin; 13253649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 13261ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 132797952fefSHong Zhang aj = a->j; 132897952fefSHong Zhang aa = a->a; 1329416022c9SBarry Smith ii = a->i; 13304eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 133197952fefSHong Zhang m = a->compressedrow.nrows; 133297952fefSHong Zhang ii = a->compressedrow.i; 133397952fefSHong Zhang ridx = a->compressedrow.rindex; 133497952fefSHong Zhang for (i=0; i<m; i++) { 133597952fefSHong Zhang n = ii[i+1] - ii[i]; 133697952fefSHong Zhang aj = a->j + ii[i]; 133797952fefSHong Zhang aa = a->a + ii[i]; 133897952fefSHong Zhang sum = 0.0; 1339a46b3154SVictor Eijkhout nonzerorow += (n>0); 1340003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1341003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 134297952fefSHong Zhang y[*ridx++] = sum; 134397952fefSHong Zhang } 134497952fefSHong Zhang } else { /* do not use compressed row format */ 1345b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1346b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1347b05257ddSBarry Smith #else 134878b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 1349ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 135078b84d54SShri Abhyankar #else 135117ab2063SBarry Smith for (i=0; i<m; i++) { 1352003131ecSBarry Smith n = ii[i+1] - ii[i]; 1353003131ecSBarry Smith aj = a->j + ii[i]; 1354003131ecSBarry Smith aa = a->a + ii[i]; 135517ab2063SBarry Smith sum = 0.0; 1356a46b3154SVictor Eijkhout nonzerorow += (n>0); 1357003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 135817ab2063SBarry Smith y[i] = sum; 135917ab2063SBarry Smith } 13608d195f9aSBarry Smith #endif 136178b84d54SShri Abhyankar #endif 1362b05257ddSBarry Smith } 1363dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 13643649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13651ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13663a40ed3dSBarry Smith PetscFunctionReturn(0); 136717ab2063SBarry Smith } 136878b84d54SShri Abhyankar #endif 136917ab2063SBarry Smith 1370b434eb95SMatthew G. Knepley #undef __FUNCT__ 1371b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ" 1372b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1373b434eb95SMatthew G. Knepley { 1374b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1375b434eb95SMatthew G. Knepley PetscScalar *y; 1376b434eb95SMatthew G. Knepley const PetscScalar *x; 1377b434eb95SMatthew G. Knepley const MatScalar *aa; 1378b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1379b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1380b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1381b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1382b434eb95SMatthew G. Knepley PetscScalar sum; 1383b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1384b434eb95SMatthew G. Knepley 1385b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1386b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1387b434eb95SMatthew G. Knepley #endif 1388b434eb95SMatthew G. Knepley 1389b434eb95SMatthew G. Knepley PetscFunctionBegin; 1390b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1391b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1392b434eb95SMatthew G. Knepley aj = a->j; 1393b434eb95SMatthew G. Knepley aa = a->a; 1394b434eb95SMatthew G. Knepley ii = a->i; 1395b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1396b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1397b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1398b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1399b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1400b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1401b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1402b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1403b434eb95SMatthew G. Knepley sum = 0.0; 1404b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1405b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1406b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1407b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1408b434eb95SMatthew G. Knepley } 1409b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1410b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1411b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1412b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1413b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1414b434eb95SMatthew G. Knepley sum = 0.0; 1415b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1416b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1417b434eb95SMatthew G. Knepley y[i] = sum; 1418b434eb95SMatthew G. Knepley } 1419b434eb95SMatthew G. Knepley } 1420b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1421b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1422b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1423b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1424b434eb95SMatthew G. Knepley } 1425b434eb95SMatthew G. Knepley 1426b434eb95SMatthew G. Knepley #undef __FUNCT__ 1427b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ" 1428b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1429b434eb95SMatthew G. Knepley { 1430b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1431b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1432b434eb95SMatthew G. Knepley const PetscScalar *x; 1433b434eb95SMatthew G. Knepley const MatScalar *aa; 1434b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1435b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1436b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1437b434eb95SMatthew G. Knepley PetscScalar sum; 1438b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1439b434eb95SMatthew G. Knepley 1440b434eb95SMatthew G. Knepley PetscFunctionBegin; 1441b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1442b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1443b434eb95SMatthew G. Knepley if (zz != yy) { 1444b434eb95SMatthew G. Knepley ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 1445b434eb95SMatthew G. Knepley } else { 1446b434eb95SMatthew G. Knepley z = y; 1447b434eb95SMatthew G. Knepley } 1448b434eb95SMatthew G. Knepley 1449b434eb95SMatthew G. Knepley aj = a->j; 1450b434eb95SMatthew G. Knepley aa = a->a; 1451b434eb95SMatthew G. Knepley ii = a->i; 1452b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1453b434eb95SMatthew G. Knepley if (zz != yy) { 1454b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1455b434eb95SMatthew G. Knepley } 1456b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1457b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1458b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1459b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1460b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1461b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1462b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1463b434eb95SMatthew G. Knepley sum = y[*ridx]; 1464b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1465b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1466b434eb95SMatthew G. Knepley } 1467b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1468b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1469b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1470b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1471b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1472b434eb95SMatthew G. Knepley sum = y[i]; 1473b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1474b434eb95SMatthew G. Knepley z[i] = sum; 1475b434eb95SMatthew G. Knepley } 1476b434eb95SMatthew G. Knepley } 1477b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1478b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1479b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1480b434eb95SMatthew G. Knepley if (zz != yy) { 1481b434eb95SMatthew G. Knepley ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 1482b434eb95SMatthew G. Knepley } 1483b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1484b434eb95SMatthew G. Knepley } 1485b434eb95SMatthew G. Knepley 1486c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 14874a2ae208SSatish Balay #undef __FUNCT__ 14884a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1489dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 149017ab2063SBarry Smith { 1491416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1492f15663dcSBarry Smith PetscScalar *y,*z; 1493f15663dcSBarry Smith const PetscScalar *x; 149454f21887SBarry Smith const MatScalar *aa; 1495dfbe8321SBarry Smith PetscErrorCode ierr; 1496d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 14970298fd71SBarry Smith PetscInt n,i,*ridx=NULL; 1498362ced78SSatish Balay PetscScalar sum; 1499ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 15009ea0dfa2SSatish Balay 15013a40ed3dSBarry Smith PetscFunctionBegin; 1502f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15031ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 15042e8a6d31SBarry Smith if (zz != yy) { 15051ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 15062e8a6d31SBarry Smith } else { 15072e8a6d31SBarry Smith z = y; 15082e8a6d31SBarry Smith } 1509bfeeae90SHong Zhang 151097952fefSHong Zhang aj = a->j; 151197952fefSHong Zhang aa = a->a; 1512cddf8d76SBarry Smith ii = a->i; 15134eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 15144eb6d288SHong Zhang if (zz != yy) { 15154eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 15164eb6d288SHong Zhang } 151797952fefSHong Zhang m = a->compressedrow.nrows; 151897952fefSHong Zhang ii = a->compressedrow.i; 151997952fefSHong Zhang ridx = a->compressedrow.rindex; 152097952fefSHong Zhang for (i=0; i<m; i++) { 152197952fefSHong Zhang n = ii[i+1] - ii[i]; 152297952fefSHong Zhang aj = a->j + ii[i]; 152397952fefSHong Zhang aa = a->a + ii[i]; 152497952fefSHong Zhang sum = y[*ridx]; 1525f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 152697952fefSHong Zhang z[*ridx++] = sum; 152797952fefSHong Zhang } 152897952fefSHong Zhang } else { /* do not use compressed row format */ 1529f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1530f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1531f15663dcSBarry Smith #else 153217ab2063SBarry Smith for (i=0; i<m; i++) { 1533f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1534f15663dcSBarry Smith aj = a->j + ii[i]; 1535f15663dcSBarry Smith aa = a->a + ii[i]; 153617ab2063SBarry Smith sum = y[i]; 1537f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 153817ab2063SBarry Smith z[i] = sum; 153917ab2063SBarry Smith } 154002ab625aSSatish Balay #endif 1541f15663dcSBarry Smith } 1542dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1543f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15441ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15452e8a6d31SBarry Smith if (zz != yy) { 15461ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 15472e8a6d31SBarry Smith } 15488154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 15496b375ea7SVictor Minden /* 1550918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1551918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1552918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 15536b375ea7SVictor Minden */ 1554918e98c3SVictor Minden #endif 15553a40ed3dSBarry Smith PetscFunctionReturn(0); 155617ab2063SBarry Smith } 155717ab2063SBarry Smith 155817ab2063SBarry Smith /* 155917ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 156017ab2063SBarry Smith */ 15614a2ae208SSatish Balay #undef __FUNCT__ 15624a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1563dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 156417ab2063SBarry Smith { 1565416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15666849ba73SBarry Smith PetscErrorCode ierr; 1567d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 156817ab2063SBarry Smith 15693a40ed3dSBarry Smith PetscFunctionBegin; 157009f38230SBarry Smith if (!a->diag) { 157109f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 15723bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 157309f38230SBarry Smith } 1574d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 157509f38230SBarry Smith a->diag[i] = a->i[i+1]; 1576bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1577bfeeae90SHong Zhang if (a->j[j] == i) { 157809f38230SBarry Smith a->diag[i] = j; 157917ab2063SBarry Smith break; 158017ab2063SBarry Smith } 158117ab2063SBarry Smith } 158217ab2063SBarry Smith } 15833a40ed3dSBarry Smith PetscFunctionReturn(0); 158417ab2063SBarry Smith } 158517ab2063SBarry Smith 1586be5855fcSBarry Smith /* 1587be5855fcSBarry Smith Checks for missing diagonals 1588be5855fcSBarry Smith */ 15894a2ae208SSatish Balay #undef __FUNCT__ 15904a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1591ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1592be5855fcSBarry Smith { 1593be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 159497f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1595be5855fcSBarry Smith 1596be5855fcSBarry Smith PetscFunctionBegin; 159709f38230SBarry Smith *missing = PETSC_FALSE; 1598d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 159909f38230SBarry Smith *missing = PETSC_TRUE; 160009f38230SBarry Smith if (d) *d = 0; 1601358d2f5dSShri Abhyankar PetscInfo(A,"Matrix has no entries therefore is missing diagonal"); 160209f38230SBarry Smith } else { 1603f1e2ffcdSBarry Smith diag = a->diag; 1604d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1605bfeeae90SHong Zhang if (jj[diag[i]] != i) { 160609f38230SBarry Smith *missing = PETSC_TRUE; 160709f38230SBarry Smith if (d) *d = i; 160809f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 1609358d2f5dSShri Abhyankar break; 161009f38230SBarry Smith } 1611be5855fcSBarry Smith } 1612be5855fcSBarry Smith } 1613be5855fcSBarry Smith PetscFunctionReturn(0); 1614be5855fcSBarry Smith } 1615be5855fcSBarry Smith 161671f1c65dSBarry Smith #undef __FUNCT__ 161771f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 16187087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 161971f1c65dSBarry Smith { 162071f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 162171f1c65dSBarry Smith PetscErrorCode ierr; 1622d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 162354f21887SBarry Smith MatScalar *v = a->a; 162454f21887SBarry Smith PetscScalar *idiag,*mdiag; 162571f1c65dSBarry Smith 162671f1c65dSBarry Smith PetscFunctionBegin; 162771f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 162871f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 162971f1c65dSBarry Smith diag = a->diag; 163071f1c65dSBarry Smith if (!a->idiag) { 163171f1c65dSBarry Smith ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr); 16323bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 163371f1c65dSBarry Smith v = a->a; 163471f1c65dSBarry Smith } 163571f1c65dSBarry Smith mdiag = a->mdiag; 163671f1c65dSBarry Smith idiag = a->idiag; 163771f1c65dSBarry Smith 1638028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 163971f1c65dSBarry Smith for (i=0; i<m; i++) { 164071f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1641e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 164271f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 164371f1c65dSBarry Smith } 164471f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 164571f1c65dSBarry Smith } else { 164671f1c65dSBarry Smith for (i=0; i<m; i++) { 164771f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 164871f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 164971f1c65dSBarry Smith } 1650dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 165171f1c65dSBarry Smith } 165271f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 165371f1c65dSBarry Smith PetscFunctionReturn(0); 165471f1c65dSBarry Smith } 165571f1c65dSBarry Smith 1656c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 16574a2ae208SSatish Balay #undef __FUNCT__ 165841f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 165941f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 166017ab2063SBarry Smith { 1661416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1662e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1663e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 166454f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1665dfbe8321SBarry Smith PetscErrorCode ierr; 1666d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 166797f1f81fSBarry Smith const PetscInt *idx,*diag; 166817ab2063SBarry Smith 16693a40ed3dSBarry Smith PetscFunctionBegin; 1670b965ef7fSBarry Smith its = its*lits; 167191723122SBarry Smith 167271f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 167371f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 167471f1c65dSBarry Smith a->fshift = fshift; 167571f1c65dSBarry Smith a->omega = omega; 1676ed480e8bSBarry Smith 167771f1c65dSBarry Smith diag = a->diag; 167871f1c65dSBarry Smith t = a->ssor_work; 1679ed480e8bSBarry Smith idiag = a->idiag; 168071f1c65dSBarry Smith mdiag = a->mdiag; 1681ed480e8bSBarry Smith 16821ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 16833649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1684ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 168517ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 168617ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1687ed480e8bSBarry Smith bs = b; 168817ab2063SBarry Smith for (i=0; i<m; i++) { 168971f1c65dSBarry Smith d = fshift + mdiag[i]; 1690416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1691ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1692ed480e8bSBarry Smith v = a->a + diag[i] + 1; 169317ab2063SBarry Smith sum = b[i]*d/omega; 1694003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 169517ab2063SBarry Smith x[i] = sum; 169617ab2063SBarry Smith } 16971ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16983649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1699efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17003a40ed3dSBarry Smith PetscFunctionReturn(0); 170117ab2063SBarry Smith } 1702c783ea89SBarry Smith 17032205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 17042205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 170517ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1706887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 170717ab2063SBarry Smith 170817ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 170917ab2063SBarry Smith 1710887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 171117ab2063SBarry Smith */ 171217ab2063SBarry Smith scale = (2.0/omega) - 1.0; 171317ab2063SBarry Smith 171417ab2063SBarry Smith /* x = (E + U)^{-1} b */ 171517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1716416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1717ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1718ed480e8bSBarry Smith v = a->a + diag[i] + 1; 171917ab2063SBarry Smith sum = b[i]; 1720e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1721ed480e8bSBarry Smith x[i] = sum*idiag[i]; 172217ab2063SBarry Smith } 172317ab2063SBarry Smith 172417ab2063SBarry Smith /* t = b - (2*E - D)x */ 1725416022c9SBarry Smith v = a->a; 17262205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 172717ab2063SBarry Smith 172817ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1729ed480e8bSBarry Smith ts = t; 1730416022c9SBarry Smith diag = a->diag; 173117ab2063SBarry Smith for (i=0; i<m; i++) { 1732416022c9SBarry Smith n = diag[i] - a->i[i]; 1733ed480e8bSBarry Smith idx = a->j + a->i[i]; 1734ed480e8bSBarry Smith v = a->a + a->i[i]; 173517ab2063SBarry Smith sum = t[i]; 1736003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1737ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1738733d66baSBarry Smith /* x = x + t */ 1739733d66baSBarry Smith x[i] += t[i]; 174017ab2063SBarry Smith } 174117ab2063SBarry Smith 1742dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 17431ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17443649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 17453a40ed3dSBarry Smith PetscFunctionReturn(0); 174617ab2063SBarry Smith } 174717ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 174817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 174917ab2063SBarry Smith for (i=0; i<m; i++) { 1750416022c9SBarry Smith n = diag[i] - a->i[i]; 1751ed480e8bSBarry Smith idx = a->j + a->i[i]; 1752ed480e8bSBarry Smith v = a->a + a->i[i]; 175317ab2063SBarry Smith sum = b[i]; 1754e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 17555c99c7daSBarry Smith t[i] = sum; 1756ed480e8bSBarry Smith x[i] = sum*idiag[i]; 175717ab2063SBarry Smith } 17585c99c7daSBarry Smith xb = t; 1759efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 17603a40ed3dSBarry Smith } else xb = b; 176117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 176217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1763416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1764ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1765ed480e8bSBarry Smith v = a->a + diag[i] + 1; 176617ab2063SBarry Smith sum = xb[i]; 1767e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 17685c99c7daSBarry Smith if (xb == b) { 1769ed480e8bSBarry Smith x[i] = sum*idiag[i]; 17705c99c7daSBarry Smith } else { 1771b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 177217ab2063SBarry Smith } 17735c99c7daSBarry Smith } 1774b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 177517ab2063SBarry Smith } 177617ab2063SBarry Smith its--; 177717ab2063SBarry Smith } 177817ab2063SBarry Smith while (its--) { 177917ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 178017ab2063SBarry Smith for (i=0; i<m; i++) { 1781b19a5dc2SMark Adams /* lower */ 1782b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1783ed480e8bSBarry Smith idx = a->j + a->i[i]; 1784ed480e8bSBarry Smith v = a->a + a->i[i]; 178517ab2063SBarry Smith sum = b[i]; 1786e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1787b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1788b19a5dc2SMark Adams /* upper */ 1789b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1790b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1791b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1792b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1793b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 179417ab2063SBarry Smith } 1795b19a5dc2SMark Adams xb = t; 17969f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1797b19a5dc2SMark Adams } else xb = b; 179817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 179917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1800b19a5dc2SMark Adams sum = xb[i]; 1801b19a5dc2SMark Adams if (xb == b) { 1802b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1803416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1804ed480e8bSBarry Smith idx = a->j + a->i[i]; 1805ed480e8bSBarry Smith v = a->a + a->i[i]; 1806e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1807ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1808b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1809b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1810b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1811b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1812b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1813b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 181417ab2063SBarry Smith } 1815b19a5dc2SMark Adams } 1816b19a5dc2SMark Adams if (xb == b) { 18179f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1818b19a5dc2SMark Adams } else { 1819b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1820b19a5dc2SMark Adams } 182117ab2063SBarry Smith } 182217ab2063SBarry Smith } 18231ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18243649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1825365a8a9eSBarry Smith PetscFunctionReturn(0); 182617ab2063SBarry Smith } 182717ab2063SBarry Smith 18282af78befSBarry Smith 18294a2ae208SSatish Balay #undef __FUNCT__ 18304a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1831dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 183217ab2063SBarry Smith { 1833416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18344e220ebcSLois Curfman McInnes 18353a40ed3dSBarry Smith PetscFunctionBegin; 18364e220ebcSLois Curfman McInnes info->block_size = 1.0; 18374e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 18384e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 18394e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 18404e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 18418e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 18427adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1843d5f3da31SBarry Smith if (A->factortype) { 18444e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 18454e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 18464e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 18474e220ebcSLois Curfman McInnes } else { 18484e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 18494e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 18504e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 18514e220ebcSLois Curfman McInnes } 18523a40ed3dSBarry Smith PetscFunctionReturn(0); 185317ab2063SBarry Smith } 185417ab2063SBarry Smith 18554a2ae208SSatish Balay #undef __FUNCT__ 18564a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 18572b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 185817ab2063SBarry Smith { 1859416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18603b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 18616849ba73SBarry Smith PetscErrorCode ierr; 186297b48c8fSBarry Smith const PetscScalar *xx; 186397b48c8fSBarry Smith PetscScalar *bb; 1864ace3abfcSBarry Smith PetscBool missing; 186517ab2063SBarry Smith 18663a40ed3dSBarry Smith PetscFunctionBegin; 186797b48c8fSBarry Smith if (x && b) { 186897b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 186997b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 187097b48c8fSBarry Smith for (i=0; i<N; i++) { 187197b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 187297b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 187397b48c8fSBarry Smith } 187497b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 187597b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 187697b48c8fSBarry Smith } 187797b48c8fSBarry Smith 1878a9817697SBarry Smith if (a->keepnonzeropattern) { 1879f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1880e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1881bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1882f1e2ffcdSBarry Smith } 1883f4df32b1SMatthew Knepley if (diag != 0.0) { 188409f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1885e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1886f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1887f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1888f1e2ffcdSBarry Smith } 1889f1e2ffcdSBarry Smith } 189088e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1891f1e2ffcdSBarry Smith } else { 1892f4df32b1SMatthew Knepley if (diag != 0.0) { 189317ab2063SBarry Smith for (i=0; i<N; i++) { 1894e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18957ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1896416022c9SBarry Smith a->ilen[rows[i]] = 1; 1897f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1898bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 18997ae801bdSBarry Smith } else { /* in case row was completely empty */ 1900f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 190117ab2063SBarry Smith } 190217ab2063SBarry Smith } 19033a40ed3dSBarry Smith } else { 190417ab2063SBarry Smith for (i=0; i<N; i++) { 1905e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1906416022c9SBarry Smith a->ilen[rows[i]] = 0; 190717ab2063SBarry Smith } 190817ab2063SBarry Smith } 190988e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1910f1e2ffcdSBarry Smith } 191143a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19123a40ed3dSBarry Smith PetscFunctionReturn(0); 191317ab2063SBarry Smith } 191417ab2063SBarry Smith 19154a2ae208SSatish Balay #undef __FUNCT__ 19166e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 19176e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 19186e169961SBarry Smith { 19196e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 19206e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 19216e169961SBarry Smith PetscErrorCode ierr; 19222b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 19236e169961SBarry Smith const PetscScalar *xx; 19246e169961SBarry Smith PetscScalar *bb; 19256e169961SBarry Smith 19266e169961SBarry Smith PetscFunctionBegin; 19276e169961SBarry Smith if (x && b) { 19286e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 19296e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 19302b40b63fSBarry Smith vecs = PETSC_TRUE; 19316e169961SBarry Smith } 19326e169961SBarry Smith ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr); 19336e169961SBarry Smith ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 19346e169961SBarry Smith for (i=0; i<N; i++) { 19356e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 19366e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 19372205254eSKarl Rupp 19386e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 19396e169961SBarry Smith } 19406e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 19416e169961SBarry Smith if (!zeroed[i]) { 19426e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 19436e169961SBarry Smith if (zeroed[a->j[j]]) { 19442b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 19456e169961SBarry Smith a->a[j] = 0.0; 19466e169961SBarry Smith } 19476e169961SBarry Smith } 19482b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 19496e169961SBarry Smith } 19506e169961SBarry Smith if (x && b) { 19516e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 19526e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 19536e169961SBarry Smith } 19546e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 19556e169961SBarry Smith if (diag != 0.0) { 19566e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 19576e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 19586e169961SBarry Smith for (i=0; i<N; i++) { 19596e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 19606e169961SBarry Smith } 19616e169961SBarry Smith } 19626e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 19636e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19646e169961SBarry Smith PetscFunctionReturn(0); 19656e169961SBarry Smith } 19666e169961SBarry Smith 19676e169961SBarry Smith #undef __FUNCT__ 19684a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1969a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 197017ab2063SBarry Smith { 1971416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 197297f1f81fSBarry Smith PetscInt *itmp; 197317ab2063SBarry Smith 19743a40ed3dSBarry Smith PetscFunctionBegin; 1975e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 197617ab2063SBarry Smith 1977416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1978bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 197917ab2063SBarry Smith if (idx) { 1980bfeeae90SHong Zhang itmp = a->j + a->i[row]; 198126fbe8dcSKarl Rupp if (*nz) *idx = itmp; 198217ab2063SBarry Smith else *idx = 0; 198317ab2063SBarry Smith } 19843a40ed3dSBarry Smith PetscFunctionReturn(0); 198517ab2063SBarry Smith } 198617ab2063SBarry Smith 1987bfeeae90SHong Zhang /* remove this function? */ 19884a2ae208SSatish Balay #undef __FUNCT__ 19894a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1990a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 199117ab2063SBarry Smith { 19923a40ed3dSBarry Smith PetscFunctionBegin; 19933a40ed3dSBarry Smith PetscFunctionReturn(0); 199417ab2063SBarry Smith } 199517ab2063SBarry Smith 19964a2ae208SSatish Balay #undef __FUNCT__ 19974a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1998dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 199917ab2063SBarry Smith { 2000416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 200154f21887SBarry Smith MatScalar *v = a->a; 200236db0b34SBarry Smith PetscReal sum = 0.0; 20036849ba73SBarry Smith PetscErrorCode ierr; 200497f1f81fSBarry Smith PetscInt i,j; 200517ab2063SBarry Smith 20063a40ed3dSBarry Smith PetscFunctionBegin; 200717ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2008416022c9SBarry Smith for (i=0; i<a->nz; i++) { 200936db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 201017ab2063SBarry Smith } 20118f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 20123a40ed3dSBarry Smith } else if (type == NORM_1) { 201336db0b34SBarry Smith PetscReal *tmp; 201497f1f81fSBarry Smith PetscInt *jj = a->j; 2015d0f46423SBarry Smith ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 2016d0f46423SBarry Smith ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr); 2017064f8208SBarry Smith *nrm = 0.0; 2018416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2019bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 202017ab2063SBarry Smith } 2021d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2022064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 202317ab2063SBarry Smith } 2024606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 20253a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2026064f8208SBarry Smith *nrm = 0.0; 2027d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2028bfeeae90SHong Zhang v = a->a + a->i[j]; 202917ab2063SBarry Smith sum = 0.0; 2030416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2031cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 203217ab2063SBarry Smith } 2033064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 203417ab2063SBarry Smith } 2035f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 20363a40ed3dSBarry Smith PetscFunctionReturn(0); 203717ab2063SBarry Smith } 203817ab2063SBarry Smith 20394e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 20404e938277SHong Zhang #undef __FUNCT__ 20414e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ" 20424e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 20434e938277SHong Zhang { 20444e938277SHong Zhang PetscErrorCode ierr; 20454e938277SHong Zhang PetscInt i,j,anzj; 20464e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 20474e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 20484e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 20494e938277SHong Zhang 20504e938277SHong Zhang PetscFunctionBegin; 20514e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 20524e938277SHong Zhang ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr); 20534e938277SHong Zhang ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr); 20544e938277SHong Zhang ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr); 20554e938277SHong Zhang ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr); 20564e938277SHong Zhang 20574e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 20584e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 205926fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 20604e938277SHong Zhang /* Form ati for csr format of A^T. */ 206126fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 20624e938277SHong Zhang 20634e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 20644e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 20654e938277SHong Zhang 20664e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 20674e938277SHong Zhang for (i=0;i<am;i++) { 20684e938277SHong Zhang anzj = ai[i+1] - ai[i]; 20694e938277SHong Zhang for (j=0;j<anzj;j++) { 20704e938277SHong Zhang atj[atfill[*aj]] = i; 20714e938277SHong Zhang atfill[*aj++] += 1; 20724e938277SHong Zhang } 20734e938277SHong Zhang } 20744e938277SHong Zhang 20754e938277SHong Zhang /* Clean up temporary space and complete requests. */ 20764e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2077ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 20782205254eSKarl Rupp 2079a2f3521dSMark F. Adams (*B)->rmap->bs = A->cmap->bs; 2080a2f3521dSMark F. Adams (*B)->cmap->bs = A->rmap->bs; 2081a2f3521dSMark F. Adams 20824e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 20834e938277SHong Zhang b->free_a = PETSC_FALSE; 20844e938277SHong Zhang b->free_ij = PETSC_TRUE; 20854e938277SHong Zhang b->nonew = 0; 20864e938277SHong Zhang PetscFunctionReturn(0); 20874e938277SHong Zhang } 20884e938277SHong Zhang 20894a2ae208SSatish Balay #undef __FUNCT__ 20904a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 2091fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 209217ab2063SBarry Smith { 2093416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2094416022c9SBarry Smith Mat C; 20956849ba73SBarry Smith PetscErrorCode ierr; 2096d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 209754f21887SBarry Smith MatScalar *array = a->a; 209817ab2063SBarry Smith 20993a40ed3dSBarry Smith PetscFunctionBegin; 2100e32f2f54SBarry 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"); 2101fc4dec0aSBarry Smith 2102fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 2103d0f46423SBarry Smith ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 2104d0f46423SBarry Smith ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr); 2105bfeeae90SHong Zhang 2106bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 2107ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2108d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 2109a2f3521dSMark F. Adams ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr); 21107adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2111ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2112606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2113a541d17aSBarry Smith } else { 2114a541d17aSBarry Smith C = *B; 2115a541d17aSBarry Smith } 2116a541d17aSBarry Smith 211717ab2063SBarry Smith for (i=0; i<m; i++) { 211817ab2063SBarry Smith len = ai[i+1]-ai[i]; 211987d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2120b9b97703SBarry Smith array += len; 2121b9b97703SBarry Smith aj += len; 212217ab2063SBarry Smith } 21236d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21246d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 212517ab2063SBarry Smith 2126815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 2127416022c9SBarry Smith *B = C; 212817ab2063SBarry Smith } else { 2129eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 213017ab2063SBarry Smith } 21313a40ed3dSBarry Smith PetscFunctionReturn(0); 213217ab2063SBarry Smith } 213317ab2063SBarry Smith 2134cd0d46ebSvictorle #undef __FUNCT__ 21355fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 21367087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2137cd0d46ebSvictorle { 2138cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 213954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 214054f21887SBarry Smith MatScalar *va,*vb; 21416849ba73SBarry Smith PetscErrorCode ierr; 214297f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2143cd0d46ebSvictorle 2144cd0d46ebSvictorle PetscFunctionBegin; 2145cd0d46ebSvictorle bij = (Mat_SeqAIJ*) B->data; 2146cd0d46ebSvictorle 2147cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2148cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 21495485867bSBarry Smith if (ma!=nb || na!=mb) { 21505485867bSBarry Smith *f = PETSC_FALSE; 21515485867bSBarry Smith PetscFunctionReturn(0); 21525485867bSBarry Smith } 2153cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2154cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2155cd0d46ebSvictorle va = aij->a; vb = bij->a; 215697f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 215797f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 2158cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2159cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2160cd0d46ebSvictorle 2161cd0d46ebSvictorle *f = PETSC_TRUE; 2162cd0d46ebSvictorle for (i=0; i<ma; i++) { 2163cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 216497f1f81fSBarry Smith PetscInt idc,idr; 21655485867bSBarry Smith PetscScalar vc,vr; 2166cd0d46ebSvictorle /* column/row index/value */ 21675485867bSBarry Smith idc = adx[aptr[i]]; 21685485867bSBarry Smith idr = bdx[bptr[idc]]; 21695485867bSBarry Smith vc = va[aptr[i]]; 21705485867bSBarry Smith vr = vb[bptr[idc]]; 21715485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 21725485867bSBarry Smith *f = PETSC_FALSE; 21735485867bSBarry Smith goto done; 2174cd0d46ebSvictorle } else { 21755485867bSBarry Smith aptr[i]++; 21765485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2177cd0d46ebSvictorle } 2178cd0d46ebSvictorle } 2179cd0d46ebSvictorle } 2180cd0d46ebSvictorle done: 2181cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 21823aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2183cd0d46ebSvictorle PetscFunctionReturn(0); 2184cd0d46ebSvictorle } 2185cd0d46ebSvictorle 21861cbb95d3SBarry Smith #undef __FUNCT__ 21871cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 21887087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 21891cbb95d3SBarry Smith { 21901cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 219154f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 219254f21887SBarry Smith MatScalar *va,*vb; 21931cbb95d3SBarry Smith PetscErrorCode ierr; 21941cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 21951cbb95d3SBarry Smith 21961cbb95d3SBarry Smith PetscFunctionBegin; 21971cbb95d3SBarry Smith bij = (Mat_SeqAIJ*) B->data; 21981cbb95d3SBarry Smith 21991cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 22001cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 22011cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 22021cbb95d3SBarry Smith *f = PETSC_FALSE; 22031cbb95d3SBarry Smith PetscFunctionReturn(0); 22041cbb95d3SBarry Smith } 22051cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 22061cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 22071cbb95d3SBarry Smith va = aij->a; vb = bij->a; 22081cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 22091cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 22101cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 22111cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 22121cbb95d3SBarry Smith 22131cbb95d3SBarry Smith *f = PETSC_TRUE; 22141cbb95d3SBarry Smith for (i=0; i<ma; i++) { 22151cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 22161cbb95d3SBarry Smith PetscInt idc,idr; 22171cbb95d3SBarry Smith PetscScalar vc,vr; 22181cbb95d3SBarry Smith /* column/row index/value */ 22191cbb95d3SBarry Smith idc = adx[aptr[i]]; 22201cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 22211cbb95d3SBarry Smith vc = va[aptr[i]]; 22221cbb95d3SBarry Smith vr = vb[bptr[idc]]; 22231cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 22241cbb95d3SBarry Smith *f = PETSC_FALSE; 22251cbb95d3SBarry Smith goto done; 22261cbb95d3SBarry Smith } else { 22271cbb95d3SBarry Smith aptr[i]++; 22281cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 22291cbb95d3SBarry Smith } 22301cbb95d3SBarry Smith } 22311cbb95d3SBarry Smith } 22321cbb95d3SBarry Smith done: 22331cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 22341cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 22351cbb95d3SBarry Smith PetscFunctionReturn(0); 22361cbb95d3SBarry Smith } 22371cbb95d3SBarry Smith 22389e29f15eSvictorle #undef __FUNCT__ 22399e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 2240ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 22419e29f15eSvictorle { 2242dfbe8321SBarry Smith PetscErrorCode ierr; 22436e111a19SKarl Rupp 22449e29f15eSvictorle PetscFunctionBegin; 22455485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 22469e29f15eSvictorle PetscFunctionReturn(0); 22479e29f15eSvictorle } 22489e29f15eSvictorle 22494a2ae208SSatish Balay #undef __FUNCT__ 22501cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 2251ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 22521cbb95d3SBarry Smith { 22531cbb95d3SBarry Smith PetscErrorCode ierr; 22546e111a19SKarl Rupp 22551cbb95d3SBarry Smith PetscFunctionBegin; 22561cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 22571cbb95d3SBarry Smith PetscFunctionReturn(0); 22581cbb95d3SBarry Smith } 22591cbb95d3SBarry Smith 22601cbb95d3SBarry Smith #undef __FUNCT__ 22614a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 2262dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 226317ab2063SBarry Smith { 2264416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 226554f21887SBarry Smith PetscScalar *l,*r,x; 226654f21887SBarry Smith MatScalar *v; 2267dfbe8321SBarry Smith PetscErrorCode ierr; 2268d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 226917ab2063SBarry Smith 22703a40ed3dSBarry Smith PetscFunctionBegin; 227117ab2063SBarry Smith if (ll) { 22723ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 22733ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2274e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2275e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 22761ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2277416022c9SBarry Smith v = a->a; 227817ab2063SBarry Smith for (i=0; i<m; i++) { 227917ab2063SBarry Smith x = l[i]; 2280416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 22812205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 228217ab2063SBarry Smith } 22831ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2284efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 228517ab2063SBarry Smith } 228617ab2063SBarry Smith if (rr) { 2287e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2288e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 22891ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2290416022c9SBarry Smith v = a->a; jj = a->j; 22912205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 22921ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2293efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 229417ab2063SBarry Smith } 2295acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 22963a40ed3dSBarry Smith PetscFunctionReturn(0); 229717ab2063SBarry Smith } 229817ab2063SBarry Smith 22994a2ae208SSatish Balay #undef __FUNCT__ 23004a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 230197f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 230217ab2063SBarry Smith { 2303db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 23046849ba73SBarry Smith PetscErrorCode ierr; 2305d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 230697f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 23075d0c19d7SBarry Smith const PetscInt *irow,*icol; 23085d0c19d7SBarry Smith PetscInt nrows,ncols; 230997f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 231054f21887SBarry Smith MatScalar *a_new,*mat_a; 2311416022c9SBarry Smith Mat C; 2312ace3abfcSBarry Smith PetscBool stride,sorted; 231317ab2063SBarry Smith 23143a40ed3dSBarry Smith PetscFunctionBegin; 231514ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 2316e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 231714ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2318e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 231999141d43SSatish Balay 232017ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2321b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2322b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 232317ab2063SBarry Smith 2324fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2325251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2326fee21e36SBarry Smith if (stride && step == 1) { 232702834360SBarry Smith /* special case of contiguous rows */ 23280e83c824SBarry Smith ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr); 232902834360SBarry Smith /* loop over new rows determining lens and starting points */ 233002834360SBarry Smith for (i=0; i<nrows; i++) { 2331bfeeae90SHong Zhang kstart = ai[irow[i]]; 2332a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 233302834360SBarry Smith for (k=kstart; k<kend; k++) { 2334bfeeae90SHong Zhang if (aj[k] >= first) { 233502834360SBarry Smith starts[i] = k; 233602834360SBarry Smith break; 233702834360SBarry Smith } 233802834360SBarry Smith } 2339a2744918SBarry Smith sum = 0; 234002834360SBarry Smith while (k < kend) { 2341bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2342a2744918SBarry Smith sum++; 234302834360SBarry Smith } 2344a2744918SBarry Smith lens[i] = sum; 234502834360SBarry Smith } 234602834360SBarry Smith /* create submatrix */ 2347cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 234897f1f81fSBarry Smith PetscInt n_cols,n_rows; 234908480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2350e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2351d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 235208480c60SBarry Smith C = *B; 23533a40ed3dSBarry Smith } else { 23543bef6203SJed Brown PetscInt rbs,cbs; 2355ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2356f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 23573bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 23583bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 23593bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 23607adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2361ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 236208480c60SBarry Smith } 2363db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2364db02288aSLois Curfman McInnes 236502834360SBarry Smith /* loop over rows inserting into submatrix */ 2366db02288aSLois Curfman McInnes a_new = c->a; 2367db02288aSLois Curfman McInnes j_new = c->j; 2368db02288aSLois Curfman McInnes i_new = c->i; 2369bfeeae90SHong Zhang 237002834360SBarry Smith for (i=0; i<nrows; i++) { 2371a2744918SBarry Smith ii = starts[i]; 2372a2744918SBarry Smith lensi = lens[i]; 2373a2744918SBarry Smith for (k=0; k<lensi; k++) { 2374a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 237502834360SBarry Smith } 237687828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2377a2744918SBarry Smith a_new += lensi; 2378a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2379a2744918SBarry Smith c->ilen[i] = lensi; 238002834360SBarry Smith } 23810e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 23823a40ed3dSBarry Smith } else { 238302834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 23840e83c824SBarry Smith ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr); 238597f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 23860e83c824SBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 23874dcab191SBarry Smith for (i=0; i<ncols; i++) { 23884dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 23894dcab191SBarry 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); 23904dcab191SBarry Smith #endif 23914dcab191SBarry Smith smap[icol[i]] = i+1; 23924dcab191SBarry Smith } 23934dcab191SBarry Smith 239402834360SBarry Smith /* determine lens of each row */ 239502834360SBarry Smith for (i=0; i<nrows; i++) { 2396bfeeae90SHong Zhang kstart = ai[irow[i]]; 239702834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 239802834360SBarry Smith lens[i] = 0; 239902834360SBarry Smith for (k=kstart; k<kend; k++) { 2400bfeeae90SHong Zhang if (smap[aj[k]]) { 240102834360SBarry Smith lens[i]++; 240202834360SBarry Smith } 240302834360SBarry Smith } 240402834360SBarry Smith } 240517ab2063SBarry Smith /* Create and fill new matrix */ 2406a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2407ace3abfcSBarry Smith PetscBool equal; 24080f5bd95cSBarry Smith 240999141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2410e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2411d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2412f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2413d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 241408480c60SBarry Smith C = *B; 24153a40ed3dSBarry Smith } else { 24163bef6203SJed Brown PetscInt rbs,cbs; 2417ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2418f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 24193bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 24203bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 24213bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 24227adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2423ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 242408480c60SBarry Smith } 242599141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 242617ab2063SBarry Smith for (i=0; i<nrows; i++) { 242799141d43SSatish Balay row = irow[i]; 2428bfeeae90SHong Zhang kstart = ai[row]; 242999141d43SSatish Balay kend = kstart + a->ilen[row]; 2430bfeeae90SHong Zhang mat_i = c->i[i]; 243199141d43SSatish Balay mat_j = c->j + mat_i; 243299141d43SSatish Balay mat_a = c->a + mat_i; 243399141d43SSatish Balay mat_ilen = c->ilen + i; 243417ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2435bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2436ed480e8bSBarry Smith *mat_j++ = tcol - 1; 243799141d43SSatish Balay *mat_a++ = a->a[k]; 243899141d43SSatish Balay (*mat_ilen)++; 243999141d43SSatish Balay 244017ab2063SBarry Smith } 244117ab2063SBarry Smith } 244217ab2063SBarry Smith } 244302834360SBarry Smith /* Free work space */ 244402834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2445606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2446606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 244702834360SBarry Smith } 24486d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24496d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 245017ab2063SBarry Smith 245117ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2452416022c9SBarry Smith *B = C; 24533a40ed3dSBarry Smith PetscFunctionReturn(0); 245417ab2063SBarry Smith } 245517ab2063SBarry Smith 24561df811f5SHong Zhang #undef __FUNCT__ 245782d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 2458fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 245982d44351SHong Zhang { 246082d44351SHong Zhang PetscErrorCode ierr; 246182d44351SHong Zhang Mat B; 246282d44351SHong Zhang 246382d44351SHong Zhang PetscFunctionBegin; 2464c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 246582d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 246682d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 2467a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr); 246882d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 246982d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 247082d44351SHong Zhang *subMat = B; 2471c2d650bdSHong Zhang } else { 2472c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2473c2d650bdSHong Zhang } 247482d44351SHong Zhang PetscFunctionReturn(0); 247582d44351SHong Zhang } 247682d44351SHong Zhang 247782d44351SHong Zhang #undef __FUNCT__ 24784a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 24790481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2480a871dcd8SBarry Smith { 248163b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2482dfbe8321SBarry Smith PetscErrorCode ierr; 248363b91edcSBarry Smith Mat outA; 2484ace3abfcSBarry Smith PetscBool row_identity,col_identity; 248563b91edcSBarry Smith 24863a40ed3dSBarry Smith PetscFunctionBegin; 2487e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 24881df811f5SHong Zhang 2489b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2490b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2491a871dcd8SBarry Smith 249263b91edcSBarry Smith outA = inA; 2493d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 24942205254eSKarl Rupp 2495c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 24966bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 24972205254eSKarl Rupp 2498c3122656SLisandro Dalcin a->row = row; 24992205254eSKarl Rupp 2500c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 25016bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 25022205254eSKarl Rupp 2503c3122656SLisandro Dalcin a->col = col; 250463b91edcSBarry Smith 250536db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 25066bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 25074c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 25083bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2509f0ec6fceSSatish Balay 251094a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2511d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 25123bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 251394a9d846SBarry Smith } 251463b91edcSBarry Smith 2515f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2516137fb511SHong Zhang if (row_identity && col_identity) { 2517ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2518137fb511SHong Zhang } else { 2519719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2520137fb511SHong Zhang } 25213a40ed3dSBarry Smith PetscFunctionReturn(0); 2522a871dcd8SBarry Smith } 2523a871dcd8SBarry Smith 25244a2ae208SSatish Balay #undef __FUNCT__ 25254a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2526f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2527f0b747eeSBarry Smith { 2528f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2529f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2530efee365bSSatish Balay PetscErrorCode ierr; 2531c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 25323a40ed3dSBarry Smith 25333a40ed3dSBarry Smith PetscFunctionBegin; 2534c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 25358b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2536efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2537acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 25383a40ed3dSBarry Smith PetscFunctionReturn(0); 2539f0b747eeSBarry Smith } 2540f0b747eeSBarry Smith 25414a2ae208SSatish Balay #undef __FUNCT__ 25424a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 254397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2544cddf8d76SBarry Smith { 2545dfbe8321SBarry Smith PetscErrorCode ierr; 254697f1f81fSBarry Smith PetscInt i; 2547cddf8d76SBarry Smith 25483a40ed3dSBarry Smith PetscFunctionBegin; 2549cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2550b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 2551cddf8d76SBarry Smith } 2552cddf8d76SBarry Smith 2553cddf8d76SBarry Smith for (i=0; i<n; i++) { 25546a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2555cddf8d76SBarry Smith } 25563a40ed3dSBarry Smith PetscFunctionReturn(0); 2557cddf8d76SBarry Smith } 2558cddf8d76SBarry Smith 25594a2ae208SSatish Balay #undef __FUNCT__ 25604a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 256197f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 25624dcbc457SBarry Smith { 2563e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25646849ba73SBarry Smith PetscErrorCode ierr; 25655d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 25665d0c19d7SBarry Smith const PetscInt *idx; 256797f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2568f1af5d2fSBarry Smith PetscBT table; 2569bbd702dbSSatish Balay 25703a40ed3dSBarry Smith PetscFunctionBegin; 2571d0f46423SBarry Smith m = A->rmap->n; 2572e4d965acSSatish Balay ai = a->i; 2573bfeeae90SHong Zhang aj = a->j; 25748a047759SSatish Balay 2575e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 257606763907SSatish Balay 257797f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 257853b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 257906763907SSatish Balay 2580e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2581b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2582e4d965acSSatish Balay isz = 0; 25836831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2584e4d965acSSatish Balay 2585e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25864dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2587b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2588e4d965acSSatish Balay 2589dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2590e4d965acSSatish Balay for (j=0; j<n; ++j) { 25912205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25924dcbc457SBarry Smith } 259306763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25946bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2595e4d965acSSatish Balay 259604a348a9SBarry Smith k = 0; 259704a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 259804a348a9SBarry Smith n = isz; 259906763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2600e4d965acSSatish Balay row = nidx[k]; 2601e4d965acSSatish Balay start = ai[row]; 2602e4d965acSSatish Balay end = ai[row+1]; 260304a348a9SBarry Smith for (l = start; l<end; l++) { 2604efb16452SHong Zhang val = aj[l]; 26052205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2606e4d965acSSatish Balay } 2607e4d965acSSatish Balay } 2608e4d965acSSatish Balay } 260970b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2610e4d965acSSatish Balay } 261194bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2612606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 26133a40ed3dSBarry Smith PetscFunctionReturn(0); 26144dcbc457SBarry Smith } 261517ab2063SBarry Smith 26160513a670SBarry Smith /* -------------------------------------------------------------- */ 26174a2ae208SSatish Balay #undef __FUNCT__ 26184a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2619dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 26200513a670SBarry Smith { 26210513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26226849ba73SBarry Smith PetscErrorCode ierr; 26233b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 26245d0c19d7SBarry Smith const PetscInt *row,*col; 26255d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 262656cd22aeSBarry Smith IS icolp,irowp; 26270298fd71SBarry Smith PetscInt *cwork = NULL; 26280298fd71SBarry Smith PetscScalar *vwork = NULL; 26290513a670SBarry Smith 26303a40ed3dSBarry Smith PetscFunctionBegin; 26314c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 263256cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 26334c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 263456cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 26350513a670SBarry Smith 26360513a670SBarry Smith /* determine lengths of permuted rows */ 263797f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 26382205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2639ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2640f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 2641a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 26427adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2643ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2644606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 26450513a670SBarry Smith 264697f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 26470513a670SBarry Smith for (i=0; i<m; i++) { 264832ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 26492205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2650cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 265132ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 26520513a670SBarry Smith } 2653606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 26542205254eSKarl Rupp 26553c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 26562205254eSKarl Rupp 26570513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26580513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 265956cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 266056cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 26616bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 26626bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 26633a40ed3dSBarry Smith PetscFunctionReturn(0); 26640513a670SBarry Smith } 26650513a670SBarry Smith 26664a2ae208SSatish Balay #undef __FUNCT__ 26674a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2668dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2669cb5b572fSBarry Smith { 2670dfbe8321SBarry Smith PetscErrorCode ierr; 2671cb5b572fSBarry Smith 2672cb5b572fSBarry Smith PetscFunctionBegin; 267333f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 267433f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2675be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2676be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2677be6bf707SBarry Smith 2678700c5bfcSBarry 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"); 2679d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2680cb5b572fSBarry Smith } else { 2681cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2682cb5b572fSBarry Smith } 2683cb5b572fSBarry Smith PetscFunctionReturn(0); 2684cb5b572fSBarry Smith } 2685cb5b572fSBarry Smith 26864a2ae208SSatish Balay #undef __FUNCT__ 26874994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ" 26884994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2689273d9f13SBarry Smith { 2690dfbe8321SBarry Smith PetscErrorCode ierr; 2691273d9f13SBarry Smith 2692273d9f13SBarry Smith PetscFunctionBegin; 2693ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2694273d9f13SBarry Smith PetscFunctionReturn(0); 2695273d9f13SBarry Smith } 2696273d9f13SBarry Smith 26974a2ae208SSatish Balay #undef __FUNCT__ 26988c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ" 26998c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 27006c0721eeSBarry Smith { 27016c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27026e111a19SKarl Rupp 27036c0721eeSBarry Smith PetscFunctionBegin; 27046c0721eeSBarry Smith *array = a->a; 27056c0721eeSBarry Smith PetscFunctionReturn(0); 27066c0721eeSBarry Smith } 27076c0721eeSBarry Smith 27084a2ae208SSatish Balay #undef __FUNCT__ 27098c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ" 27108c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 27116c0721eeSBarry Smith { 27126c0721eeSBarry Smith PetscFunctionBegin; 27136c0721eeSBarry Smith PetscFunctionReturn(0); 27146c0721eeSBarry Smith } 2715273d9f13SBarry Smith 2716b7caf3d6SHong Zhang /*---------------------------------------------*/ 2717b7caf3d6SHong Zhang /* #define JACOBIANCOLOROPT */ 2718b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT) 2719b7caf3d6SHong Zhang #include <petsctime.h> 2720b7caf3d6SHong Zhang #endif 2721ee4f033dSBarry Smith #undef __FUNCT__ 2722ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2723dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2724ee4f033dSBarry Smith { 27256849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void*))coloring->f; 27266849ba73SBarry Smith PetscErrorCode ierr; 2727b7caf3d6SHong Zhang PetscInt k,start,end,l,row,col,**vscaleforrow; 2728b7caf3d6SHong Zhang PetscScalar dx,*y,*xx,*w3_array; 2729b7caf3d6SHong Zhang PetscScalar *vscale_array; 2730b7caf3d6SHong Zhang PetscReal epsilon = coloring->error_rel,umin = coloring->umin,unorm; 2731b7caf3d6SHong Zhang Vec w1 = coloring->w1,w2=coloring->w2,w3; 2732b7caf3d6SHong Zhang void *fctx = coloring->fctx; 2733b7caf3d6SHong Zhang PetscBool flg = PETSC_FALSE; 2734b7caf3d6SHong Zhang PetscInt ctype = coloring->ctype,N,col_start=0,col_end=0; 2735b7caf3d6SHong Zhang Vec x1_tmp; 2736b7caf3d6SHong Zhang Mat_SeqAIJ *csp = (Mat_SeqAIJ*)J->data; 2737b7caf3d6SHong Zhang PetscInt *den2sp=coloring->den2sp,*idx=den2sp; 2738b7caf3d6SHong Zhang PetscScalar *ca=csp->a; 2739b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT) 2740b7caf3d6SHong Zhang PetscLogDouble t0,t1,time_setvalues=0.0; 2741b7caf3d6SHong Zhang #endif 2742b7caf3d6SHong Zhang 2743b7caf3d6SHong Zhang PetscFunctionBegin; 2744b7caf3d6SHong Zhang PetscValidHeaderSpecific(J,MAT_CLASSID,1); 2745b7caf3d6SHong Zhang PetscValidHeaderSpecific(coloring,MAT_FDCOLORING_CLASSID,2); 2746b7caf3d6SHong Zhang PetscValidHeaderSpecific(x1,VEC_CLASSID,3); 2747b7caf3d6SHong Zhang if (!f) SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_WRONGSTATE,"Must call MatFDColoringSetFunction()"); 2748b7caf3d6SHong Zhang 2749b7caf3d6SHong Zhang ierr = PetscLogEventBegin(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 2750b7caf3d6SHong Zhang ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2751b7caf3d6SHong Zhang ierr = PetscOptionsGetBool(NULL,"-mat_fd_coloring_dont_rezero",&flg,NULL);CHKERRQ(ierr); 2752b7caf3d6SHong Zhang if (flg) { 2753b7caf3d6SHong Zhang ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2754b7caf3d6SHong Zhang } else { 2755b7caf3d6SHong Zhang PetscBool assembled; 2756b7caf3d6SHong Zhang ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 2757b7caf3d6SHong Zhang if (assembled) { 2758b7caf3d6SHong Zhang ierr = MatZeroEntries(J);CHKERRQ(ierr); 2759b7caf3d6SHong Zhang } 2760b7caf3d6SHong Zhang } 2761b7caf3d6SHong Zhang 2762b7caf3d6SHong Zhang x1_tmp = x1; 2763b7caf3d6SHong Zhang if (!coloring->vscale) { 2764b7caf3d6SHong Zhang ierr = VecDuplicate(x1_tmp,&coloring->vscale);CHKERRQ(ierr); 2765b7caf3d6SHong Zhang } 2766b7caf3d6SHong Zhang 2767b7caf3d6SHong Zhang if (coloring->htype[0] == 'w') { /* tacky test; need to make systematic if we add other approaches to computing h*/ 2768b7caf3d6SHong Zhang ierr = VecNorm(x1_tmp,NORM_2,&unorm);CHKERRQ(ierr); 2769b7caf3d6SHong Zhang } 2770b7caf3d6SHong Zhang ierr = VecGetOwnershipRange(w1,&start,&end);CHKERRQ(ierr); /* OwnershipRange is used by ghosted x! */ 2771b7caf3d6SHong Zhang 2772b7caf3d6SHong Zhang /* Set w1 = F(x1) */ 2773b7caf3d6SHong Zhang if (!coloring->fset) { 2774b7caf3d6SHong Zhang ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2775b7caf3d6SHong Zhang ierr = (*f)(sctx,x1_tmp,w1,fctx);CHKERRQ(ierr); 2776b7caf3d6SHong Zhang ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2777b7caf3d6SHong Zhang } else { 2778b7caf3d6SHong Zhang coloring->fset = PETSC_FALSE; 2779b7caf3d6SHong Zhang } 2780b7caf3d6SHong Zhang 2781b7caf3d6SHong Zhang if (!coloring->w3) { 2782b7caf3d6SHong Zhang ierr = VecDuplicate(x1_tmp,&coloring->w3);CHKERRQ(ierr); 2783b7caf3d6SHong Zhang ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w3);CHKERRQ(ierr); 2784b7caf3d6SHong Zhang } 2785b7caf3d6SHong Zhang w3 = coloring->w3; 2786b7caf3d6SHong Zhang 2787b7caf3d6SHong Zhang /* Compute all the local scale factors, including ghost points */ 2788b7caf3d6SHong Zhang ierr = VecGetLocalSize(x1_tmp,&N);CHKERRQ(ierr); 2789b7caf3d6SHong Zhang ierr = VecGetArray(x1_tmp,&xx);CHKERRQ(ierr); 2790b7caf3d6SHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2791b7caf3d6SHong Zhang if (ctype == IS_COLORING_GHOSTED) { 2792b7caf3d6SHong Zhang col_start = 0; col_end = N; 2793b7caf3d6SHong Zhang } else if (ctype == IS_COLORING_GLOBAL) { 2794b7caf3d6SHong Zhang xx = xx - start; 2795b7caf3d6SHong Zhang vscale_array = vscale_array - start; 2796b7caf3d6SHong Zhang col_start = start; col_end = N + start; 2797b7caf3d6SHong Zhang } 2798b7caf3d6SHong Zhang for (col=col_start; col<col_end; col++) { 2799b7caf3d6SHong Zhang /* Loop over each local column, vscale[col] = 1./(epsilon*dx[col]) */ 2800b7caf3d6SHong Zhang if (coloring->htype[0] == 'w') { 2801b7caf3d6SHong Zhang dx = 1.0 + unorm; 2802b7caf3d6SHong Zhang } else { 2803b7caf3d6SHong Zhang dx = xx[col]; 2804b7caf3d6SHong Zhang } 2805b7caf3d6SHong Zhang if (dx == (PetscScalar)0.0) dx = 1.0; 2806b7caf3d6SHong Zhang if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2807b7caf3d6SHong Zhang else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2808b7caf3d6SHong Zhang dx *= epsilon; 2809b7caf3d6SHong Zhang vscale_array[col] = (PetscScalar)1.0/dx; 2810b7caf3d6SHong Zhang } 2811b7caf3d6SHong Zhang if (ctype == IS_COLORING_GLOBAL) vscale_array = vscale_array + start; 2812b7caf3d6SHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2813b7caf3d6SHong Zhang if (ctype == IS_COLORING_GLOBAL) { 2814b7caf3d6SHong Zhang ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2815b7caf3d6SHong Zhang ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2816b7caf3d6SHong Zhang } 2817b7caf3d6SHong Zhang 2818b7caf3d6SHong Zhang if (coloring->vscaleforrow) { 2819b7caf3d6SHong Zhang vscaleforrow = coloring->vscaleforrow; 2820b7caf3d6SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)J),PETSC_ERR_ARG_NULL,"Null Object: coloring->vscaleforrow"); 2821b7caf3d6SHong Zhang 2822b7caf3d6SHong Zhang /* 2823b7caf3d6SHong Zhang Loop over each color 2824b7caf3d6SHong Zhang */ 2825b7caf3d6SHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2826b7caf3d6SHong Zhang for (k=0; k<coloring->ncolors; k++) { /* loop over colors */ 2827b7caf3d6SHong Zhang coloring->currentcolor = k; 2828b7caf3d6SHong Zhang 2829b7caf3d6SHong Zhang ierr = VecCopy(x1_tmp,w3);CHKERRQ(ierr); 2830b7caf3d6SHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr); 2831b7caf3d6SHong Zhang if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array - start; 2832b7caf3d6SHong Zhang /* 2833b7caf3d6SHong Zhang Loop over each column associated with color 2834b7caf3d6SHong Zhang adding the perturbation to the vector w3. 2835b7caf3d6SHong Zhang */ 2836b7caf3d6SHong Zhang for (l=0; l<coloring->ncolumns[k]; l++) { /* loop over columns */ 2837b7caf3d6SHong Zhang col = coloring->columns[k][l]; /* local column of the matrix we are probing for */ 2838b7caf3d6SHong Zhang if (coloring->htype[0] == 'w') { 2839b7caf3d6SHong Zhang dx = 1.0 + unorm; 2840b7caf3d6SHong Zhang } else { 2841b7caf3d6SHong Zhang dx = xx[col]; 2842b7caf3d6SHong Zhang } 2843b7caf3d6SHong Zhang if (dx == (PetscScalar)0.0) dx = 1.0; 2844b7caf3d6SHong Zhang if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2845b7caf3d6SHong Zhang else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2846b7caf3d6SHong Zhang dx *= epsilon; 2847b7caf3d6SHong Zhang if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2848b7caf3d6SHong Zhang w3_array[col] += dx; 2849b7caf3d6SHong Zhang } 2850b7caf3d6SHong Zhang if (ctype == IS_COLORING_GLOBAL) w3_array = w3_array + start; 2851b7caf3d6SHong Zhang ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2852b7caf3d6SHong Zhang 2853b7caf3d6SHong Zhang /* 2854b7caf3d6SHong Zhang Evaluate function at w3 = x1 + dx (here dx is a vector of perturbations) 2855b7caf3d6SHong Zhang w2 = F(x1 + dx) - F(x1) 2856b7caf3d6SHong Zhang */ 2857b7caf3d6SHong Zhang ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2858b7caf3d6SHong Zhang ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 2859b7caf3d6SHong Zhang ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2860b7caf3d6SHong Zhang ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2861b7caf3d6SHong Zhang 2862b7caf3d6SHong Zhang /* 2863b7caf3d6SHong Zhang Loop over rows of vector, putting results into Jacobian matrix 2864b7caf3d6SHong Zhang */ 2865b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT) 2866b7caf3d6SHong Zhang ierr = PetscTime(&t0);CHKERRQ(ierr); 2867b7caf3d6SHong Zhang #endif 2868b7caf3d6SHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2869b7caf3d6SHong Zhang for (l=0; l<coloring->nrows[k]; l++) { /* loop over rows */ 2870b7caf3d6SHong Zhang row = coloring->rows[k][l]; /* local row index */ 2871b7caf3d6SHong Zhang y[row] *= vscale_array[vscaleforrow[k][l]]; 2872b7caf3d6SHong Zhang ca[idx[l]] = y[row]; 2873b7caf3d6SHong Zhang } 2874b7caf3d6SHong Zhang idx = idx + coloring->nrows[k]; 2875b7caf3d6SHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2876b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT) 2877b7caf3d6SHong Zhang ierr = PetscTime(&t1);CHKERRQ(ierr); 2878b7caf3d6SHong Zhang time_setvalues += t1-t0; 2879b7caf3d6SHong Zhang #endif 2880b7caf3d6SHong Zhang } /* endof for each color */ 2881b7caf3d6SHong Zhang #if defined(JACOBIANCOLOROPT) 2882b7caf3d6SHong Zhang printf(" MatFDColoringApply_SeqAIJ: time_setvalues %g\n",time_setvalues); 2883b7caf3d6SHong Zhang #endif 2884b7caf3d6SHong Zhang if (ctype == IS_COLORING_GLOBAL) xx = xx + start; 2885b7caf3d6SHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2886b7caf3d6SHong Zhang ierr = VecRestoreArray(x1_tmp,&xx);CHKERRQ(ierr); 2887b7caf3d6SHong Zhang 2888b7caf3d6SHong Zhang coloring->currentcolor = -1; 2889b7caf3d6SHong Zhang ierr = PetscLogEventEnd(MAT_FDColoringApply,coloring,J,x1,0);CHKERRQ(ierr); 2890b7caf3d6SHong Zhang PetscFunctionReturn(0); 2891b7caf3d6SHong Zhang } 2892b7caf3d6SHong Zhang /* --------------------------------------------------------*/ 2893b7caf3d6SHong Zhang 2894b7caf3d6SHong Zhang #undef __FUNCT__ 2895b7caf3d6SHong Zhang #define __FUNCT__ "MatFDColoringApply_SeqAIJ_old" 2896b7caf3d6SHong Zhang PetscErrorCode MatFDColoringApply_SeqAIJ_old(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2897b7caf3d6SHong Zhang { 2898b7caf3d6SHong Zhang PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void*))coloring->f; 2899b7caf3d6SHong Zhang PetscErrorCode ierr; 29004e269d77SPeter Brune PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow; 2901efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 290287828ca2SBarry Smith PetscScalar *vscale_array; 2903ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2904ee4f033dSBarry Smith Vec w1,w2,w3; 2905ee4f033dSBarry Smith void *fctx = coloring->fctx; 2906ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2907ee4f033dSBarry Smith 2908ee4f033dSBarry Smith PetscFunctionBegin; 2909b7caf3d6SHong Zhang printf("MatFDColoringApply_SeqAIJ ...\n"); 2910ee4f033dSBarry Smith if (!coloring->w1) { 2911ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 29123bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w1);CHKERRQ(ierr); 2913ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 29143bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w2);CHKERRQ(ierr); 2915ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 29163bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)coloring,(PetscObject)coloring->w3);CHKERRQ(ierr); 2917ee4f033dSBarry Smith } 2918ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2919ee4f033dSBarry Smith 2920ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 29210298fd71SBarry Smith ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,NULL);CHKERRQ(ierr); 2922ee4f033dSBarry Smith if (flg) { 2923ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2924ee4f033dSBarry Smith } else { 2925ace3abfcSBarry Smith PetscBool assembled; 29260b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 29270b9b6f31SBarry Smith if (assembled) { 2928ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2929ee4f033dSBarry Smith } 29300b9b6f31SBarry Smith } 2931ee4f033dSBarry Smith 2932ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2933ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2934ee4f033dSBarry Smith 29354e269d77SPeter Brune if (!coloring->fset) { 293666f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2937ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 293866f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 29394e269d77SPeter Brune } else { 29404e269d77SPeter Brune coloring->fset = PETSC_FALSE; 2941ee4f033dSBarry Smith } 2942ee4f033dSBarry Smith 2943ee4f033dSBarry Smith /* 2944ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2945ee4f033dSBarry Smith */ 29461ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 29471ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2948ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2949ee4f033dSBarry Smith /* 2950ee4f033dSBarry Smith Loop over each column associated with color adding the 2951ee4f033dSBarry Smith perturbation to the vector w3. 2952ee4f033dSBarry Smith */ 2953ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2954ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2955ee4f033dSBarry Smith dx = xx[col]; 2956ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2957ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2958ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2959ee4f033dSBarry Smith dx *= epsilon; 2960ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2961ee4f033dSBarry Smith } 2962ee4f033dSBarry Smith } 29632205254eSKarl Rupp vscale_array = vscale_array + start; 29642205254eSKarl Rupp 29652205254eSKarl Rupp ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2966ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2967ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2968ee4f033dSBarry Smith 2969ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2970ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2971ee4f033dSBarry Smith 2972ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2973ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2974ee4f033dSBarry Smith 29751ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2976ee4f033dSBarry Smith /* 2977ee4f033dSBarry Smith Loop over each color 2978ee4f033dSBarry Smith */ 2979ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 298049b058dcSBarry Smith coloring->currentcolor = k; 29812205254eSKarl Rupp 2982ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 29831ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2984ee4f033dSBarry Smith /* 2985ee4f033dSBarry Smith Loop over each column associated with color adding the 2986ee4f033dSBarry Smith perturbation to the vector w3. 2987ee4f033dSBarry Smith */ 2988ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2989ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2990ee4f033dSBarry Smith dx = xx[col]; 29915b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2992ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2993ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2994ee4f033dSBarry Smith dx *= epsilon; 2995e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2996ee4f033dSBarry Smith w3_array[col] += dx; 2997ee4f033dSBarry Smith } 29981ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2999ee4f033dSBarry Smith 3000ee4f033dSBarry Smith /* 3001ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 3002ee4f033dSBarry Smith */ 3003ee4f033dSBarry Smith 300466f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 3005ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 300666f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 3007efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 3008ee4f033dSBarry Smith 3009ee4f033dSBarry Smith /* 3010ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 3011ee4f033dSBarry Smith */ 30121ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 3013ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 3014ee4f033dSBarry Smith row = coloring->rows[k][l]; 3015ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 3016ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 3017ee4f033dSBarry Smith srow = row + start; 3018ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 3019ee4f033dSBarry Smith } 30201ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 3021ee4f033dSBarry Smith } 302249b058dcSBarry Smith coloring->currentcolor = k; 30232205254eSKarl Rupp 30241ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 30252205254eSKarl Rupp xx = xx + start; 30262205254eSKarl Rupp ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 3027ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3028ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3029ee4f033dSBarry Smith PetscFunctionReturn(0); 3030ee4f033dSBarry Smith } 3031ee4f033dSBarry Smith 30328229c054SShri Abhyankar /* 30338229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 30348229c054SShri Abhyankar have different nonzero structure. 30358229c054SShri Abhyankar */ 3036ac90fabeSBarry Smith #undef __FUNCT__ 30378229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 30388229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3039ec7775f6SShri Abhyankar { 30408229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 3041ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3042ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3043ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 3044ec7775f6SShri Abhyankar 3045ec7775f6SShri Abhyankar PetscFunctionBegin; 3046ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3047ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 30488af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 30498af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 30508af7cee1SJed Brown nnz[i] = 0; 30518af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 30528af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 30538af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 30548af7cee1SJed Brown nnz[i]++; 30558af7cee1SJed Brown } 30568af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3057ec7775f6SShri Abhyankar } 3058ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3059ec7775f6SShri Abhyankar } 3060ec7775f6SShri Abhyankar 3061ec7775f6SShri Abhyankar #undef __FUNCT__ 3062ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 3063f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3064ac90fabeSBarry Smith { 3065dfbe8321SBarry Smith PetscErrorCode ierr; 306697f1f81fSBarry Smith PetscInt i; 3067ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3068c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 3069ac90fabeSBarry Smith 3070ac90fabeSBarry Smith PetscFunctionBegin; 3071c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 3072ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 3073f4df32b1SMatthew Knepley PetscScalar alpha = a; 30748b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 3075acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3076c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3077a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 3078a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 30796bf464f9SBarry Smith ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr); 3080a30b2313SHong Zhang } 3081a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 30820298fd71SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr); 3083a30b2313SHong Zhang y->XtoY = X; 3084407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 3085c537a176SHong Zhang } 3086f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 3087ba0e910bSBarry 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); 3088ac90fabeSBarry Smith } else { 30898229c054SShri Abhyankar Mat B; 30908229c054SShri Abhyankar PetscInt *nnz; 309116b2e9dcSShri Abhyankar ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 3092ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3093bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 30944aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 3095a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr); 3096176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 30978229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3098ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3099ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 3100ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 31018229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3102ac90fabeSBarry Smith } 3103ac90fabeSBarry Smith PetscFunctionReturn(0); 3104ac90fabeSBarry Smith } 3105ac90fabeSBarry Smith 3106521d7252SBarry Smith #undef __FUNCT__ 3107354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 31087087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3109354c94deSBarry Smith { 3110354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3111354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3112354c94deSBarry Smith PetscInt i,nz; 3113354c94deSBarry Smith PetscScalar *a; 3114354c94deSBarry Smith 3115354c94deSBarry Smith PetscFunctionBegin; 3116354c94deSBarry Smith nz = aij->nz; 3117354c94deSBarry Smith a = aij->a; 31182205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3119354c94deSBarry Smith #else 3120354c94deSBarry Smith PetscFunctionBegin; 3121354c94deSBarry Smith #endif 3122354c94deSBarry Smith PetscFunctionReturn(0); 3123354c94deSBarry Smith } 3124354c94deSBarry Smith 3125e34fafa9SBarry Smith #undef __FUNCT__ 3126985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 3127985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3128e34fafa9SBarry Smith { 3129e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3130e34fafa9SBarry Smith PetscErrorCode ierr; 3131d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3132e34fafa9SBarry Smith PetscReal atmp; 3133985db425SBarry Smith PetscScalar *x; 3134e34fafa9SBarry Smith MatScalar *aa; 3135e34fafa9SBarry Smith 3136e34fafa9SBarry Smith PetscFunctionBegin; 3137e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3138e34fafa9SBarry Smith aa = a->a; 3139e34fafa9SBarry Smith ai = a->i; 3140e34fafa9SBarry Smith aj = a->j; 3141e34fafa9SBarry Smith 3142985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3143e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3144e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3145e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3146e34fafa9SBarry Smith for (i=0; i<m; i++) { 3147e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 31489189402eSHong Zhang x[i] = 0.0; 3149e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3150985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3151985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3152985db425SBarry Smith aa++; aj++; 3153985db425SBarry Smith } 3154985db425SBarry Smith } 3155985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3156985db425SBarry Smith PetscFunctionReturn(0); 3157985db425SBarry Smith } 3158985db425SBarry Smith 3159985db425SBarry Smith #undef __FUNCT__ 3160985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 3161985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3162985db425SBarry Smith { 3163985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3164985db425SBarry Smith PetscErrorCode ierr; 3165d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3166985db425SBarry Smith PetscScalar *x; 3167985db425SBarry Smith MatScalar *aa; 3168985db425SBarry Smith 3169985db425SBarry Smith PetscFunctionBegin; 3170e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3171985db425SBarry Smith aa = a->a; 3172985db425SBarry Smith ai = a->i; 3173985db425SBarry Smith aj = a->j; 3174985db425SBarry Smith 3175985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3176985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3177985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3178e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3179985db425SBarry Smith for (i=0; i<m; i++) { 3180985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3181d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3182985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3183985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3184985db425SBarry Smith x[i] = 0.0; 3185985db425SBarry Smith if (idx) { 3186985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3187985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 3188985db425SBarry Smith if (aj[j] > j) { 3189985db425SBarry Smith idx[i] = j; 3190985db425SBarry Smith break; 3191985db425SBarry Smith } 3192985db425SBarry Smith } 3193985db425SBarry Smith } 3194985db425SBarry Smith } 3195985db425SBarry Smith for (j=0; j<ncols; j++) { 3196985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3197985db425SBarry Smith aa++; aj++; 3198985db425SBarry Smith } 3199985db425SBarry Smith } 3200985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3201985db425SBarry Smith PetscFunctionReturn(0); 3202985db425SBarry Smith } 3203985db425SBarry Smith 3204985db425SBarry Smith #undef __FUNCT__ 3205c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 3206c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3207c87e5d42SMatthew Knepley { 3208c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3209c87e5d42SMatthew Knepley PetscErrorCode ierr; 3210c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3211c87e5d42SMatthew Knepley PetscReal atmp; 3212c87e5d42SMatthew Knepley PetscScalar *x; 3213c87e5d42SMatthew Knepley MatScalar *aa; 3214c87e5d42SMatthew Knepley 3215c87e5d42SMatthew Knepley PetscFunctionBegin; 3216e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3217c87e5d42SMatthew Knepley aa = a->a; 3218c87e5d42SMatthew Knepley ai = a->i; 3219c87e5d42SMatthew Knepley aj = a->j; 3220c87e5d42SMatthew Knepley 3221c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3222c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3223c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 32243bb78c5cSMatthew 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); 3225c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3226c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3227289a08f5SMatthew Knepley if (ncols) { 3228289a08f5SMatthew Knepley /* Get first nonzero */ 3229289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 3230289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 32312205254eSKarl Rupp if (atmp > 1.0e-12) { 32322205254eSKarl Rupp x[i] = atmp; 32332205254eSKarl Rupp if (idx) idx[i] = aj[j]; 32342205254eSKarl Rupp break; 32352205254eSKarl Rupp } 3236289a08f5SMatthew Knepley } 323712431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 3238289a08f5SMatthew Knepley } else { 3239289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 3240289a08f5SMatthew Knepley } 3241c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 3242c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 3243289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3244c87e5d42SMatthew Knepley aa++; aj++; 3245c87e5d42SMatthew Knepley } 3246c87e5d42SMatthew Knepley } 3247c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3248c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3249c87e5d42SMatthew Knepley } 3250c87e5d42SMatthew Knepley 3251c87e5d42SMatthew Knepley #undef __FUNCT__ 3252985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 3253985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3254985db425SBarry Smith { 3255985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3256985db425SBarry Smith PetscErrorCode ierr; 3257d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3258985db425SBarry Smith PetscScalar *x; 3259985db425SBarry Smith MatScalar *aa; 3260985db425SBarry Smith 3261985db425SBarry Smith PetscFunctionBegin; 3262e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3263985db425SBarry Smith aa = a->a; 3264985db425SBarry Smith ai = a->i; 3265985db425SBarry Smith aj = a->j; 3266985db425SBarry Smith 3267985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3268985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3269985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3270e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3271985db425SBarry Smith for (i=0; i<m; i++) { 3272985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3273d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3274985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3275985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3276985db425SBarry Smith x[i] = 0.0; 3277985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3278985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3279985db425SBarry Smith for (j=0; j<ncols; j++) { 3280985db425SBarry Smith if (aj[j] > j) { 3281985db425SBarry Smith idx[i] = j; 3282985db425SBarry Smith break; 3283985db425SBarry Smith } 3284985db425SBarry Smith } 3285985db425SBarry Smith } 3286985db425SBarry Smith } 3287985db425SBarry Smith for (j=0; j<ncols; j++) { 3288985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3289985db425SBarry Smith aa++; aj++; 3290e34fafa9SBarry Smith } 3291e34fafa9SBarry Smith } 3292e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3293e34fafa9SBarry Smith PetscFunctionReturn(0); 3294e34fafa9SBarry Smith } 3295bbead8a2SBarry Smith 3296bbead8a2SBarry Smith #include <petscblaslapack.h> 329706873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h> 3298bbead8a2SBarry Smith 3299bbead8a2SBarry Smith #undef __FUNCT__ 3300bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ" 3301713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3302bbead8a2SBarry Smith { 3303bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3304bbead8a2SBarry Smith PetscErrorCode ierr; 330534fc4b71SJed 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; 3306bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 3307bbead8a2SBarry Smith PetscReal shift = 0.0; 3308bbead8a2SBarry Smith 3309bbead8a2SBarry Smith PetscFunctionBegin; 33104a0d0026SBarry Smith if (a->ibdiagvalid) { 33114a0d0026SBarry Smith if (values) *values = a->ibdiag; 33124a0d0026SBarry Smith PetscFunctionReturn(0); 33134a0d0026SBarry Smith } 3314bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3315bbead8a2SBarry Smith if (!a->ibdiag) { 3316bbead8a2SBarry Smith ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr); 33173bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3318bbead8a2SBarry Smith } 3319bbead8a2SBarry Smith diag = a->ibdiag; 3320bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3321bbead8a2SBarry Smith /* factor and invert each block */ 3322bbead8a2SBarry Smith switch (bs) { 3323bbead8a2SBarry Smith case 1: 3324bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3325bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3326bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3327bbead8a2SBarry Smith } 3328bbead8a2SBarry Smith break; 3329bbead8a2SBarry Smith case 2: 3330bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3331bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3332bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 333396b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr); 333496b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3335bbead8a2SBarry Smith diag += 4; 3336bbead8a2SBarry Smith } 3337bbead8a2SBarry Smith break; 3338bbead8a2SBarry Smith case 3: 3339bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3340bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3341bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 334296b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr); 334396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3344bbead8a2SBarry Smith diag += 9; 3345bbead8a2SBarry Smith } 3346bbead8a2SBarry Smith break; 3347bbead8a2SBarry Smith case 4: 3348bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3349bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3350bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 335196b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr); 335296b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3353bbead8a2SBarry Smith diag += 16; 3354bbead8a2SBarry Smith } 3355bbead8a2SBarry Smith break; 3356bbead8a2SBarry Smith case 5: 3357bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3358bbead8a2SBarry 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; 3359bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 336096b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr); 336196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3362bbead8a2SBarry Smith diag += 25; 3363bbead8a2SBarry Smith } 3364bbead8a2SBarry Smith break; 3365bbead8a2SBarry Smith case 6: 3366bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3367bbead8a2SBarry 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; 3368bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 336996b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr); 337096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3371bbead8a2SBarry Smith diag += 36; 3372bbead8a2SBarry Smith } 3373bbead8a2SBarry Smith break; 3374bbead8a2SBarry Smith case 7: 3375bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3376bbead8a2SBarry 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; 3377bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 337896b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr); 337996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3380bbead8a2SBarry Smith diag += 49; 3381bbead8a2SBarry Smith } 3382bbead8a2SBarry Smith break; 3383bbead8a2SBarry Smith default: 3384bbead8a2SBarry Smith ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&IJ);CHKERRQ(ierr); 3385bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3386bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3387bbead8a2SBarry Smith IJ[j] = bs*i + j; 3388bbead8a2SBarry Smith } 3389bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 339096b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr); 339196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3392bbead8a2SBarry Smith diag += bs2; 3393bbead8a2SBarry Smith } 3394bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3395bbead8a2SBarry Smith } 3396bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3397bbead8a2SBarry Smith PetscFunctionReturn(0); 3398bbead8a2SBarry Smith } 3399bbead8a2SBarry Smith 340073a71a0fSBarry Smith #undef __FUNCT__ 340173a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ" 340273a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 340373a71a0fSBarry Smith { 340473a71a0fSBarry Smith PetscErrorCode ierr; 340573a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 340673a71a0fSBarry Smith PetscScalar a; 340773a71a0fSBarry Smith PetscInt m,n,i,j,col; 340873a71a0fSBarry Smith 340973a71a0fSBarry Smith PetscFunctionBegin; 341073a71a0fSBarry Smith if (!x->assembled) { 341173a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 341273a71a0fSBarry Smith for (i=0; i<m; i++) { 341373a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 341473a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 341573a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 341673a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 341773a71a0fSBarry Smith } 341873a71a0fSBarry Smith } 341973a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 342073a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 342173a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 342273a71a0fSBarry Smith PetscFunctionReturn(0); 342373a71a0fSBarry Smith } 342473a71a0fSBarry Smith 34257087cfbeSBarry Smith extern PetscErrorCode MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*); 3426682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 34270a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3428cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3429cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3430cb5b572fSBarry Smith MatMult_SeqAIJ, 343197304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 34327c922b88SBarry Smith MatMultTranspose_SeqAIJ, 34337c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3434db4efbfdSBarry Smith 0, 3435db4efbfdSBarry Smith 0, 3436db4efbfdSBarry Smith 0, 3437db4efbfdSBarry Smith /* 10*/ 0, 3438cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3439cb5b572fSBarry Smith 0, 344041f059aeSBarry Smith MatSOR_SeqAIJ, 344117ab2063SBarry Smith MatTranspose_SeqAIJ, 344297304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3443cb5b572fSBarry Smith MatEqual_SeqAIJ, 3444cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3445cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3446cb5b572fSBarry Smith MatNorm_SeqAIJ, 344797304618SKris Buschelman /* 20*/ 0, 3448cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3449cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3450cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3451d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3452db4efbfdSBarry Smith 0, 3453db4efbfdSBarry Smith 0, 3454db4efbfdSBarry Smith 0, 3455db4efbfdSBarry Smith 0, 34564994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3457db4efbfdSBarry Smith 0, 3458db4efbfdSBarry Smith 0, 34598c778c55SBarry Smith 0, 34608c778c55SBarry Smith 0, 3461d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3462cb5b572fSBarry Smith 0, 3463cb5b572fSBarry Smith 0, 3464cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3465cb5b572fSBarry Smith 0, 3466d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 3467cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3468cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3469cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3470cb5b572fSBarry Smith MatCopy_SeqAIJ, 3471d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3472cb5b572fSBarry Smith MatScale_SeqAIJ, 3473cb5b572fSBarry Smith 0, 347479299369SBarry Smith MatDiagonalSet_SeqAIJ, 34756e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 347673a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 34773b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 34783b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 34793b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3480a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 3481d519adbfSMatthew Knepley /* 54*/ MatFDColoringCreate_SeqAIJ, 3482b9617806SBarry Smith 0, 34830513a670SBarry Smith 0, 3484cda55fadSBarry Smith MatPermute_SeqAIJ, 3485cda55fadSBarry Smith 0, 3486d519adbfSMatthew Knepley /* 59*/ 0, 3487b9b97703SBarry Smith MatDestroy_SeqAIJ, 3488b9b97703SBarry Smith MatView_SeqAIJ, 3489357abbc8SBarry Smith 0, 3490321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3491321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3492321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3493ee4f033dSBarry Smith 0, 3494ee4f033dSBarry Smith 0, 3495ee4f033dSBarry Smith 0, 3496d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3497c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3498ee4f033dSBarry Smith 0, 3499ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 3500dcf5cc72SBarry Smith 0, 3501d519adbfSMatthew Knepley /* 74*/ MatSetValuesAdifor_SeqAIJ, 35023acb8795SBarry Smith MatFDColoringApply_AIJ, 350397304618SKris Buschelman 0, 350497304618SKris Buschelman 0, 350597304618SKris Buschelman 0, 35066ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 350797304618SKris Buschelman 0, 350897304618SKris Buschelman 0, 350997304618SKris Buschelman 0, 3510bc011b1eSHong Zhang MatLoad_SeqAIJ, 3511d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 35121cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 35136284ec50SHong Zhang 0, 35146284ec50SHong Zhang 0, 3515bc011b1eSHong Zhang 0, 3516d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 351726be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 351826be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 351965e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 35204a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 352165e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 35226fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 35236fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 35246fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 35252121bac1SHong Zhang 0, 35262121bac1SHong Zhang /* 99*/ 0, 3527609c6c4dSKris Buschelman 0, 3528609c6c4dSKris Buschelman 0, 352987d4246cSBarry Smith MatConjugate_SeqAIJ, 353087d4246cSBarry Smith 0, 3531d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 353299cafbc1SBarry Smith MatRealPart_SeqAIJ, 3533f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3534f5edf698SHong Zhang 0, 35352bebee5dSHong Zhang 0, 3536cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3537985db425SBarry Smith 0, 35382af78befSBarry Smith MatGetRowMin_SeqAIJ, 35392af78befSBarry Smith 0, 3540599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3541d519adbfSMatthew Knepley /*114*/ 0, 3542599ef60dSHong Zhang 0, 35433c2a7987SHong Zhang 0, 3544fe97e370SBarry Smith 0, 3545fbdbba38SShri Abhyankar 0, 3546fbdbba38SShri Abhyankar /*119*/ 0, 3547fbdbba38SShri Abhyankar 0, 3548fbdbba38SShri Abhyankar 0, 354982d44351SHong Zhang 0, 3550b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 35510716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3552bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 355337868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 355437868618SMatthew G Knepley 0, 355537868618SMatthew G Knepley 0, 35565df89d91SHong Zhang /*129*/ 0, 355775648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 355875648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 355975648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3560b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3561b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 35622b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 35632b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 35642b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 35653964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 35663964eb88SJed Brown /*139*/0, 35673964eb88SJed Brown 0 35689e29f15eSvictorle }; 356917ab2063SBarry Smith 35704a2ae208SSatish Balay #undef __FUNCT__ 35714a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 35727087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3573bef8e0ddSBarry Smith { 3574bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 357597f1f81fSBarry Smith PetscInt i,nz,n; 3576bef8e0ddSBarry Smith 3577bef8e0ddSBarry Smith PetscFunctionBegin; 3578bef8e0ddSBarry Smith nz = aij->maxnz; 3579d0f46423SBarry Smith n = mat->rmap->n; 3580bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3581bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3582bef8e0ddSBarry Smith } 3583bef8e0ddSBarry Smith aij->nz = nz; 3584bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3585bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3586bef8e0ddSBarry Smith } 3587bef8e0ddSBarry Smith PetscFunctionReturn(0); 3588bef8e0ddSBarry Smith } 3589bef8e0ddSBarry Smith 35904a2ae208SSatish Balay #undef __FUNCT__ 35914a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3592bef8e0ddSBarry Smith /*@ 3593bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3594bef8e0ddSBarry Smith in the matrix. 3595bef8e0ddSBarry Smith 3596bef8e0ddSBarry Smith Input Parameters: 3597bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3598bef8e0ddSBarry Smith - indices - the column indices 3599bef8e0ddSBarry Smith 360015091d37SBarry Smith Level: advanced 360115091d37SBarry Smith 3602bef8e0ddSBarry Smith Notes: 3603bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3604bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3605bef8e0ddSBarry Smith of the MatSetValues() operation. 3606bef8e0ddSBarry Smith 3607bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3608d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3609bef8e0ddSBarry Smith 3610bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3611bef8e0ddSBarry Smith 3612b9617806SBarry Smith The indices should start with zero, not one. 3613b9617806SBarry Smith 3614bef8e0ddSBarry Smith @*/ 36157087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3616bef8e0ddSBarry Smith { 36174ac538c5SBarry Smith PetscErrorCode ierr; 3618bef8e0ddSBarry Smith 3619bef8e0ddSBarry Smith PetscFunctionBegin; 36200700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 36214482741eSBarry Smith PetscValidPointer(indices,2); 36224ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3623bef8e0ddSBarry Smith PetscFunctionReturn(0); 3624bef8e0ddSBarry Smith } 3625bef8e0ddSBarry Smith 3626be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3627be6bf707SBarry Smith 36284a2ae208SSatish Balay #undef __FUNCT__ 36294a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 36307087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3631be6bf707SBarry Smith { 3632be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 36336849ba73SBarry Smith PetscErrorCode ierr; 3634d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3635be6bf707SBarry Smith 3636be6bf707SBarry Smith PetscFunctionBegin; 3637f23aa3ddSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3638be6bf707SBarry Smith 3639be6bf707SBarry Smith /* allocate space for values if not already there */ 3640be6bf707SBarry Smith if (!aij->saved_values) { 364187828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 36423bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3643be6bf707SBarry Smith } 3644be6bf707SBarry Smith 3645be6bf707SBarry Smith /* copy values over */ 364687828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3647be6bf707SBarry Smith PetscFunctionReturn(0); 3648be6bf707SBarry Smith } 3649be6bf707SBarry Smith 36504a2ae208SSatish Balay #undef __FUNCT__ 3651b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3652be6bf707SBarry Smith /*@ 3653be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3654be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3655be6bf707SBarry Smith nonlinear portion. 3656be6bf707SBarry Smith 3657be6bf707SBarry Smith Collect on Mat 3658be6bf707SBarry Smith 3659be6bf707SBarry Smith Input Parameters: 36600e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3661be6bf707SBarry Smith 366215091d37SBarry Smith Level: advanced 366315091d37SBarry Smith 3664be6bf707SBarry Smith Common Usage, with SNESSolve(): 3665be6bf707SBarry Smith $ Create Jacobian matrix 3666be6bf707SBarry Smith $ Set linear terms into matrix 3667be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3668be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3669be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3670512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3671be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3672be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3673be6bf707SBarry Smith $ In your Jacobian routine 3674be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3675be6bf707SBarry Smith $ Set nonlinear terms in matrix 3676be6bf707SBarry Smith 3677be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3678be6bf707SBarry Smith $ // build linear portion of Jacobian 3679512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3680be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3681be6bf707SBarry Smith $ loop over nonlinear iterations 3682be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3683be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3684be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3685be6bf707SBarry Smith $ Solve linear system with Jacobian 3686be6bf707SBarry Smith $ endloop 3687be6bf707SBarry Smith 3688be6bf707SBarry Smith Notes: 3689be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3690512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3691be6bf707SBarry Smith calling this routine. 3692be6bf707SBarry Smith 36930c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 36940c468ba9SBarry Smith and does not allocated additional space. 36950c468ba9SBarry Smith 3696be6bf707SBarry Smith .seealso: MatRetrieveValues() 3697be6bf707SBarry Smith 3698be6bf707SBarry Smith @*/ 36997087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3700be6bf707SBarry Smith { 37014ac538c5SBarry Smith PetscErrorCode ierr; 3702be6bf707SBarry Smith 3703be6bf707SBarry Smith PetscFunctionBegin; 37040700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3705e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3706e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 37074ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3708be6bf707SBarry Smith PetscFunctionReturn(0); 3709be6bf707SBarry Smith } 3710be6bf707SBarry Smith 37114a2ae208SSatish Balay #undef __FUNCT__ 37124a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 37137087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3714be6bf707SBarry Smith { 3715be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 37166849ba73SBarry Smith PetscErrorCode ierr; 3717d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3718be6bf707SBarry Smith 3719be6bf707SBarry Smith PetscFunctionBegin; 3720f23aa3ddSBarry Smith if (aij->nonew != 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3721f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3722be6bf707SBarry Smith /* copy values over */ 372387828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3724be6bf707SBarry Smith PetscFunctionReturn(0); 3725be6bf707SBarry Smith } 3726be6bf707SBarry Smith 37274a2ae208SSatish Balay #undef __FUNCT__ 37284a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3729be6bf707SBarry Smith /*@ 3730be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3731be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3732be6bf707SBarry Smith nonlinear portion. 3733be6bf707SBarry Smith 3734be6bf707SBarry Smith Collect on Mat 3735be6bf707SBarry Smith 3736be6bf707SBarry Smith Input Parameters: 3737be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3738be6bf707SBarry Smith 373915091d37SBarry Smith Level: advanced 374015091d37SBarry Smith 3741be6bf707SBarry Smith .seealso: MatStoreValues() 3742be6bf707SBarry Smith 3743be6bf707SBarry Smith @*/ 37447087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3745be6bf707SBarry Smith { 37464ac538c5SBarry Smith PetscErrorCode ierr; 3747be6bf707SBarry Smith 3748be6bf707SBarry Smith PetscFunctionBegin; 37490700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3750e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3751e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 37524ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3753be6bf707SBarry Smith PetscFunctionReturn(0); 3754be6bf707SBarry Smith } 3755be6bf707SBarry Smith 3756f83d6046SBarry Smith 3757be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 37584a2ae208SSatish Balay #undef __FUNCT__ 37594a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 376017ab2063SBarry Smith /*@C 3761682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 37620d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 37636e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 376451c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 37652bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 376617ab2063SBarry Smith 3767db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3768db81eaa0SLois Curfman McInnes 376917ab2063SBarry Smith Input Parameters: 3770db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 377117ab2063SBarry Smith . m - number of rows 377217ab2063SBarry Smith . n - number of columns 377317ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 377451c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 37750298fd71SBarry Smith (possibly different for each row) or NULL 377617ab2063SBarry Smith 377717ab2063SBarry Smith Output Parameter: 3778416022c9SBarry Smith . A - the matrix 377917ab2063SBarry Smith 3780175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3781ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3782175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3783175b88e8SBarry Smith 3784b259b22eSLois Curfman McInnes Notes: 378549a6f317SBarry Smith If nnz is given then nz is ignored 378649a6f317SBarry Smith 378717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 378817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 37890002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 379044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 379117ab2063SBarry Smith 379217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 37930298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 37943d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 37956da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 379617ab2063SBarry Smith 3797682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 37984fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3799682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 38006c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 38016c7ebb05SLois Curfman McInnes 38026c7ebb05SLois Curfman McInnes Options Database Keys: 3803698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 38049db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 380517ab2063SBarry Smith 3806027ccd11SLois Curfman McInnes Level: intermediate 3807027ccd11SLois Curfman McInnes 380869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 380936db0b34SBarry Smith 381017ab2063SBarry Smith @*/ 38117087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 381217ab2063SBarry Smith { 3813dfbe8321SBarry Smith PetscErrorCode ierr; 38146945ee14SBarry Smith 38153a40ed3dSBarry Smith PetscFunctionBegin; 3816f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3817117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3818c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3819d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3820273d9f13SBarry Smith PetscFunctionReturn(0); 3821273d9f13SBarry Smith } 3822273d9f13SBarry Smith 38234a2ae208SSatish Balay #undef __FUNCT__ 38244a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3825273d9f13SBarry Smith /*@C 3826273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3827273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3828273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3829273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3830273d9f13SBarry Smith 3831273d9f13SBarry Smith Collective on MPI_Comm 3832273d9f13SBarry Smith 3833273d9f13SBarry Smith Input Parameters: 3834117016b1SBarry Smith + B - The matrix-free 3835273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3836273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 38370298fd71SBarry Smith (possibly different for each row) or NULL 3838273d9f13SBarry Smith 3839273d9f13SBarry Smith Notes: 384049a6f317SBarry Smith If nnz is given then nz is ignored 384149a6f317SBarry Smith 3842273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3843273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3844273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3845273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3846273d9f13SBarry Smith 3847273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 38480298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3849273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3850273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3851273d9f13SBarry Smith 3852aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3853aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3854aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3855aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3856aa95bbe8SBarry Smith 3857a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3858a96a251dSBarry Smith entries or columns indices 3859a96a251dSBarry Smith 3860273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3861273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3862273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3863273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3864273d9f13SBarry Smith 3865273d9f13SBarry Smith Options Database Keys: 3866698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3867698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3868273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3869273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3870273d9f13SBarry Smith the user still MUST index entries starting at 0! 3871273d9f13SBarry Smith 3872273d9f13SBarry Smith Level: intermediate 3873273d9f13SBarry Smith 387469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3875273d9f13SBarry Smith 3876273d9f13SBarry Smith @*/ 38777087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3878273d9f13SBarry Smith { 38794ac538c5SBarry Smith PetscErrorCode ierr; 3880a23d5eceSKris Buschelman 3881a23d5eceSKris Buschelman PetscFunctionBegin; 38826ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 38836ba663aaSJed Brown PetscValidType(B,1); 38844ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3885a23d5eceSKris Buschelman PetscFunctionReturn(0); 3886a23d5eceSKris Buschelman } 3887a23d5eceSKris Buschelman 3888a23d5eceSKris Buschelman #undef __FUNCT__ 3889a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 38907087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3891a23d5eceSKris Buschelman { 3892273d9f13SBarry Smith Mat_SeqAIJ *b; 38932576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 38946849ba73SBarry Smith PetscErrorCode ierr; 389597f1f81fSBarry Smith PetscInt i; 3896273d9f13SBarry Smith 3897273d9f13SBarry Smith PetscFunctionBegin; 38982576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3899a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3900c461c341SBarry Smith skipallocation = PETSC_TRUE; 3901c461c341SBarry Smith nz = 0; 3902c461c341SBarry Smith } 3903c461c341SBarry Smith 390426283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 390526283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3906899cda47SBarry Smith 3907435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3908e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3909b73539f3SBarry Smith if (nnz) { 3910d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3911e32f2f54SBarry 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]); 3912e32f2f54SBarry 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); 3913b73539f3SBarry Smith } 3914b73539f3SBarry Smith } 3915b73539f3SBarry Smith 3916273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 39172205254eSKarl Rupp 3918273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3919273d9f13SBarry Smith 3920ab93d7beSBarry Smith if (!skipallocation) { 39212ee49352SLisandro Dalcin if (!b->imax) { 3922d0f46423SBarry Smith ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr); 39233bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 39242ee49352SLisandro Dalcin } 3925273d9f13SBarry Smith if (!nnz) { 3926435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3927c62bd62aSJed Brown else if (nz < 0) nz = 1; 3928d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3929d0f46423SBarry Smith nz = nz*B->rmap->n; 3930273d9f13SBarry Smith } else { 3931273d9f13SBarry Smith nz = 0; 3932d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3933273d9f13SBarry Smith } 3934ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 39352205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3936ab93d7beSBarry Smith 3937273d9f13SBarry Smith /* allocate the matrix space */ 39382ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3939d0f46423SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr); 39403bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3941bfeeae90SHong Zhang b->i[0] = 0; 3942d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 39435da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 39445da197adSKris Buschelman } 3945273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3946e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3947e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3948b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 3949b31eba2aSShri Abhyankar ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr); 3950b31eba2aSShri Abhyankar #endif 3951c461c341SBarry Smith } else { 3952e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3953e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3954c461c341SBarry Smith } 3955273d9f13SBarry Smith 3956273d9f13SBarry Smith b->nz = 0; 3957273d9f13SBarry Smith b->maxnz = nz; 3958273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 39592205254eSKarl Rupp if (realalloc) { 39602205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 39612205254eSKarl Rupp } 3962273d9f13SBarry Smith PetscFunctionReturn(0); 3963273d9f13SBarry Smith } 3964273d9f13SBarry Smith 3965a1661176SMatthew Knepley #undef __FUNCT__ 3966a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 396758d36128SBarry Smith /*@ 3968a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3969a1661176SMatthew Knepley 3970a1661176SMatthew Knepley Input Parameters: 3971a1661176SMatthew Knepley + B - the matrix 3972a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3973a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3974a1661176SMatthew Knepley - v - optional values in the matrix 3975a1661176SMatthew Knepley 3976a1661176SMatthew Knepley Level: developer 3977a1661176SMatthew Knepley 397858d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 397958d36128SBarry Smith 3980a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3981a1661176SMatthew Knepley 3982a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3983a1661176SMatthew Knepley @*/ 3984a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3985a1661176SMatthew Knepley { 3986a1661176SMatthew Knepley PetscErrorCode ierr; 3987a1661176SMatthew Knepley 3988a1661176SMatthew Knepley PetscFunctionBegin; 39890700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 39906ba663aaSJed Brown PetscValidType(B,1); 39914ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3992a1661176SMatthew Knepley PetscFunctionReturn(0); 3993a1661176SMatthew Knepley } 3994a1661176SMatthew Knepley 3995a1661176SMatthew Knepley #undef __FUNCT__ 3996a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 39977087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3998a1661176SMatthew Knepley { 3999a1661176SMatthew Knepley PetscInt i; 4000a1661176SMatthew Knepley PetscInt m,n; 4001a1661176SMatthew Knepley PetscInt nz; 4002a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 4003a1661176SMatthew Knepley PetscScalar *values; 4004a1661176SMatthew Knepley PetscErrorCode ierr; 4005a1661176SMatthew Knepley 4006a1661176SMatthew Knepley PetscFunctionBegin; 400765e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4008779a8d59SSatish Balay 4009779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4010779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4011779a8d59SSatish Balay 4012779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4013a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 4014a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4015b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 4016a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 401765e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4018a1661176SMatthew Knepley nnz[i] = nz; 4019a1661176SMatthew Knepley } 4020a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4021a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4022a1661176SMatthew Knepley 4023a1661176SMatthew Knepley if (v) { 4024a1661176SMatthew Knepley values = (PetscScalar*) v; 4025a1661176SMatthew Knepley } else { 40260e83c824SBarry Smith ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr); 4027a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 4028a1661176SMatthew Knepley } 4029a1661176SMatthew Knepley 4030a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4031b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 4032b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 4033a1661176SMatthew Knepley } 4034a1661176SMatthew Knepley 4035a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4036a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4037a1661176SMatthew Knepley 4038a1661176SMatthew Knepley if (!v) { 4039a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 4040a1661176SMatthew Knepley } 40417827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4042a1661176SMatthew Knepley PetscFunctionReturn(0); 4043a1661176SMatthew Knepley } 4044a1661176SMatthew Knepley 4045c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 404606873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h> 4047170fe5c8SBarry Smith 4048170fe5c8SBarry Smith #undef __FUNCT__ 4049170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 4050170fe5c8SBarry Smith /* 4051170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4052170fe5c8SBarry Smith 4053170fe5c8SBarry Smith n p p 4054170fe5c8SBarry Smith ( ) ( ) ( ) 4055170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 4056170fe5c8SBarry Smith ( ) ( ) ( ) 4057170fe5c8SBarry Smith 4058170fe5c8SBarry Smith */ 4059170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4060170fe5c8SBarry Smith { 4061170fe5c8SBarry Smith PetscErrorCode ierr; 4062170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4063170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4064170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 40651de00fd4SBarry Smith PetscInt i,n,m,q,p; 4066170fe5c8SBarry Smith const PetscInt *ii,*idx; 4067170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4068170fe5c8SBarry Smith PetscScalar *c,*c_q; 4069170fe5c8SBarry Smith 4070170fe5c8SBarry Smith PetscFunctionBegin; 4071d0f46423SBarry Smith m = A->rmap->n; 4072d0f46423SBarry Smith n = A->cmap->n; 4073d0f46423SBarry Smith p = B->cmap->n; 4074170fe5c8SBarry Smith a = sub_a->v; 4075170fe5c8SBarry Smith b = sub_b->a; 4076170fe5c8SBarry Smith c = sub_c->v; 4077170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 4078170fe5c8SBarry Smith 4079170fe5c8SBarry Smith ii = sub_b->i; 4080170fe5c8SBarry Smith idx = sub_b->j; 4081170fe5c8SBarry Smith for (i=0; i<n; i++) { 4082170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4083170fe5c8SBarry Smith while (q-->0) { 4084170fe5c8SBarry Smith c_q = c + m*(*idx); 4085170fe5c8SBarry Smith a_q = a + m*i; 4086854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4087170fe5c8SBarry Smith idx++; 4088170fe5c8SBarry Smith b++; 4089170fe5c8SBarry Smith } 4090170fe5c8SBarry Smith } 4091170fe5c8SBarry Smith PetscFunctionReturn(0); 4092170fe5c8SBarry Smith } 4093170fe5c8SBarry Smith 4094170fe5c8SBarry Smith #undef __FUNCT__ 4095170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 4096170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 4097170fe5c8SBarry Smith { 4098170fe5c8SBarry Smith PetscErrorCode ierr; 4099d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 4100170fe5c8SBarry Smith Mat Cmat; 4101170fe5c8SBarry Smith 4102170fe5c8SBarry Smith PetscFunctionBegin; 4103e32f2f54SBarry 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); 4104ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 4105170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 4106a2f3521dSMark F. Adams ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr); 4107170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 41080298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 4109d73949e8SHong Zhang 4110d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 41112205254eSKarl Rupp 4112170fe5c8SBarry Smith *C = Cmat; 4113170fe5c8SBarry Smith PetscFunctionReturn(0); 4114170fe5c8SBarry Smith } 4115170fe5c8SBarry Smith 4116170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 4117170fe5c8SBarry Smith #undef __FUNCT__ 4118170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 4119170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 4120170fe5c8SBarry Smith { 4121170fe5c8SBarry Smith PetscErrorCode ierr; 4122170fe5c8SBarry Smith 4123170fe5c8SBarry Smith PetscFunctionBegin; 4124170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 41253ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 4126170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 41273ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 4128170fe5c8SBarry Smith } 41293ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 4130170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 41313ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 4132170fe5c8SBarry Smith PetscFunctionReturn(0); 4133170fe5c8SBarry Smith } 4134170fe5c8SBarry Smith 4135170fe5c8SBarry Smith 41360bad9183SKris Buschelman /*MC 4137fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 41380bad9183SKris Buschelman based on compressed sparse row format. 41390bad9183SKris Buschelman 41400bad9183SKris Buschelman Options Database Keys: 41410bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 41420bad9183SKris Buschelman 41430bad9183SKris Buschelman Level: beginner 41440bad9183SKris Buschelman 4145f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 41460bad9183SKris Buschelman M*/ 41470bad9183SKris Buschelman 4148ccd284c7SBarry Smith /*MC 4149ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4150ccd284c7SBarry Smith 4151ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4152ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 4153ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 4154ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4155ccd284c7SBarry Smith the above preallocation routines for simplicity. 4156ccd284c7SBarry Smith 4157ccd284c7SBarry Smith Options Database Keys: 4158ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4159ccd284c7SBarry Smith 4160ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 4161ccd284c7SBarry Smith enough exist. 4162ccd284c7SBarry Smith 4163ccd284c7SBarry Smith Level: beginner 4164ccd284c7SBarry Smith 4165ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4166ccd284c7SBarry Smith M*/ 4167ccd284c7SBarry Smith 4168ccd284c7SBarry Smith /*MC 4169ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4170ccd284c7SBarry Smith 4171ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4172ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4173ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4174ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4175ccd284c7SBarry Smith the above preallocation routines for simplicity. 4176ccd284c7SBarry Smith 4177ccd284c7SBarry Smith Options Database Keys: 4178ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4179ccd284c7SBarry Smith 4180ccd284c7SBarry Smith Level: beginner 4181ccd284c7SBarry Smith 4182ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4183ccd284c7SBarry Smith M*/ 4184ccd284c7SBarry Smith 4185b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 41868cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 4187b5e56a35SBarry Smith #endif 4188ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 41898cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*); 4190af1023dbSSatish Balay #endif 41918cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 41928cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 41938cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 41947087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*); 4195611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 41968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 4197611f576cSBarry Smith #endif 4198611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 41998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 4200611f576cSBarry Smith #endif 4201f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 42028cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 4203f3c0ef26SHong Zhang #endif 4204eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 42058cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 4206eb3b5408SSatish Balay #endif 4207586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 42088cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 4209586621ddSJed Brown #endif 4210719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 42118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 4212719d5645SBarry Smith #endif 4213b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 42148cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 42157087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 42167087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 4217b3866ffcSBarry Smith #endif 421817f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE) 42198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*); 422017f1a0eaSHong Zhang #endif 422117667f90SBarry Smith 4222c0c8ee5eSDmitry Karpeev 42238c778c55SBarry Smith #undef __FUNCT__ 42248c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray" 42258c778c55SBarry Smith /*@C 42268c778c55SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored 42278c778c55SBarry Smith 42288c778c55SBarry Smith Not Collective 42298c778c55SBarry Smith 42308c778c55SBarry Smith Input Parameter: 42318c778c55SBarry Smith . mat - a MATSEQDENSE matrix 42328c778c55SBarry Smith 42338c778c55SBarry Smith Output Parameter: 42348c778c55SBarry Smith . array - pointer to the data 42358c778c55SBarry Smith 42368c778c55SBarry Smith Level: intermediate 42378c778c55SBarry Smith 4238774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 42398c778c55SBarry Smith @*/ 42408c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 42418c778c55SBarry Smith { 42428c778c55SBarry Smith PetscErrorCode ierr; 42438c778c55SBarry Smith 42448c778c55SBarry Smith PetscFunctionBegin; 42458c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 42468c778c55SBarry Smith PetscFunctionReturn(0); 42478c778c55SBarry Smith } 42488c778c55SBarry Smith 42498c778c55SBarry Smith #undef __FUNCT__ 42508c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray" 42518c778c55SBarry Smith /*@C 42528c778c55SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray() 42538c778c55SBarry Smith 42548c778c55SBarry Smith Not Collective 42558c778c55SBarry Smith 42568c778c55SBarry Smith Input Parameters: 42578c778c55SBarry Smith . mat - a MATSEQDENSE matrix 42588c778c55SBarry Smith . array - pointer to the data 42598c778c55SBarry Smith 42608c778c55SBarry Smith Level: intermediate 42618c778c55SBarry Smith 4262774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 42638c778c55SBarry Smith @*/ 42648c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 42658c778c55SBarry Smith { 42668c778c55SBarry Smith PetscErrorCode ierr; 42678c778c55SBarry Smith 42688c778c55SBarry Smith PetscFunctionBegin; 42698c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 42708c778c55SBarry Smith PetscFunctionReturn(0); 42718c778c55SBarry Smith } 42728c778c55SBarry Smith 42734a2ae208SSatish Balay #undef __FUNCT__ 42744a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 42758cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4276273d9f13SBarry Smith { 4277273d9f13SBarry Smith Mat_SeqAIJ *b; 4278dfbe8321SBarry Smith PetscErrorCode ierr; 427938baddfdSBarry Smith PetscMPIInt size; 4280273d9f13SBarry Smith 4281273d9f13SBarry Smith PetscFunctionBegin; 4282ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 4283e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4284273d9f13SBarry Smith 428538f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr); 42862205254eSKarl Rupp 4287b0a32e0cSBarry Smith B->data = (void*)b; 42882205254eSKarl Rupp 4289549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 42902205254eSKarl Rupp 4291416022c9SBarry Smith b->row = 0; 4292416022c9SBarry Smith b->col = 0; 429382bf6240SBarry Smith b->icol = 0; 4294b810aeb4SBarry Smith b->reallocs = 0; 429536db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4296f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4297416022c9SBarry Smith b->nonew = 0; 4298416022c9SBarry Smith b->diag = 0; 4299416022c9SBarry Smith b->solve_work = 0; 43002a1b7f2aSHong Zhang B->spptr = 0; 4301be6bf707SBarry Smith b->saved_values = 0; 4302d7f994e1SBarry Smith b->idiag = 0; 430371f1c65dSBarry Smith b->mdiag = 0; 430471f1c65dSBarry Smith b->ssor_work = 0; 430571f1c65dSBarry Smith b->omega = 1.0; 430671f1c65dSBarry Smith b->fshift = 0.0; 430771f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4308bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4309a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 4310a30b2313SHong Zhang b->xtoy = 0; 4311a30b2313SHong Zhang b->XtoY = 0; 431288e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 431317ab2063SBarry Smith 431435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4315bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4316bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 43178c778c55SBarry Smith 4318b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4319bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 4320bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4321bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4322b3866ffcSBarry Smith #endif 4323b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 4324bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 4325b5e56a35SBarry Smith #endif 4326ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 4327bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 4328719d5645SBarry Smith #endif 4329611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 4330bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 4331611f576cSBarry Smith #endif 4332f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 4333bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 4334f3c0ef26SHong Zhang #endif 4335611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 4336bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr); 4337611f576cSBarry Smith #endif 4338eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 4339bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 4340eb3b5408SSatish Balay #endif 4341586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 4342bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 4343586621ddSJed Brown #endif 4344719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 4345bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 4346719d5645SBarry Smith #endif 434717f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE) 4348bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr); 434917f1a0eaSHong Zhang #endif 435017f1a0eaSHong Zhang 4351bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 4352bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 4353bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 4354bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4355bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4356bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4357bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4358bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4359bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 4360bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4361bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4362bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4363bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4364bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4365bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 4366bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 4367bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 4368bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 43694108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 437017667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 43713a40ed3dSBarry Smith PetscFunctionReturn(0); 437217ab2063SBarry Smith } 437317ab2063SBarry Smith 43744a2ae208SSatish Balay #undef __FUNCT__ 4375b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 4376b24902e0SBarry Smith /* 4377b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4378b24902e0SBarry Smith */ 4379ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 438017ab2063SBarry Smith { 4381416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 43826849ba73SBarry Smith PetscErrorCode ierr; 4383d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 438417ab2063SBarry Smith 43853a40ed3dSBarry Smith PetscFunctionBegin; 4386273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 4387273d9f13SBarry Smith 4388d5f3da31SBarry Smith C->factortype = A->factortype; 4389416022c9SBarry Smith c->row = 0; 4390416022c9SBarry Smith c->col = 0; 439182bf6240SBarry Smith c->icol = 0; 43926ad4291fSHong Zhang c->reallocs = 0; 439317ab2063SBarry Smith 43946ad4291fSHong Zhang C->assembled = PETSC_TRUE; 439517ab2063SBarry Smith 4396aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4397aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4398eec197d1SBarry Smith 439933b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 44003bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 440117ab2063SBarry Smith for (i=0; i<m; i++) { 4402416022c9SBarry Smith c->imax[i] = a->imax[i]; 4403416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 440417ab2063SBarry Smith } 440517ab2063SBarry Smith 440617ab2063SBarry Smith /* allocate the matrix space */ 4407f77e22a1SHong Zhang if (mallocmatspace) { 4408a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 44093bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 44102205254eSKarl Rupp 4411f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 44122205254eSKarl Rupp 441397f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 441417ab2063SBarry Smith if (m > 0) { 441597f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 4416be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4417bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 4418be6bf707SBarry Smith } else { 4419bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 442017ab2063SBarry Smith } 442108480c60SBarry Smith } 4422f77e22a1SHong Zhang } 442317ab2063SBarry Smith 44246ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4425416022c9SBarry Smith c->roworiented = a->roworiented; 4426416022c9SBarry Smith c->nonew = a->nonew; 4427416022c9SBarry Smith if (a->diag) { 442897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 44293bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 443017ab2063SBarry Smith for (i=0; i<m; i++) { 4431416022c9SBarry Smith c->diag[i] = a->diag[i]; 443217ab2063SBarry Smith } 44333a40ed3dSBarry Smith } else c->diag = 0; 44342205254eSKarl Rupp 44356ad4291fSHong Zhang c->solve_work = 0; 44366ad4291fSHong Zhang c->saved_values = 0; 44376ad4291fSHong Zhang c->idiag = 0; 443871f1c65dSBarry Smith c->ssor_work = 0; 4439a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4440e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4441e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 44426ad4291fSHong Zhang c->xtoy = 0; 44436ad4291fSHong Zhang c->XtoY = 0; 44446ad4291fSHong Zhang 4445893ad86cSHong Zhang c->rmax = a->rmax; 4446416022c9SBarry Smith c->nz = a->nz; 44478ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4448273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4449754ec7b1SSatish Balay 44506ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 44516ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4452cd6b891eSBarry Smith c->compressedrow.check = a->compressedrow.check; 4453cd6b891eSBarry Smith if (a->compressedrow.use) { 44546ad4291fSHong Zhang i = a->compressedrow.nrows; 44550e83c824SBarry Smith ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr); 44566ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 44576ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 445827ea64f8SHong Zhang } else { 445927ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 44600298fd71SBarry Smith c->compressedrow.i = NULL; 44610298fd71SBarry Smith c->compressedrow.rindex = NULL; 44626ad4291fSHong Zhang } 446388e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 44644846f1f5SKris Buschelman 44652205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4466140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 44673a40ed3dSBarry Smith PetscFunctionReturn(0); 446817ab2063SBarry Smith } 446917ab2063SBarry Smith 44704a2ae208SSatish Balay #undef __FUNCT__ 4471b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 4472b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4473b24902e0SBarry Smith { 4474b24902e0SBarry Smith PetscErrorCode ierr; 4475b24902e0SBarry Smith 4476b24902e0SBarry Smith PetscFunctionBegin; 4477ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 44784b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4479a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 4480a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4481f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4482b24902e0SBarry Smith PetscFunctionReturn(0); 4483b24902e0SBarry Smith } 4484b24902e0SBarry Smith 4485b24902e0SBarry Smith #undef __FUNCT__ 44864a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 4487112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4488fbdbba38SShri Abhyankar { 4489fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4490fbdbba38SShri Abhyankar PetscErrorCode ierr; 4491fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4492fbdbba38SShri Abhyankar int fd; 4493fbdbba38SShri Abhyankar PetscMPIInt size; 4494fbdbba38SShri Abhyankar MPI_Comm comm; 4495bbead8a2SBarry Smith PetscInt bs = 1; 4496fbdbba38SShri Abhyankar 4497fbdbba38SShri Abhyankar PetscFunctionBegin; 4498fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4499fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4500fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4501bbead8a2SBarry Smith 45020298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 45030298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4504bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 45051814747fSJed Brown if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);} 4506bbead8a2SBarry Smith 4507fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4508fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4509fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4510fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4511fbdbba38SShri Abhyankar 4512bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4513fbdbba38SShri Abhyankar 4514fbdbba38SShri Abhyankar /* read in row lengths */ 4515fbdbba38SShri Abhyankar ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 4516fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4517fbdbba38SShri Abhyankar 4518fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4519fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 4520fbdbba38SShri 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); 4521fbdbba38SShri Abhyankar 4522fbdbba38SShri Abhyankar /* set global size if not set already*/ 4523f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4524fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4525aabbc4fbSShri Abhyankar } else { 4526fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 4527fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 45284c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 45294c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 45304c5b953cSHong Zhang } 4531f501eaabSShri 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); 4532aabbc4fbSShri Abhyankar } 4533fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4534fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4535fbdbba38SShri Abhyankar 4536fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4537fbdbba38SShri Abhyankar 4538fbdbba38SShri Abhyankar /* read in nonzero values */ 4539fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4540fbdbba38SShri Abhyankar 4541fbdbba38SShri Abhyankar /* set matrix "i" values */ 4542fbdbba38SShri Abhyankar a->i[0] = 0; 4543fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4544fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4545fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4546fbdbba38SShri Abhyankar } 4547fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4548fbdbba38SShri Abhyankar 4549fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4550fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4551fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4552fbdbba38SShri Abhyankar } 4553fbdbba38SShri Abhyankar 4554fbdbba38SShri Abhyankar #undef __FUNCT__ 4555b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 4556ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 45577264ac53SSatish Balay { 45587264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4559dfbe8321SBarry Smith PetscErrorCode ierr; 4560eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4561eeffb40dSHong Zhang PetscInt k; 4562eeffb40dSHong Zhang #endif 45637264ac53SSatish Balay 45643a40ed3dSBarry Smith PetscFunctionBegin; 4565bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4566d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4567ca44d042SBarry Smith *flg = PETSC_FALSE; 4568ca44d042SBarry Smith PetscFunctionReturn(0); 4569bcd2baecSBarry Smith } 45707264ac53SSatish Balay 45717264ac53SSatish Balay /* if the a->i are the same */ 4572d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4573abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 45747264ac53SSatish Balay 45757264ac53SSatish Balay /* if a->j are the same */ 457697f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4577abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4578bcd2baecSBarry Smith 4579bcd2baecSBarry Smith /* if a->a are the same */ 4580eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4581eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4582eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4583eeffb40dSHong Zhang *flg = PETSC_FALSE; 45843a40ed3dSBarry Smith PetscFunctionReturn(0); 4585eeffb40dSHong Zhang } 4586eeffb40dSHong Zhang } 4587eeffb40dSHong Zhang #else 4588eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4589eeffb40dSHong Zhang #endif 4590eeffb40dSHong Zhang PetscFunctionReturn(0); 45917264ac53SSatish Balay } 459236db0b34SBarry Smith 45934a2ae208SSatish Balay #undef __FUNCT__ 45944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 459505869f15SSatish Balay /*@ 459636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 459736db0b34SBarry Smith provided by the user. 459836db0b34SBarry Smith 4599c75a6043SHong Zhang Collective on MPI_Comm 460036db0b34SBarry Smith 460136db0b34SBarry Smith Input Parameters: 460236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 460336db0b34SBarry Smith . m - number of rows 460436db0b34SBarry Smith . n - number of columns 460536db0b34SBarry Smith . i - row indices 460636db0b34SBarry Smith . j - column indices 460736db0b34SBarry Smith - a - matrix values 460836db0b34SBarry Smith 460936db0b34SBarry Smith Output Parameter: 461036db0b34SBarry Smith . mat - the matrix 461136db0b34SBarry Smith 461236db0b34SBarry Smith Level: intermediate 461336db0b34SBarry Smith 461436db0b34SBarry Smith Notes: 46150551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4616292fb18eSBarry Smith once the matrix is destroyed and not before 461736db0b34SBarry Smith 461836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 461936db0b34SBarry Smith 4620bfeeae90SHong Zhang The i and j indices are 0 based 462136db0b34SBarry Smith 4622a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4623a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4624a4552177SSatish Balay as shown: 4625a4552177SSatish Balay 4626a4552177SSatish Balay 1 0 0 4627a4552177SSatish Balay 2 0 3 4628a4552177SSatish Balay 4 5 6 4629a4552177SSatish Balay 4630a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 46319985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4632a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4633a4552177SSatish Balay 46349985e31cSBarry Smith 463569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 463636db0b34SBarry Smith 463736db0b34SBarry Smith @*/ 46387087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat) 463936db0b34SBarry Smith { 4640dfbe8321SBarry Smith PetscErrorCode ierr; 4641cbcfb4deSHong Zhang PetscInt ii; 464236db0b34SBarry Smith Mat_SeqAIJ *aij; 4643cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4644cbcfb4deSHong Zhang PetscInt jj; 4645cbcfb4deSHong Zhang #endif 464636db0b34SBarry Smith 464736db0b34SBarry Smith PetscFunctionBegin; 4648f23aa3ddSBarry Smith if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4649f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4650f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4651a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4652ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4653ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4654ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4655ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 4656ab93d7beSBarry Smith 465736db0b34SBarry Smith aij->i = i; 465836db0b34SBarry Smith aij->j = j; 465936db0b34SBarry Smith aij->a = a; 466036db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 466136db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4662e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4663e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 466436db0b34SBarry Smith 466536db0b34SBarry Smith for (ii=0; ii<m; ii++) { 466636db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 46672515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 4668e32f2f54SBarry 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]); 46699985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4670e32f2f54SBarry 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); 4671e32f2f54SBarry 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); 46729985e31cSBarry Smith } 467336db0b34SBarry Smith #endif 467436db0b34SBarry Smith } 46752515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 467636db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 4677e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 4678e32f2f54SBarry 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]); 467936db0b34SBarry Smith } 468036db0b34SBarry Smith #endif 468136db0b34SBarry Smith 4682b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4683b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 468436db0b34SBarry Smith PetscFunctionReturn(0); 468536db0b34SBarry Smith } 46868a0b0e6bSVictor Minden #undef __FUNCT__ 46878a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple" 468880ef6e79SMatthew G Knepley /*@C 4689d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 46908a0b0e6bSVictor Minden provided by the user. 46918a0b0e6bSVictor Minden 46928a0b0e6bSVictor Minden Collective on MPI_Comm 46938a0b0e6bSVictor Minden 46948a0b0e6bSVictor Minden Input Parameters: 46958a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 46968a0b0e6bSVictor Minden . m - number of rows 46978a0b0e6bSVictor Minden . n - number of columns 46988a0b0e6bSVictor Minden . i - row indices 46998a0b0e6bSVictor Minden . j - column indices 47001230e6d1SVictor Minden . a - matrix values 47011230e6d1SVictor Minden . nz - number of nonzeros 47021230e6d1SVictor Minden - idx - 0 or 1 based 47038a0b0e6bSVictor Minden 47048a0b0e6bSVictor Minden Output Parameter: 47058a0b0e6bSVictor Minden . mat - the matrix 47068a0b0e6bSVictor Minden 47078a0b0e6bSVictor Minden Level: intermediate 47088a0b0e6bSVictor Minden 47098a0b0e6bSVictor Minden Notes: 47108a0b0e6bSVictor Minden The i and j indices are 0 based 47118a0b0e6bSVictor Minden 47128a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 47138a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 47148a0b0e6bSVictor Minden as shown: 47158a0b0e6bSVictor Minden 47168a0b0e6bSVictor Minden 1 0 0 47178a0b0e6bSVictor Minden 2 0 3 47188a0b0e6bSVictor Minden 4 5 6 47198a0b0e6bSVictor Minden 47208a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 47218a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 47228a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 47238a0b0e6bSVictor Minden 47248a0b0e6bSVictor Minden 472569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 47268a0b0e6bSVictor Minden 47278a0b0e6bSVictor Minden @*/ 47281230e6d1SVictor Minden PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx) 47298a0b0e6bSVictor Minden { 47308a0b0e6bSVictor Minden PetscErrorCode ierr; 4731d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 47328a0b0e6bSVictor Minden 47338a0b0e6bSVictor Minden 47348a0b0e6bSVictor Minden PetscFunctionBegin; 4735d021a1c5SVictor Minden ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 47361230e6d1SVictor Minden ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr); 47371230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 47381230e6d1SVictor Minden nnz[i[ii]] += 1; 47391230e6d1SVictor Minden } 47408a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 47418a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4742a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 47438a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 47441230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 47451230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 47461230e6d1SVictor Minden if (idx) { 47471230e6d1SVictor Minden row = i[ii] - 1; 47481230e6d1SVictor Minden col = j[ii] - 1; 47491230e6d1SVictor Minden } else { 47501230e6d1SVictor Minden row = i[ii]; 47511230e6d1SVictor Minden col = j[ii]; 47528a0b0e6bSVictor Minden } 47531230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 47548a0b0e6bSVictor Minden } 47558a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47568a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4757d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 47588a0b0e6bSVictor Minden PetscFunctionReturn(0); 47598a0b0e6bSVictor Minden } 476036db0b34SBarry Smith 4761cc8ba8e1SBarry Smith #undef __FUNCT__ 4762ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4763dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4764cc8ba8e1SBarry Smith { 4765dfbe8321SBarry Smith PetscErrorCode ierr; 4766cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 476736db0b34SBarry Smith 4768cc8ba8e1SBarry Smith PetscFunctionBegin; 47698ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4770cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4771cc8ba8e1SBarry Smith a->coloring = coloring; 477212c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 477397f1f81fSBarry Smith PetscInt i,*larray; 477412c595b3SBarry Smith ISColoring ocoloring; 477508b6dcc0SBarry Smith ISColoringValue *colors; 477612c595b3SBarry Smith 477712c595b3SBarry Smith /* set coloring for diagonal portion */ 47780e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr); 47792205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) larray[i] = i; 47800298fd71SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr); 47810e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 47822205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]]; 478312c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4784d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 478512c595b3SBarry Smith a->coloring = ocoloring; 478612c595b3SBarry Smith } 4787cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4788cc8ba8e1SBarry Smith } 4789cc8ba8e1SBarry Smith 4790ee4f033dSBarry Smith #undef __FUNCT__ 4791ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 479297f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4793ee4f033dSBarry Smith { 4794ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4795d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 479654f21887SBarry Smith MatScalar *v = a->a; 479754f21887SBarry Smith PetscScalar *values = (PetscScalar*)advalues; 479808b6dcc0SBarry Smith ISColoringValue *color; 4799ee4f033dSBarry Smith 4800ee4f033dSBarry Smith PetscFunctionBegin; 4801e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4802ee4f033dSBarry Smith color = a->coloring->colors; 4803ee4f033dSBarry Smith /* loop over rows */ 4804ee4f033dSBarry Smith for (i=0; i<m; i++) { 4805ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4806ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 48072205254eSKarl Rupp for (j=0; j<nz; j++) *v++ = values[color[*jj++]]; 4808ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4809cc8ba8e1SBarry Smith } 4810cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4811cc8ba8e1SBarry Smith } 481236db0b34SBarry Smith 4813acf2f550SJed Brown #undef __FUNCT__ 4814acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal" 4815acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4816acf2f550SJed Brown { 4817acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4818acf2f550SJed Brown PetscErrorCode ierr; 4819acf2f550SJed Brown 4820acf2f550SJed Brown PetscFunctionBegin; 4821acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4822acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 48232205254eSKarl Rupp 4824acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4825acf2f550SJed Brown PetscFunctionReturn(0); 4826acf2f550SJed Brown } 4827acf2f550SJed Brown 482881824310SBarry Smith /* 482981824310SBarry Smith Special version for direct calls from Fortran 483081824310SBarry Smith */ 4831b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h> 483281824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 483381824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 483481824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 483581824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 483681824310SBarry Smith #endif 483781824310SBarry Smith 483881824310SBarry Smith /* Change these macros so can be used in void function */ 483981824310SBarry Smith #undef CHKERRQ 4840ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 484181824310SBarry Smith #undef SETERRQ2 4842e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 48434994cf47SJed Brown #undef SETERRQ3 48444994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 484581824310SBarry Smith 484681824310SBarry Smith #undef __FUNCT__ 484781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 48488cc058d9SJed 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) 484981824310SBarry Smith { 485081824310SBarry Smith Mat A = *AA; 485181824310SBarry Smith PetscInt m = *mm, n = *nn; 485281824310SBarry Smith InsertMode is = *isis; 485381824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 485481824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 485581824310SBarry Smith PetscInt *imax,*ai,*ailen; 485681824310SBarry Smith PetscErrorCode ierr; 485781824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 485854f21887SBarry Smith MatScalar *ap,value,*aa; 4859ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4860ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 486181824310SBarry Smith 486281824310SBarry Smith PetscFunctionBegin; 48634994cf47SJed Brown MatCheckPreallocated(A,1); 486481824310SBarry Smith imax = a->imax; 486581824310SBarry Smith ai = a->i; 486681824310SBarry Smith ailen = a->ilen; 486781824310SBarry Smith aj = a->j; 486881824310SBarry Smith aa = a->a; 486981824310SBarry Smith 487081824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 487181824310SBarry Smith row = im[k]; 487281824310SBarry Smith if (row < 0) continue; 487381824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4874ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 487581824310SBarry Smith #endif 487681824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 487781824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 487881824310SBarry Smith low = 0; 487981824310SBarry Smith high = nrow; 488081824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 488181824310SBarry Smith if (in[l] < 0) continue; 488281824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4883ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 488481824310SBarry Smith #endif 488581824310SBarry Smith col = in[l]; 48862205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 48872205254eSKarl Rupp else value = v[k + l*m]; 48882205254eSKarl Rupp 488981824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 489081824310SBarry Smith 48912205254eSKarl Rupp if (col <= lastcol) low = 0; 48922205254eSKarl Rupp else high = nrow; 489381824310SBarry Smith lastcol = col; 489481824310SBarry Smith while (high-low > 5) { 489581824310SBarry Smith t = (low+high)/2; 489681824310SBarry Smith if (rp[t] > col) high = t; 489781824310SBarry Smith else low = t; 489881824310SBarry Smith } 489981824310SBarry Smith for (i=low; i<high; i++) { 490081824310SBarry Smith if (rp[i] > col) break; 490181824310SBarry Smith if (rp[i] == col) { 490281824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 490381824310SBarry Smith else ap[i] = value; 490481824310SBarry Smith goto noinsert; 490581824310SBarry Smith } 490681824310SBarry Smith } 490781824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 490881824310SBarry Smith if (nonew == 1) goto noinsert; 4909ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4910fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 491181824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 491281824310SBarry Smith /* shift up all the later entries in this row */ 491381824310SBarry Smith for (ii=N; ii>=i; ii--) { 491481824310SBarry Smith rp[ii+1] = rp[ii]; 491581824310SBarry Smith ap[ii+1] = ap[ii]; 491681824310SBarry Smith } 491781824310SBarry Smith rp[i] = col; 491881824310SBarry Smith ap[i] = value; 491981824310SBarry Smith noinsert:; 492081824310SBarry Smith low = i + 1; 492181824310SBarry Smith } 492281824310SBarry Smith ailen[row] = nrow; 492381824310SBarry Smith } 492481824310SBarry Smith A->same_nonzero = PETSC_FALSE; 492581824310SBarry Smith PetscFunctionReturnVoid(); 492681824310SBarry Smith } 49279f7953f8SBarry Smith 492862298a1eSBarry Smith 4929