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__ 483a062f41SBarry Smith #define __FUNCT__ "MatFindOffBlockDiagonalEntries_SeqAIJ" 493a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 503a062f41SBarry Smith { 513a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 523a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 533a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 543a062f41SBarry Smith PetscInt *rows; 553a062f41SBarry Smith PetscErrorCode ierr; 563a062f41SBarry Smith 573a062f41SBarry Smith PetscFunctionBegin; 583a062f41SBarry Smith for (i=0; i<m; i++) { 593a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 603a062f41SBarry Smith cnt++; 613a062f41SBarry Smith } 623a062f41SBarry Smith } 633a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 643a062f41SBarry Smith cnt = 0; 653a062f41SBarry Smith for (i=0; i<m; i++) { 663a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 673a062f41SBarry Smith rows[cnt] = i; 683a062f41SBarry Smith cnt++; 693a062f41SBarry Smith } 703a062f41SBarry Smith } 713a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 723a062f41SBarry Smith PetscFunctionReturn(0); 733a062f41SBarry Smith } 743a062f41SBarry Smith 753a062f41SBarry Smith #undef __FUNCT__ 76f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private" 77f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 786ce1633cSBarry Smith { 796ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 806ce1633cSBarry Smith const MatScalar *aa = a->a; 816ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 826ce1633cSBarry Smith const PetscInt *jj = a->j,*diag; 836ce1633cSBarry Smith PetscInt *rows; 846ce1633cSBarry Smith PetscErrorCode ierr; 856ce1633cSBarry Smith 866ce1633cSBarry Smith PetscFunctionBegin; 876ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 886ce1633cSBarry Smith diag = a->diag; 896ce1633cSBarry Smith for (i=0; i<m; i++) { 906ce1633cSBarry Smith if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 916ce1633cSBarry Smith cnt++; 926ce1633cSBarry Smith } 936ce1633cSBarry Smith } 94785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 956ce1633cSBarry Smith cnt = 0; 966ce1633cSBarry Smith for (i=0; i<m; i++) { 976ce1633cSBarry Smith if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 986ce1633cSBarry Smith rows[cnt++] = i; 996ce1633cSBarry Smith } 1006ce1633cSBarry Smith } 101f1f41ecbSJed Brown *nrows = cnt; 102f1f41ecbSJed Brown *zrows = rows; 103f1f41ecbSJed Brown PetscFunctionReturn(0); 104f1f41ecbSJed Brown } 105f1f41ecbSJed Brown 106f1f41ecbSJed Brown #undef __FUNCT__ 107f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ" 108f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 109f1f41ecbSJed Brown { 110f1f41ecbSJed Brown PetscInt nrows,*rows; 111f1f41ecbSJed Brown PetscErrorCode ierr; 112f1f41ecbSJed Brown 113f1f41ecbSJed Brown PetscFunctionBegin; 1140298fd71SBarry Smith *zrows = NULL; 115f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 116ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1176ce1633cSBarry Smith PetscFunctionReturn(0); 1186ce1633cSBarry Smith } 1196ce1633cSBarry Smith 1206ce1633cSBarry Smith #undef __FUNCT__ 121b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ" 122b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 123b3a44c85SBarry Smith { 124b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 125b3a44c85SBarry Smith const MatScalar *aa; 126b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 127b3a44c85SBarry Smith const PetscInt *ii; 128b3a44c85SBarry Smith PetscInt n,i,j,*rows; 129b3a44c85SBarry Smith PetscErrorCode ierr; 130b3a44c85SBarry Smith 131b3a44c85SBarry Smith PetscFunctionBegin; 132b3a44c85SBarry Smith *keptrows = 0; 133b3a44c85SBarry Smith ii = a->i; 134b3a44c85SBarry Smith for (i=0; i<m; i++) { 135b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 136b3a44c85SBarry Smith if (!n) { 137b3a44c85SBarry Smith cnt++; 138b3a44c85SBarry Smith goto ok1; 139b3a44c85SBarry Smith } 140b3a44c85SBarry Smith aa = a->a + ii[i]; 141b3a44c85SBarry Smith for (j=0; j<n; j++) { 142b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 143b3a44c85SBarry Smith } 144b3a44c85SBarry Smith cnt++; 145b3a44c85SBarry Smith ok1:; 146b3a44c85SBarry Smith } 147b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 148785e854fSJed Brown ierr = PetscMalloc1((A->rmap->n-cnt),&rows);CHKERRQ(ierr); 149b3a44c85SBarry Smith cnt = 0; 150b3a44c85SBarry Smith for (i=0; i<m; i++) { 151b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 152b3a44c85SBarry Smith if (!n) continue; 153b3a44c85SBarry Smith aa = a->a + ii[i]; 154b3a44c85SBarry Smith for (j=0; j<n; j++) { 155b3a44c85SBarry Smith if (aa[j] != 0.0) { 156b3a44c85SBarry Smith rows[cnt++] = i; 157b3a44c85SBarry Smith break; 158b3a44c85SBarry Smith } 159b3a44c85SBarry Smith } 160b3a44c85SBarry Smith } 161b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 162b3a44c85SBarry Smith PetscFunctionReturn(0); 163b3a44c85SBarry Smith } 164b3a44c85SBarry Smith 165b3a44c85SBarry Smith #undef __FUNCT__ 16679299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 1677087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 16879299369SBarry Smith { 16979299369SBarry Smith PetscErrorCode ierr; 17079299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 171d0f46423SBarry Smith PetscInt i,*diag, m = Y->rmap->n; 17254f21887SBarry Smith MatScalar *aa = aij->a; 17354f21887SBarry Smith PetscScalar *v; 174ace3abfcSBarry Smith PetscBool missing; 17579299369SBarry Smith 17679299369SBarry Smith PetscFunctionBegin; 17709f38230SBarry Smith if (Y->assembled) { 1780298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 17909f38230SBarry Smith if (!missing) { 18079299369SBarry Smith diag = aij->diag; 18179299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 18279299369SBarry Smith if (is == INSERT_VALUES) { 18379299369SBarry Smith for (i=0; i<m; i++) { 18479299369SBarry Smith aa[diag[i]] = v[i]; 18579299369SBarry Smith } 18679299369SBarry Smith } else { 18779299369SBarry Smith for (i=0; i<m; i++) { 18879299369SBarry Smith aa[diag[i]] += v[i]; 18979299369SBarry Smith } 19079299369SBarry Smith } 19179299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 19279299369SBarry Smith PetscFunctionReturn(0); 19379299369SBarry Smith } 194acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 19509f38230SBarry Smith } 19609f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 19709f38230SBarry Smith PetscFunctionReturn(0); 19809f38230SBarry Smith } 19979299369SBarry Smith 20079299369SBarry Smith #undef __FUNCT__ 2014a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 2021a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 20317ab2063SBarry Smith { 204416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 205dfbe8321SBarry Smith PetscErrorCode ierr; 20697f1f81fSBarry Smith PetscInt i,ishift; 20717ab2063SBarry Smith 2083a40ed3dSBarry Smith PetscFunctionBegin; 209d0f46423SBarry Smith *m = A->rmap->n; 2103a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 211bfeeae90SHong Zhang ishift = 0; 21253e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2131a83f524SJed Brown ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 214bfeeae90SHong Zhang } else if (oshift == 1) { 2151a83f524SJed Brown PetscInt *tia; 216d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2173b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 218785e854fSJed Brown ierr = PetscMalloc1((A->rmap->n+1),&tia);CHKERRQ(ierr); 2191a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2201a83f524SJed Brown *ia = tia; 221ecc77c7aSBarry Smith if (ja) { 2221a83f524SJed Brown PetscInt *tja; 223785e854fSJed Brown ierr = PetscMalloc1((nz+1),&tja);CHKERRQ(ierr); 2241a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2251a83f524SJed Brown *ja = tja; 226ecc77c7aSBarry Smith } 2276945ee14SBarry Smith } else { 228ecc77c7aSBarry Smith *ia = a->i; 229ecc77c7aSBarry Smith if (ja) *ja = a->j; 230a2ce50c7SBarry Smith } 2313a40ed3dSBarry Smith PetscFunctionReturn(0); 232a2744918SBarry Smith } 233a2744918SBarry Smith 2344a2ae208SSatish Balay #undef __FUNCT__ 2354a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 2361a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2376945ee14SBarry Smith { 238dfbe8321SBarry Smith PetscErrorCode ierr; 2396945ee14SBarry Smith 2403a40ed3dSBarry Smith PetscFunctionBegin; 2413a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 242bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 243606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 244ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 245bcd2baecSBarry Smith } 2463a40ed3dSBarry Smith PetscFunctionReturn(0); 24717ab2063SBarry Smith } 24817ab2063SBarry Smith 2494a2ae208SSatish Balay #undef __FUNCT__ 2504a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 2511a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2523b2fbd54SBarry Smith { 2533b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 254dfbe8321SBarry Smith PetscErrorCode ierr; 255d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 25697f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2573b2fbd54SBarry Smith 2583a40ed3dSBarry Smith PetscFunctionBegin; 259899cda47SBarry Smith *nn = n; 2603a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2613b2fbd54SBarry Smith if (symmetric) { 2621a83f524SJed Brown ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2633b2fbd54SBarry Smith } else { 2641795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 265785e854fSJed Brown ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr); 266785e854fSJed Brown ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr); 2673b2fbd54SBarry Smith jj = a->j; 2683b2fbd54SBarry Smith for (i=0; i<nz; i++) { 269bfeeae90SHong Zhang collengths[jj[i]]++; 2703b2fbd54SBarry Smith } 2713b2fbd54SBarry Smith cia[0] = oshift; 2723b2fbd54SBarry Smith for (i=0; i<n; i++) { 2733b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2743b2fbd54SBarry Smith } 27597f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2763b2fbd54SBarry Smith jj = a->j; 277a93ec695SBarry Smith for (row=0; row<m; row++) { 278a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 279a93ec695SBarry Smith for (i=0; i<mr; i++) { 280bfeeae90SHong Zhang col = *jj++; 2812205254eSKarl Rupp 2823b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2833b2fbd54SBarry Smith } 2843b2fbd54SBarry Smith } 285606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2863b2fbd54SBarry Smith *ia = cia; *ja = cja; 2873b2fbd54SBarry Smith } 2883a40ed3dSBarry Smith PetscFunctionReturn(0); 2893b2fbd54SBarry Smith } 2903b2fbd54SBarry Smith 2914a2ae208SSatish Balay #undef __FUNCT__ 2924a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 2931a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2943b2fbd54SBarry Smith { 295dfbe8321SBarry Smith PetscErrorCode ierr; 296606d414cSSatish Balay 2973a40ed3dSBarry Smith PetscFunctionBegin; 2983a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2993b2fbd54SBarry Smith 300606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 301606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3023a40ed3dSBarry Smith PetscFunctionReturn(0); 3033b2fbd54SBarry Smith } 3043b2fbd54SBarry Smith 3057cee066cSHong Zhang /* 3067cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3077cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 308040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3097cee066cSHong Zhang */ 3107cee066cSHong Zhang #undef __FUNCT__ 3117cee066cSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color" 3127cee066cSHong 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) 3137cee066cSHong Zhang { 3147cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3157cee066cSHong Zhang PetscErrorCode ierr; 3167cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 3177cee066cSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 3187cee066cSHong Zhang PetscInt *cspidx; 3197cee066cSHong Zhang 3207cee066cSHong Zhang PetscFunctionBegin; 3217cee066cSHong Zhang *nn = n; 3227cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 323625f6d37SHong Zhang 3241795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 325785e854fSJed Brown ierr = PetscMalloc1((n+1),&cia);CHKERRQ(ierr); 326785e854fSJed Brown ierr = PetscMalloc1((nz+1),&cja);CHKERRQ(ierr); 327785e854fSJed Brown ierr = PetscMalloc1((nz+1),&cspidx);CHKERRQ(ierr); 3287cee066cSHong Zhang jj = a->j; 3297cee066cSHong Zhang for (i=0; i<nz; i++) { 3307cee066cSHong Zhang collengths[jj[i]]++; 3317cee066cSHong Zhang } 3327cee066cSHong Zhang cia[0] = oshift; 3337cee066cSHong Zhang for (i=0; i<n; i++) { 3347cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3357cee066cSHong Zhang } 3367cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 3377cee066cSHong Zhang jj = a->j; 3387cee066cSHong Zhang for (row=0; row<m; row++) { 3397cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3407cee066cSHong Zhang for (i=0; i<mr; i++) { 3417cee066cSHong Zhang col = *jj++; 3427cee066cSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 3437cee066cSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 3447cee066cSHong Zhang } 3457cee066cSHong Zhang } 3467cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 3477cee066cSHong Zhang *ia = cia; *ja = cja; 3487cee066cSHong Zhang *spidx = cspidx; 3497cee066cSHong Zhang PetscFunctionReturn(0); 3507cee066cSHong Zhang } 3517cee066cSHong Zhang 3527cee066cSHong Zhang #undef __FUNCT__ 3537cee066cSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color" 3547cee066cSHong 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) 3557cee066cSHong Zhang { 3567cee066cSHong Zhang PetscErrorCode ierr; 3577cee066cSHong Zhang 3587cee066cSHong Zhang PetscFunctionBegin; 3595243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3607cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3617cee066cSHong Zhang PetscFunctionReturn(0); 3627cee066cSHong Zhang } 3637cee066cSHong Zhang 36487d4246cSBarry Smith #undef __FUNCT__ 36587d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 36687d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 36787d4246cSBarry Smith { 36887d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 36987d4246cSBarry Smith PetscInt *ai = a->i; 37087d4246cSBarry Smith PetscErrorCode ierr; 37187d4246cSBarry Smith 37287d4246cSBarry Smith PetscFunctionBegin; 37387d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 37487d4246cSBarry Smith PetscFunctionReturn(0); 37587d4246cSBarry Smith } 37687d4246cSBarry Smith 3774a2ae208SSatish Balay #undef __FUNCT__ 378bd04181cSBarry Smith #define __FUNCT__ "MatSeqAIJSetValuesLocalFast" 379bd04181cSBarry Smith /* 380bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 381bd04181cSBarry Smith 382bd04181cSBarry Smith - a single row of values is set with each call 383bd04181cSBarry Smith - the local to global mapping is the identity 384bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 385bd04181cSBarry Smith - the values are always added to the matrix, not set 386bd04181cSBarry Smith - the columns indices on each call are sorted 387bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 388bd04181cSBarry Smith 389bd04181cSBarry Smith */ 390*189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFastold(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 391bd04181cSBarry Smith { 392bd04181cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 393bd04181cSBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 394bd04181cSBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen; 395bd04181cSBarry Smith const PetscInt *aj = a->j; 396bd04181cSBarry Smith MatScalar *ap,*aa = a->a; 397bd04181cSBarry Smith PetscBool found; 398bd04181cSBarry Smith 399bd04181cSBarry Smith PetscFunctionBegin; 400bd04181cSBarry Smith if (m >1) printf("trouble1\n"); 401bd04181cSBarry Smith row = im[0]; 402bd04181cSBarry Smith rp = aj + ai[row]; 403bd04181cSBarry Smith ap = aa + ai[row]; 404bd04181cSBarry Smith nrow = ailen[row]; 405*189e4007SBarry Smith printf("row %d nrow %d\n",row,nrow); 406*189e4007SBarry Smith if (!nrow) printf("trouble4 %d\n",row); 407bd04181cSBarry Smith low = 0; 408bd04181cSBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 409bd04181cSBarry Smith col = in[l]; 410bd04181cSBarry Smith high = nrow; 411bd04181cSBarry Smith found = PETSC_FALSE; 412*189e4007SBarry Smith //printf("%d %d %d %d %d %d\n",l,low,high-1,rp[low],rp[high-1],col); 413bd04181cSBarry Smith if (l > 0 && in[l] < in[l-1]) printf("trouble3 %d %d\n",in[l-1],in[l]); 414bd04181cSBarry Smith while (high-low > 5) { 415bd04181cSBarry Smith t = (low+high)/2; 416bd04181cSBarry Smith if (rp[t] > col) high = t; 417bd04181cSBarry Smith else low = t; 418bd04181cSBarry Smith } 419bd04181cSBarry Smith for (i=low; i<high; i++) { 420bd04181cSBarry Smith if (rp[i] == col) { 421bd04181cSBarry Smith ap[i] += v[l]; 422bd04181cSBarry Smith low = i + 1; 423bd04181cSBarry Smith found = PETSC_TRUE; 424bd04181cSBarry Smith break; 425bd04181cSBarry Smith } 426bd04181cSBarry Smith } 427*189e4007SBarry Smith if (!found) printf("trouble2 row %d %d %d %d %d %d %d %d\n",row,low,high-1,rp[low],rp[high-1],col,rp[0],rp[nrow-1]); 428bd04181cSBarry Smith } 429bd04181cSBarry Smith PetscFunctionReturn(0); 430bd04181cSBarry Smith } 431bd04181cSBarry Smith 432*189e4007SBarry Smith #include <petsc-private/isimpl.h> 433*189e4007SBarry Smith #undef __FUNCT__ 434*189e4007SBarry Smith #define __FUNCT__ "MatSeqAIJSetValuesLocalFast" 435*189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 436*189e4007SBarry Smith { 437*189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 438*189e4007SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 439*189e4007SBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 440*189e4007SBarry Smith PetscErrorCode ierr; 441*189e4007SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 442*189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 443*189e4007SBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 444*189e4007SBarry Smith PetscBool roworiented = a->roworiented; 445*189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 446*189e4007SBarry Smith 447*189e4007SBarry Smith PetscFunctionBegin; 448*189e4007SBarry Smith if (v) PetscValidScalarPointer(v,6); 449*189e4007SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 450*189e4007SBarry Smith row = ridx[im[k]]; 451*189e4007SBarry Smith if (row < 0) continue; 452*189e4007SBarry Smith #if defined(PETSC_USE_DEBUG) 453*189e4007SBarry 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); 454*189e4007SBarry Smith #endif 455*189e4007SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 456*189e4007SBarry Smith rmax = imax[row]; nrow = ailen[row]; 457*189e4007SBarry Smith low = 0; 458*189e4007SBarry Smith high = nrow; 459*189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 460*189e4007SBarry Smith col = cidx[in[l]]; 461*189e4007SBarry Smith if (col < 0) continue; 462*189e4007SBarry Smith #if defined(PETSC_USE_DEBUG) 463*189e4007SBarry Smith if (col >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",col,A->cmap->n-1); 464*189e4007SBarry Smith #endif 465*189e4007SBarry Smith 466*189e4007SBarry Smith if (v) { 467*189e4007SBarry Smith if (roworiented) { 468*189e4007SBarry Smith value = v[l + k*n]; 469*189e4007SBarry Smith } else { 470*189e4007SBarry Smith value = v[k + l*m]; 471*189e4007SBarry Smith } 472*189e4007SBarry Smith } else { 473*189e4007SBarry Smith value = 0.; 474*189e4007SBarry Smith } 475*189e4007SBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue; 476*189e4007SBarry Smith 477*189e4007SBarry Smith if (col <= lastcol) low = 0; 478*189e4007SBarry Smith else high = nrow; 479*189e4007SBarry Smith lastcol = col; 480*189e4007SBarry Smith while (high-low > 5) { 481*189e4007SBarry Smith t = (low+high)/2; 482*189e4007SBarry Smith if (rp[t] > col) high = t; 483*189e4007SBarry Smith else low = t; 484*189e4007SBarry Smith } 485*189e4007SBarry Smith for (i=low; i<high; i++) { 486*189e4007SBarry Smith if (rp[i] > col) break; 487*189e4007SBarry Smith if (rp[i] == col) { 488*189e4007SBarry Smith if (is == ADD_VALUES) ap[i] += value; 489*189e4007SBarry Smith else ap[i] = value; 490*189e4007SBarry Smith low = i + 1; 491*189e4007SBarry Smith goto noinsert; 492*189e4007SBarry Smith } 493*189e4007SBarry Smith } 494*189e4007SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 495*189e4007SBarry Smith if (nonew == 1) goto noinsert; 496*189e4007SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 497*189e4007SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 498*189e4007SBarry Smith N = nrow++ - 1; a->nz++; high++; 499*189e4007SBarry Smith /* shift up all the later entries in this row */ 500*189e4007SBarry Smith for (ii=N; ii>=i; ii--) { 501*189e4007SBarry Smith rp[ii+1] = rp[ii]; 502*189e4007SBarry Smith ap[ii+1] = ap[ii]; 503*189e4007SBarry Smith } 504*189e4007SBarry Smith rp[i] = col; 505*189e4007SBarry Smith ap[i] = value; 506*189e4007SBarry Smith low = i + 1; 507*189e4007SBarry Smith noinsert:; 508*189e4007SBarry Smith } 509*189e4007SBarry Smith ailen[row] = nrow; 510*189e4007SBarry Smith } 511*189e4007SBarry Smith A->same_nonzero = PETSC_FALSE; 512*189e4007SBarry Smith PetscFunctionReturn(0); 513*189e4007SBarry Smith } 514*189e4007SBarry Smith 515bd04181cSBarry Smith #undef __FUNCT__ 5164a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 51797f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 51817ab2063SBarry Smith { 519416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 520e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 52197f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 5226849ba73SBarry Smith PetscErrorCode ierr; 523e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 52454f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 525ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 526ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 52717ab2063SBarry Smith 5283a40ed3dSBarry Smith PetscFunctionBegin; 52971fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 53017ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 531416022c9SBarry Smith row = im[k]; 5325ef9f2a5SBarry Smith if (row < 0) continue; 5332515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 534e32f2f54SBarry 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); 5353b2fbd54SBarry Smith #endif 536bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 53717ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 538416022c9SBarry Smith low = 0; 539c71e6ed7SBarry Smith high = nrow; 54017ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 5415ef9f2a5SBarry Smith if (in[l] < 0) continue; 5422515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 543e32f2f54SBarry 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); 5443b2fbd54SBarry Smith #endif 545bfeeae90SHong Zhang col = in[l]; 54616371a99SBarry Smith if (v) { 5474b0e389bSBarry Smith if (roworiented) { 5485ef9f2a5SBarry Smith value = v[l + k*n]; 549bef8e0ddSBarry Smith } else { 5504b0e389bSBarry Smith value = v[k + l*m]; 5514b0e389bSBarry Smith } 55216371a99SBarry Smith } else { 55375567043SBarry Smith value = 0.; 55416371a99SBarry Smith } 55533b2b78bSBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES)) continue; 55636db0b34SBarry Smith 5572205254eSKarl Rupp if (col <= lastcol) low = 0; 5582205254eSKarl Rupp else high = nrow; 559e2ee6c50SBarry Smith lastcol = col; 560416022c9SBarry Smith while (high-low > 5) { 561416022c9SBarry Smith t = (low+high)/2; 562416022c9SBarry Smith if (rp[t] > col) high = t; 563416022c9SBarry Smith else low = t; 56417ab2063SBarry Smith } 565416022c9SBarry Smith for (i=low; i<high; i++) { 56617ab2063SBarry Smith if (rp[i] > col) break; 56717ab2063SBarry Smith if (rp[i] == col) { 568416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 56917ab2063SBarry Smith else ap[i] = value; 570e44c0bd4SBarry Smith low = i + 1; 57117ab2063SBarry Smith goto noinsert; 57217ab2063SBarry Smith } 57317ab2063SBarry Smith } 574abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 575c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 576e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 577fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 578c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 579416022c9SBarry Smith /* shift up all the later entries in this row */ 580416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 58117ab2063SBarry Smith rp[ii+1] = rp[ii]; 58217ab2063SBarry Smith ap[ii+1] = ap[ii]; 58317ab2063SBarry Smith } 58417ab2063SBarry Smith rp[i] = col; 58517ab2063SBarry Smith ap[i] = value; 586416022c9SBarry Smith low = i + 1; 587e44c0bd4SBarry Smith noinsert:; 58817ab2063SBarry Smith } 58917ab2063SBarry Smith ailen[row] = nrow; 59017ab2063SBarry Smith } 59188e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 5923a40ed3dSBarry Smith PetscFunctionReturn(0); 59317ab2063SBarry Smith } 59417ab2063SBarry Smith 59581824310SBarry Smith 5964a2ae208SSatish Balay #undef __FUNCT__ 5974a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 598a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 5997eb43aa7SLois Curfman McInnes { 6007eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 60197f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 60297f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 60354f21887SBarry Smith MatScalar *ap,*aa = a->a; 6047eb43aa7SLois Curfman McInnes 6053a40ed3dSBarry Smith PetscFunctionBegin; 6067eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6077eb43aa7SLois Curfman McInnes row = im[k]; 608e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 609e32f2f54SBarry 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); 610bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6117eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6127eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 613e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 614e32f2f54SBarry 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); 615bfeeae90SHong Zhang col = in[l]; 6167eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6177eb43aa7SLois Curfman McInnes while (high-low > 5) { 6187eb43aa7SLois Curfman McInnes t = (low+high)/2; 6197eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6207eb43aa7SLois Curfman McInnes else low = t; 6217eb43aa7SLois Curfman McInnes } 6227eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6237eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6247eb43aa7SLois Curfman McInnes if (rp[i] == col) { 625b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6267eb43aa7SLois Curfman McInnes goto finished; 6277eb43aa7SLois Curfman McInnes } 6287eb43aa7SLois Curfman McInnes } 62997e567efSBarry Smith *v++ = 0.0; 6307eb43aa7SLois Curfman McInnes finished:; 6317eb43aa7SLois Curfman McInnes } 6327eb43aa7SLois Curfman McInnes } 6333a40ed3dSBarry Smith PetscFunctionReturn(0); 6347eb43aa7SLois Curfman McInnes } 6357eb43aa7SLois Curfman McInnes 63617ab2063SBarry Smith 6374a2ae208SSatish Balay #undef __FUNCT__ 6384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 639dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 64017ab2063SBarry Smith { 641416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 6426849ba73SBarry Smith PetscErrorCode ierr; 6436f69ff64SBarry Smith PetscInt i,*col_lens; 6446f69ff64SBarry Smith int fd; 645b37d52dbSMark F. Adams FILE *file; 64617ab2063SBarry Smith 6473a40ed3dSBarry Smith PetscFunctionBegin; 648b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 649785e854fSJed Brown ierr = PetscMalloc1((4+A->rmap->n),&col_lens);CHKERRQ(ierr); 6502205254eSKarl Rupp 6510700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 652d0f46423SBarry Smith col_lens[1] = A->rmap->n; 653d0f46423SBarry Smith col_lens[2] = A->cmap->n; 654416022c9SBarry Smith col_lens[3] = a->nz; 655416022c9SBarry Smith 656416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 657d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 658416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 65917ab2063SBarry Smith } 660d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 661606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 662416022c9SBarry Smith 663416022c9SBarry Smith /* store column indices (zero start index) */ 6646f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 665416022c9SBarry Smith 666416022c9SBarry Smith /* store nonzero values */ 6676f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 668b37d52dbSMark F. Adams 669b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 670b37d52dbSMark F. Adams if (file) { 671b37d52dbSMark F. Adams fprintf(file,"-matload_block_size %d\n",(int)A->rmap->bs); 672b37d52dbSMark F. Adams } 6733a40ed3dSBarry Smith PetscFunctionReturn(0); 67417ab2063SBarry Smith } 675416022c9SBarry Smith 67609573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 677cd155464SBarry Smith 6784a2ae208SSatish Balay #undef __FUNCT__ 6794a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 680dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 681416022c9SBarry Smith { 682416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 683dfbe8321SBarry Smith PetscErrorCode ierr; 684d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,shift=0; 685e060cb09SBarry Smith const char *name; 686f3ef73ceSBarry Smith PetscViewerFormat format; 68717ab2063SBarry Smith 6883a40ed3dSBarry Smith PetscFunctionBegin; 689b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 69071c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 69197f1f81fSBarry Smith PetscInt nofinalvalue = 0; 692014b3a6eSMark Adams if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift))) { 693d00d2cf4SBarry Smith nofinalvalue = 1; 694d00d2cf4SBarry Smith } 695d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 696d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 69777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 69877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 699b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 70017ab2063SBarry Smith 70117ab2063SBarry Smith for (i=0; i<m; i++) { 702416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 703aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70477431f27SBarry 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); 70517ab2063SBarry Smith #else 70677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 70717ab2063SBarry Smith #endif 70817ab2063SBarry Smith } 70917ab2063SBarry Smith } 710d00d2cf4SBarry Smith if (nofinalvalue) { 711d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 712d00d2cf4SBarry Smith } 713317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 714fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 715d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 71668369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 717cd155464SBarry Smith PetscFunctionReturn(0); 718fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 719d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 720dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 72144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 72277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 72344cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 724aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 72536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 726ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 72736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(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); 72936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 730ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 7316831982aSBarry Smith } 73244cd7ae7SLois Curfman McInnes #else 733ba0e910bSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr);} 73444cd7ae7SLois Curfman McInnes #endif 73544cd7ae7SLois Curfman McInnes } 736b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 73744cd7ae7SLois Curfman McInnes } 738d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 739fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 74097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 741d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 742dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 743785e854fSJed Brown ierr = PetscMalloc1((m+1),&sptr);CHKERRQ(ierr); 744496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 745496be53dSLois Curfman McInnes sptr[i] = nzd+1; 746496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 747496be53dSLois Curfman McInnes if (a->j[j] >= i) { 748aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 74936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 750496be53dSLois Curfman McInnes #else 751496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 752496be53dSLois Curfman McInnes #endif 753496be53dSLois Curfman McInnes } 754496be53dSLois Curfman McInnes } 755496be53dSLois Curfman McInnes } 7562e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 75777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 7582e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 7592205254eSKarl Rupp if (i+4<m) { 7602205254eSKarl 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); 7612205254eSKarl Rupp } else if (i+3<m) { 7622205254eSKarl 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); 7632205254eSKarl Rupp } else if (i+2<m) { 7642205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 7652205254eSKarl Rupp } else if (i+1<m) { 7662205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 7672205254eSKarl Rupp } else if (i<m) { 7682205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 7692205254eSKarl Rupp } else { 7702205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 7712205254eSKarl Rupp } 772496be53dSLois Curfman McInnes } 773b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 774606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 775496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 776496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 77777431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 778496be53dSLois Curfman McInnes } 779b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 780496be53dSLois Curfman McInnes } 781b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 782496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 783496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 784496be53dSLois Curfman McInnes if (a->j[j] >= i) { 785aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 78636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 787b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7886831982aSBarry Smith } 789496be53dSLois Curfman McInnes #else 790b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 791496be53dSLois Curfman McInnes #endif 792496be53dSLois Curfman McInnes } 793496be53dSLois Curfman McInnes } 794b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 795496be53dSLois Curfman McInnes } 796d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 797fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 79897f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 79987828ca2SBarry Smith PetscScalar value; 80068f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 80168f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 80268f1ed48SBarry Smith 80368f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 80468f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 80568f1ed48SBarry Smith realonly = PETSC_FALSE; 80668f1ed48SBarry Smith break; 80768f1ed48SBarry Smith } 80868f1ed48SBarry Smith } 80968f1ed48SBarry Smith #endif 81002594712SBarry Smith 811d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 812dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 81302594712SBarry Smith for (i=0; i<m; i++) { 81402594712SBarry Smith jcnt = 0; 815d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 816e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 81702594712SBarry Smith value = a->a[cnt++]; 818e24b481bSBarry Smith jcnt++; 81902594712SBarry Smith } else { 82002594712SBarry Smith value = 0.0; 82102594712SBarry Smith } 822aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 82368f1ed48SBarry Smith if (realonly) { 82468f1ed48SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",PetscRealPart(value));CHKERRQ(ierr); 82568f1ed48SBarry Smith } else { 826b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 82768f1ed48SBarry Smith } 82802594712SBarry Smith #else 829b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 83002594712SBarry Smith #endif 83102594712SBarry Smith } 832b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 83302594712SBarry Smith } 834d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8353c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 836150b93efSMatthew G. Knepley PetscInt fshift=1; 837d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 8383c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 8393c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 8403c215bfdSMatthew Knepley #else 8413c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 8423c215bfdSMatthew Knepley #endif 843d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 8443c215bfdSMatthew Knepley for (i=0; i<m; i++) { 8453c215bfdSMatthew Knepley for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 8463c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 8473c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 848150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8493c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 850150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g -%g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8513c215bfdSMatthew Knepley } else { 852150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %g\n", i+fshift,a->j[j]+fshift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 8533c215bfdSMatthew Knepley } 8543c215bfdSMatthew Knepley #else 855150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 8563c215bfdSMatthew Knepley #endif 8573c215bfdSMatthew Knepley } 8583c215bfdSMatthew Knepley } 859d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8603a40ed3dSBarry Smith } else { 861d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 862dae58748SBarry Smith ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer);CHKERRQ(ierr); 863d5f3da31SBarry Smith if (A->factortype) { 86416cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 86516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 86616cd7e1dSShri Abhyankar /* L part */ 86716cd7e1dSShri Abhyankar for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 86816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 86916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 870ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 87116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 872ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 87316cd7e1dSShri Abhyankar } else { 874ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 87516cd7e1dSShri Abhyankar } 87616cd7e1dSShri Abhyankar #else 877ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 87816cd7e1dSShri Abhyankar #endif 87916cd7e1dSShri Abhyankar } 88016cd7e1dSShri Abhyankar /* diagonal */ 88116cd7e1dSShri Abhyankar j = a->diag[i]; 88216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 88316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 884ba0e910bSBarry 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); 88516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 886ba0e910bSBarry 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); 88716cd7e1dSShri Abhyankar } else { 888ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 88916cd7e1dSShri Abhyankar } 89016cd7e1dSShri Abhyankar #else 891ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)1.0/a->a[j]);CHKERRQ(ierr); 89216cd7e1dSShri Abhyankar #endif 89316cd7e1dSShri Abhyankar 89416cd7e1dSShri Abhyankar /* U part */ 89516cd7e1dSShri Abhyankar for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) { 89616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 89716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 898ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 89916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 900ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 90116cd7e1dSShri Abhyankar } else { 902ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 90316cd7e1dSShri Abhyankar } 90416cd7e1dSShri Abhyankar #else 905ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 90616cd7e1dSShri Abhyankar #endif 90716cd7e1dSShri Abhyankar } 90816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 90916cd7e1dSShri Abhyankar } 91016cd7e1dSShri Abhyankar } else { 91117ab2063SBarry Smith for (i=0; i<m; i++) { 91277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 913416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 914aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 91536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 916ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 91736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 918ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 9193a40ed3dSBarry Smith } else { 920ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 92117ab2063SBarry Smith } 92217ab2063SBarry Smith #else 923ba0e910bSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j]+shift,(double)a->a[j]);CHKERRQ(ierr); 92417ab2063SBarry Smith #endif 92517ab2063SBarry Smith } 926b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 92717ab2063SBarry Smith } 92816cd7e1dSShri Abhyankar } 929d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 93017ab2063SBarry Smith } 931b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 9323a40ed3dSBarry Smith PetscFunctionReturn(0); 933416022c9SBarry Smith } 934416022c9SBarry Smith 9359804daf3SBarry Smith #include <petscdraw.h> 9364a2ae208SSatish Balay #undef __FUNCT__ 9374a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 938dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 939416022c9SBarry Smith { 940480ef9eaSBarry Smith Mat A = (Mat) Aa; 941416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 942dfbe8321SBarry Smith PetscErrorCode ierr; 943d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 94436db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 945b0a32e0cSBarry Smith PetscViewer viewer; 946f3ef73ceSBarry Smith PetscViewerFormat format; 947cddf8d76SBarry Smith 9483a40ed3dSBarry Smith PetscFunctionBegin; 949480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 950b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 95119bcc07fSBarry Smith 952b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 953416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 9540513a670SBarry Smith 955fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 9560513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 957b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 958416022c9SBarry Smith for (i=0; i<m; i++) { 959cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 960bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 961bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 96236db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 963b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 964cddf8d76SBarry Smith } 965cddf8d76SBarry Smith } 966b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 967cddf8d76SBarry Smith for (i=0; i<m; i++) { 968cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 969bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 970bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 971cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 972b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 973cddf8d76SBarry Smith } 974cddf8d76SBarry Smith } 975b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 976cddf8d76SBarry Smith for (i=0; i<m; i++) { 977cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 978bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 979bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 98036db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 981b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 982416022c9SBarry Smith } 983416022c9SBarry Smith } 9840513a670SBarry Smith } else { 9850513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 9860513a670SBarry Smith /* first determine max of all nonzero values */ 98797f1f81fSBarry Smith PetscInt nz = a->nz,count; 988b0a32e0cSBarry Smith PetscDraw popup; 98936db0b34SBarry Smith PetscReal scale; 9900513a670SBarry Smith 9910513a670SBarry Smith for (i=0; i<nz; i++) { 9920513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 9930513a670SBarry Smith } 994b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 995b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 9962205254eSKarl Rupp if (popup) { 9972205254eSKarl Rupp ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr); 9982205254eSKarl Rupp } 9990513a670SBarry Smith count = 0; 10000513a670SBarry Smith for (i=0; i<m; i++) { 10010513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1002bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1003bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 100497f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 1005b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 10060513a670SBarry Smith count++; 10070513a670SBarry Smith } 10080513a670SBarry Smith } 10090513a670SBarry Smith } 1010480ef9eaSBarry Smith PetscFunctionReturn(0); 1011480ef9eaSBarry Smith } 1012cddf8d76SBarry Smith 10139804daf3SBarry Smith #include <petscdraw.h> 10144a2ae208SSatish Balay #undef __FUNCT__ 10154a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 1016dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1017480ef9eaSBarry Smith { 1018dfbe8321SBarry Smith PetscErrorCode ierr; 1019b0a32e0cSBarry Smith PetscDraw draw; 102036db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1021ace3abfcSBarry Smith PetscBool isnull; 1022480ef9eaSBarry Smith 1023480ef9eaSBarry Smith PetscFunctionBegin; 1024b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1025b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1026480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1027480ef9eaSBarry Smith 1028480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1029d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1030480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1031b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1032b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 10330298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 10343a40ed3dSBarry Smith PetscFunctionReturn(0); 1035416022c9SBarry Smith } 1036416022c9SBarry Smith 10374a2ae208SSatish Balay #undef __FUNCT__ 10384a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 1039dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1040416022c9SBarry Smith { 1041dfbe8321SBarry Smith PetscErrorCode ierr; 1042ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1043416022c9SBarry Smith 10443a40ed3dSBarry Smith PetscFunctionBegin; 1045251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1046251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1047251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1048c45a1595SBarry Smith if (iascii) { 10493a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 10500f5bd95cSBarry Smith } else if (isbinary) { 10513a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 10520f5bd95cSBarry Smith } else if (isdraw) { 10533a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 105411aeaf0aSBarry Smith } 10554108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 10563a40ed3dSBarry Smith PetscFunctionReturn(0); 105717ab2063SBarry Smith } 105819bcc07fSBarry Smith 10594a2ae208SSatish Balay #undef __FUNCT__ 10604a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 1061dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 106217ab2063SBarry Smith { 1063416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10646849ba73SBarry Smith PetscErrorCode ierr; 106597f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 1066d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 106754f21887SBarry Smith MatScalar *aa = a->a,*ap; 10683447b6efSHong Zhang PetscReal ratio = 0.6; 106917ab2063SBarry Smith 10703a40ed3dSBarry Smith PetscFunctionBegin; 10713a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 107217ab2063SBarry Smith 107343ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 107417ab2063SBarry Smith for (i=1; i<m; i++) { 1075416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 107617ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 107794a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 107817ab2063SBarry Smith if (fshift) { 1079bfeeae90SHong Zhang ip = aj + ai[i]; 1080bfeeae90SHong Zhang ap = aa + ai[i]; 108117ab2063SBarry Smith N = ailen[i]; 108217ab2063SBarry Smith for (j=0; j<N; j++) { 108317ab2063SBarry Smith ip[j-fshift] = ip[j]; 108417ab2063SBarry Smith ap[j-fshift] = ap[j]; 108517ab2063SBarry Smith } 108617ab2063SBarry Smith } 108717ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 108817ab2063SBarry Smith } 108917ab2063SBarry Smith if (m) { 109017ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 109117ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 109217ab2063SBarry Smith } 10937b083b7cSBarry Smith 109417ab2063SBarry Smith /* reset ilen and imax for each row */ 10957b083b7cSBarry Smith a->nonzerorowcnt = 0; 109617ab2063SBarry Smith for (i=0; i<m; i++) { 109717ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 10987b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 109917ab2063SBarry Smith } 1100bfeeae90SHong Zhang a->nz = ai[m]; 110165e19b50SBarry 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); 110217ab2063SBarry Smith 110309f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1104d0f46423SBarry 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); 1105ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1106ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 11072205254eSKarl Rupp 11088e58a170SBarry Smith A->info.mallocs += a->reallocs; 1109dd5f02e7SSatish Balay a->reallocs = 0; 11104e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 111136db0b34SBarry Smith a->rmax = rmax; 11124e220ebcSLois Curfman McInnes 111311e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 11142205254eSKarl Rupp 111588e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 111671c2f376SKris Buschelman 11174108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 111871f1c65dSBarry Smith 1119acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 11203a40ed3dSBarry Smith PetscFunctionReturn(0); 112117ab2063SBarry Smith } 112217ab2063SBarry Smith 11234a2ae208SSatish Balay #undef __FUNCT__ 112499cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 112599cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 112699cafbc1SBarry Smith { 112799cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 112899cafbc1SBarry Smith PetscInt i,nz = a->nz; 112954f21887SBarry Smith MatScalar *aa = a->a; 1130acf2f550SJed Brown PetscErrorCode ierr; 113199cafbc1SBarry Smith 113299cafbc1SBarry Smith PetscFunctionBegin; 113399cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1134acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 113599cafbc1SBarry Smith PetscFunctionReturn(0); 113699cafbc1SBarry Smith } 113799cafbc1SBarry Smith 113899cafbc1SBarry Smith #undef __FUNCT__ 113999cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 114099cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 114199cafbc1SBarry Smith { 114299cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 114399cafbc1SBarry Smith PetscInt i,nz = a->nz; 114454f21887SBarry Smith MatScalar *aa = a->a; 1145acf2f550SJed Brown PetscErrorCode ierr; 114699cafbc1SBarry Smith 114799cafbc1SBarry Smith PetscFunctionBegin; 114899cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1149acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 115099cafbc1SBarry Smith PetscFunctionReturn(0); 115199cafbc1SBarry Smith } 115299cafbc1SBarry Smith 115378b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 115478b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ_Kernel(PetscInt thread_id,Mat A) 115578b84d54SShri Abhyankar { 115678b84d54SShri Abhyankar PetscErrorCode ierr; 115778b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 115878b84d54SShri Abhyankar PetscInt n,start,end; 115978b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 116078b84d54SShri Abhyankar 116178b84d54SShri Abhyankar start = trstarts[thread_id]; 116278b84d54SShri Abhyankar end = trstarts[thread_id+1]; 116319baf141SJed Brown n = a->i[end] - a->i[start]; 116419baf141SJed Brown ierr = PetscMemzero(a->a+a->i[start],n*sizeof(PetscScalar));CHKERRQ(ierr); 116578b84d54SShri Abhyankar return 0; 116678b84d54SShri Abhyankar } 116778b84d54SShri Abhyankar 116878b84d54SShri Abhyankar #undef __FUNCT__ 116978b84d54SShri Abhyankar #define __FUNCT__ "MatZeroEntries_SeqAIJ" 117078b84d54SShri Abhyankar PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 117178b84d54SShri Abhyankar { 117278b84d54SShri Abhyankar PetscErrorCode ierr; 117378b84d54SShri Abhyankar 117478b84d54SShri Abhyankar PetscFunctionBegin; 1175ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatZeroEntries_SeqAIJ_Kernel,1,A);CHKERRQ(ierr); 1176acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 117778b84d54SShri Abhyankar PetscFunctionReturn(0); 117878b84d54SShri Abhyankar } 117978b84d54SShri Abhyankar #else 118099cafbc1SBarry Smith #undef __FUNCT__ 11814a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 1182dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 118317ab2063SBarry Smith { 1184416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1185dfbe8321SBarry Smith PetscErrorCode ierr; 11863a40ed3dSBarry Smith 11873a40ed3dSBarry Smith PetscFunctionBegin; 1188d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1189acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 11903a40ed3dSBarry Smith PetscFunctionReturn(0); 119117ab2063SBarry Smith } 119278b84d54SShri Abhyankar #endif 1193416022c9SBarry Smith 11944a2ae208SSatish Balay #undef __FUNCT__ 11954a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 1196dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 119717ab2063SBarry Smith { 1198416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1199dfbe8321SBarry Smith PetscErrorCode ierr; 1200d5d45c9bSBarry Smith 12013a40ed3dSBarry Smith PetscFunctionBegin; 1202aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1203d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 120417ab2063SBarry Smith #endif 1205e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12066bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12076bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 120805b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1209d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 121005b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 121171f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 121205b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12136bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 121405b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 12156bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 121605b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 12176bf464f9SBarry Smith ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr); 1218cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 12190b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1220a30b2313SHong Zhang 12214108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1222bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1223901853e0SKris Buschelman 1224dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1225bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1226bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1227bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1228bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1229bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1230bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1231bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1232bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1233bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1234bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 12353a40ed3dSBarry Smith PetscFunctionReturn(0); 123617ab2063SBarry Smith } 123717ab2063SBarry Smith 12384a2ae208SSatish Balay #undef __FUNCT__ 12394a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 1240ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 124117ab2063SBarry Smith { 1242416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12434846f1f5SKris Buschelman PetscErrorCode ierr; 12443a40ed3dSBarry Smith 12453a40ed3dSBarry Smith PetscFunctionBegin; 1246a65d3064SKris Buschelman switch (op) { 1247a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 12484e0d8c25SBarry Smith a->roworiented = flg; 1249a65d3064SKris Buschelman break; 1250a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1251a9817697SBarry Smith a->keepnonzeropattern = flg; 1252a65d3064SKris Buschelman break; 1253512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1254512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1255a65d3064SKris Buschelman break; 1256a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 12574e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1258a65d3064SKris Buschelman break; 1259a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 12604e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1261a65d3064SKris Buschelman break; 126228b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 126328b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 126428b2fa4aSMatthew Knepley break; 1265a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 12664e0d8c25SBarry Smith a->ignorezeroentries = flg; 12670df259c2SBarry Smith break; 12683d472b54SHong Zhang case MAT_SPD: 1269b1646e73SJed Brown case MAT_SYMMETRIC: 1270b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1271b1646e73SJed Brown case MAT_HERMITIAN: 1272b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 12735021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 12745021d80fSJed Brown break; 12754e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1276a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1277a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1278290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1279a65d3064SKris Buschelman break; 1280b87ac2d8SJed Brown case MAT_USE_INODES: 1281b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1282b87ac2d8SJed Brown break; 1283a65d3064SKris Buschelman default: 1284e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1285a65d3064SKris Buschelman } 12864108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 12873a40ed3dSBarry Smith PetscFunctionReturn(0); 128817ab2063SBarry Smith } 128917ab2063SBarry Smith 12904a2ae208SSatish Balay #undef __FUNCT__ 12914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 1292dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 129317ab2063SBarry Smith { 1294416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12956849ba73SBarry Smith PetscErrorCode ierr; 1296d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 129735e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 129817ab2063SBarry Smith 12993a40ed3dSBarry Smith PetscFunctionBegin; 1300d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1301e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 130235e7444dSHong Zhang 1303d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1304d3e70bfaSHong Zhang PetscInt *diag=a->diag; 130535e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 13062c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 130735e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 130835e7444dSHong Zhang PetscFunctionReturn(0); 130935e7444dSHong Zhang } 131035e7444dSHong Zhang 13112dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 13121ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 131335e7444dSHong Zhang for (i=0; i<n; i++) { 131435e7444dSHong Zhang nz = ai[i+1] - ai[i]; 13152f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 131635e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 131735e7444dSHong Zhang if (aj[j] == i) { 131835e7444dSHong Zhang x[i] = aa[j]; 131917ab2063SBarry Smith break; 132017ab2063SBarry Smith } 132117ab2063SBarry Smith } 132217ab2063SBarry Smith } 13231ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 13243a40ed3dSBarry Smith PetscFunctionReturn(0); 132517ab2063SBarry Smith } 132617ab2063SBarry Smith 1327c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 13284a2ae208SSatish Balay #undef __FUNCT__ 13294a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 1330dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 133117ab2063SBarry Smith { 1332416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13335c897100SBarry Smith PetscScalar *x,*y; 1334dfbe8321SBarry Smith PetscErrorCode ierr; 1335d0f46423SBarry Smith PetscInt m = A->rmap->n; 13365c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1337a77337e4SBarry Smith MatScalar *v; 1338a77337e4SBarry Smith PetscScalar alpha; 13390298fd71SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=NULL; 13403447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1341ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 13425c897100SBarry Smith #endif 134317ab2063SBarry Smith 13443a40ed3dSBarry Smith PetscFunctionBegin; 13452e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 13461ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 13471ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 13485c897100SBarry Smith 13495c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1350bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 13515c897100SBarry Smith #else 13523447b6efSHong Zhang if (usecprow) { 13533447b6efSHong Zhang m = cprow.nrows; 13543447b6efSHong Zhang ii = cprow.i; 13557b2bb3b9SHong Zhang ridx = cprow.rindex; 13563447b6efSHong Zhang } else { 13573447b6efSHong Zhang ii = a->i; 13583447b6efSHong Zhang } 135917ab2063SBarry Smith for (i=0; i<m; i++) { 13603447b6efSHong Zhang idx = a->j + ii[i]; 13613447b6efSHong Zhang v = a->a + ii[i]; 13623447b6efSHong Zhang n = ii[i+1] - ii[i]; 13633447b6efSHong Zhang if (usecprow) { 13647b2bb3b9SHong Zhang alpha = x[ridx[i]]; 13653447b6efSHong Zhang } else { 136617ab2063SBarry Smith alpha = x[i]; 13673447b6efSHong Zhang } 136804fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 136917ab2063SBarry Smith } 13705c897100SBarry Smith #endif 1371dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 13721ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 13731ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13743a40ed3dSBarry Smith PetscFunctionReturn(0); 137517ab2063SBarry Smith } 137617ab2063SBarry Smith 13774a2ae208SSatish Balay #undef __FUNCT__ 13785c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 1379dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 13805c897100SBarry Smith { 1381dfbe8321SBarry Smith PetscErrorCode ierr; 13825c897100SBarry Smith 13835c897100SBarry Smith PetscFunctionBegin; 1384170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 13855c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 13865c897100SBarry Smith PetscFunctionReturn(0); 13875c897100SBarry Smith } 13885c897100SBarry Smith 1389c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 139078b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 139178b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ_Kernel(PetscInt thread_id,Mat A,Vec xx,Vec yy) 139278b84d54SShri Abhyankar { 139378b84d54SShri Abhyankar PetscErrorCode ierr; 139478b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 139578b84d54SShri Abhyankar PetscScalar *y; 139678b84d54SShri Abhyankar const PetscScalar *x; 139778b84d54SShri Abhyankar const MatScalar *aa; 139878b84d54SShri Abhyankar PetscInt *trstarts=A->rmap->trstarts; 139978b84d54SShri Abhyankar PetscInt n,start,end,i; 140078b84d54SShri Abhyankar const PetscInt *aj,*ai; 140178b84d54SShri Abhyankar PetscScalar sum; 140278b84d54SShri Abhyankar 140378b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 140478b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 140578b84d54SShri Abhyankar start = trstarts[thread_id]; 140678b84d54SShri Abhyankar end = trstarts[thread_id+1]; 140778b84d54SShri Abhyankar aj = a->j; 140878b84d54SShri Abhyankar aa = a->a; 140978b84d54SShri Abhyankar ai = a->i; 141078b84d54SShri Abhyankar for (i=start; i<end; i++) { 141178b84d54SShri Abhyankar n = ai[i+1] - ai[i]; 141278b84d54SShri Abhyankar aj = a->j + ai[i]; 141378b84d54SShri Abhyankar aa = a->a + ai[i]; 141478b84d54SShri Abhyankar sum = 0.0; 141578b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 141678b84d54SShri Abhyankar y[i] = sum; 141778b84d54SShri Abhyankar } 141878b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 141978b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 142078b84d54SShri Abhyankar return 0; 142178b84d54SShri Abhyankar } 142278b84d54SShri Abhyankar 142378b84d54SShri Abhyankar #undef __FUNCT__ 142478b84d54SShri Abhyankar #define __FUNCT__ "MatMult_SeqAIJ" 142578b84d54SShri Abhyankar PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 142678b84d54SShri Abhyankar { 142778b84d54SShri Abhyankar Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 142878b84d54SShri Abhyankar PetscScalar *y; 142978b84d54SShri Abhyankar const PetscScalar *x; 143078b84d54SShri Abhyankar const MatScalar *aa; 143178b84d54SShri Abhyankar PetscErrorCode ierr; 143278b84d54SShri Abhyankar PetscInt m=A->rmap->n; 14330298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 14347b083b7cSBarry Smith PetscInt n,i; 143578b84d54SShri Abhyankar PetscScalar sum; 143678b84d54SShri Abhyankar PetscBool usecprow=a->compressedrow.use; 143778b84d54SShri Abhyankar 143878b84d54SShri Abhyankar #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 143978b84d54SShri Abhyankar #pragma disjoint(*x,*y,*aa) 144078b84d54SShri Abhyankar #endif 144178b84d54SShri Abhyankar 144278b84d54SShri Abhyankar PetscFunctionBegin; 144378b84d54SShri Abhyankar aj = a->j; 144478b84d54SShri Abhyankar aa = a->a; 144578b84d54SShri Abhyankar ii = a->i; 144678b84d54SShri Abhyankar if (usecprow) { /* use compressed row format */ 144778b84d54SShri Abhyankar ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 144878b84d54SShri Abhyankar ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 144978b84d54SShri Abhyankar m = a->compressedrow.nrows; 145078b84d54SShri Abhyankar ii = a->compressedrow.i; 145178b84d54SShri Abhyankar ridx = a->compressedrow.rindex; 145278b84d54SShri Abhyankar for (i=0; i<m; i++) { 145378b84d54SShri Abhyankar n = ii[i+1] - ii[i]; 145478b84d54SShri Abhyankar aj = a->j + ii[i]; 145578b84d54SShri Abhyankar aa = a->a + ii[i]; 145678b84d54SShri Abhyankar sum = 0.0; 145778b84d54SShri Abhyankar PetscSparseDensePlusDot(sum,x,aa,aj,n); 145878b84d54SShri Abhyankar /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 145978b84d54SShri Abhyankar y[*ridx++] = sum; 146078b84d54SShri Abhyankar } 146178b84d54SShri Abhyankar ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 146278b84d54SShri Abhyankar ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 146378b84d54SShri Abhyankar } else { /* do not use compressed row format */ 146478b84d54SShri Abhyankar #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 146578b84d54SShri Abhyankar fortranmultaij_(&m,x,ii,aj,aa,y); 146678b84d54SShri Abhyankar #else 1467ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 146878b84d54SShri Abhyankar #endif 146978b84d54SShri Abhyankar } 14707b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 147178b84d54SShri Abhyankar PetscFunctionReturn(0); 147278b84d54SShri Abhyankar } 147378b84d54SShri Abhyankar #else 14745c897100SBarry Smith #undef __FUNCT__ 14754a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 1476dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 147717ab2063SBarry Smith { 1478416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1479d9fead3dSBarry Smith PetscScalar *y; 148054f21887SBarry Smith const PetscScalar *x; 148154f21887SBarry Smith const MatScalar *aa; 1482dfbe8321SBarry Smith PetscErrorCode ierr; 1483003131ecSBarry Smith PetscInt m=A->rmap->n; 14840298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 14857b083b7cSBarry Smith PetscInt n,i; 1486362ced78SSatish Balay PetscScalar sum; 1487ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 148817ab2063SBarry Smith 1489b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 149097952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1491fee21e36SBarry Smith #endif 1492fee21e36SBarry Smith 14933a40ed3dSBarry Smith PetscFunctionBegin; 14943649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14951ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 149697952fefSHong Zhang aj = a->j; 149797952fefSHong Zhang aa = a->a; 1498416022c9SBarry Smith ii = a->i; 14994eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 150097952fefSHong Zhang m = a->compressedrow.nrows; 150197952fefSHong Zhang ii = a->compressedrow.i; 150297952fefSHong Zhang ridx = a->compressedrow.rindex; 150397952fefSHong Zhang for (i=0; i<m; i++) { 150497952fefSHong Zhang n = ii[i+1] - ii[i]; 150597952fefSHong Zhang aj = a->j + ii[i]; 150697952fefSHong Zhang aa = a->a + ii[i]; 150797952fefSHong Zhang sum = 0.0; 1508003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1509003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 151097952fefSHong Zhang y[*ridx++] = sum; 151197952fefSHong Zhang } 151297952fefSHong Zhang } else { /* do not use compressed row format */ 1513b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1514b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1515b05257ddSBarry Smith #else 151678b84d54SShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 1517ce94432eSBarry Smith ierr = PetscThreadCommRunKernel(PetscObjectComm((PetscObject)A),(PetscThreadKernel)MatMult_SeqAIJ_Kernel,3,A,xx,yy);CHKERRQ(ierr); 151878b84d54SShri Abhyankar #else 151917ab2063SBarry Smith for (i=0; i<m; i++) { 1520003131ecSBarry Smith n = ii[i+1] - ii[i]; 1521003131ecSBarry Smith aj = a->j + ii[i]; 1522003131ecSBarry Smith aa = a->a + ii[i]; 152317ab2063SBarry Smith sum = 0.0; 1524003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 152517ab2063SBarry Smith y[i] = sum; 152617ab2063SBarry Smith } 15278d195f9aSBarry Smith #endif 152878b84d54SShri Abhyankar #endif 1529b05257ddSBarry Smith } 15307b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15313649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15321ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15333a40ed3dSBarry Smith PetscFunctionReturn(0); 153417ab2063SBarry Smith } 153578b84d54SShri Abhyankar #endif 153617ab2063SBarry Smith 1537b434eb95SMatthew G. Knepley #undef __FUNCT__ 1538b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultMax_SeqAIJ" 1539b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1540b434eb95SMatthew G. Knepley { 1541b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1542b434eb95SMatthew G. Knepley PetscScalar *y; 1543b434eb95SMatthew G. Knepley const PetscScalar *x; 1544b434eb95SMatthew G. Knepley const MatScalar *aa; 1545b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1546b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1547b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1548b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1549b434eb95SMatthew G. Knepley PetscScalar sum; 1550b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1551b434eb95SMatthew G. Knepley 1552b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1553b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1554b434eb95SMatthew G. Knepley #endif 1555b434eb95SMatthew G. Knepley 1556b434eb95SMatthew G. Knepley PetscFunctionBegin; 1557b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1558b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1559b434eb95SMatthew G. Knepley aj = a->j; 1560b434eb95SMatthew G. Knepley aa = a->a; 1561b434eb95SMatthew G. Knepley ii = a->i; 1562b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1563b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1564b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1565b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1566b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1567b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1568b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1569b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1570b434eb95SMatthew G. Knepley sum = 0.0; 1571b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1572b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1573b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1574b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1575b434eb95SMatthew G. Knepley } 1576b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1577b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1578b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1579b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1580b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1581b434eb95SMatthew G. Knepley sum = 0.0; 1582b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1583b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1584b434eb95SMatthew G. Knepley y[i] = sum; 1585b434eb95SMatthew G. Knepley } 1586b434eb95SMatthew G. Knepley } 1587b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1588b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1589b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1590b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1591b434eb95SMatthew G. Knepley } 1592b434eb95SMatthew G. Knepley 1593b434eb95SMatthew G. Knepley #undef __FUNCT__ 1594b434eb95SMatthew G. Knepley #define __FUNCT__ "MatMultAddMax_SeqAIJ" 1595b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1596b434eb95SMatthew G. Knepley { 1597b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1598b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1599b434eb95SMatthew G. Knepley const PetscScalar *x; 1600b434eb95SMatthew G. Knepley const MatScalar *aa; 1601b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1602b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1603b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1604b434eb95SMatthew G. Knepley PetscScalar sum; 1605b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1606b434eb95SMatthew G. Knepley 1607b434eb95SMatthew G. Knepley PetscFunctionBegin; 1608b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1609b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1610b434eb95SMatthew G. Knepley if (zz != yy) { 1611b434eb95SMatthew G. Knepley ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 1612b434eb95SMatthew G. Knepley } else { 1613b434eb95SMatthew G. Knepley z = y; 1614b434eb95SMatthew G. Knepley } 1615b434eb95SMatthew G. Knepley 1616b434eb95SMatthew G. Knepley aj = a->j; 1617b434eb95SMatthew G. Knepley aa = a->a; 1618b434eb95SMatthew G. Knepley ii = a->i; 1619b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1620b434eb95SMatthew G. Knepley if (zz != yy) { 1621b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1622b434eb95SMatthew G. Knepley } 1623b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1624b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1625b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1626b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1627b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1628b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1629b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1630b434eb95SMatthew G. Knepley sum = y[*ridx]; 1631b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1632b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1633b434eb95SMatthew G. Knepley } 1634b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 1635b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1636b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1637b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1638b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1639b434eb95SMatthew G. Knepley sum = y[i]; 1640b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1641b434eb95SMatthew G. Knepley z[i] = sum; 1642b434eb95SMatthew G. Knepley } 1643b434eb95SMatthew G. Knepley } 1644b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1645b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1646b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1647b434eb95SMatthew G. Knepley if (zz != yy) { 1648b434eb95SMatthew G. Knepley ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 1649b434eb95SMatthew G. Knepley } 1650b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1651b434eb95SMatthew G. Knepley } 1652b434eb95SMatthew G. Knepley 1653c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 16544a2ae208SSatish Balay #undef __FUNCT__ 16554a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1656dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 165717ab2063SBarry Smith { 1658416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1659f15663dcSBarry Smith PetscScalar *y,*z; 1660f15663dcSBarry Smith const PetscScalar *x; 166154f21887SBarry Smith const MatScalar *aa; 1662dfbe8321SBarry Smith PetscErrorCode ierr; 1663d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 16640298fd71SBarry Smith PetscInt n,i,*ridx=NULL; 1665362ced78SSatish Balay PetscScalar sum; 1666ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16679ea0dfa2SSatish Balay 16683a40ed3dSBarry Smith PetscFunctionBegin; 1669f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 16701ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 16712e8a6d31SBarry Smith if (zz != yy) { 16721ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 16732e8a6d31SBarry Smith } else { 16742e8a6d31SBarry Smith z = y; 16752e8a6d31SBarry Smith } 1676bfeeae90SHong Zhang 167797952fefSHong Zhang aj = a->j; 167897952fefSHong Zhang aa = a->a; 1679cddf8d76SBarry Smith ii = a->i; 16804eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16814eb6d288SHong Zhang if (zz != yy) { 16824eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 16834eb6d288SHong Zhang } 168497952fefSHong Zhang m = a->compressedrow.nrows; 168597952fefSHong Zhang ii = a->compressedrow.i; 168697952fefSHong Zhang ridx = a->compressedrow.rindex; 168797952fefSHong Zhang for (i=0; i<m; i++) { 168897952fefSHong Zhang n = ii[i+1] - ii[i]; 168997952fefSHong Zhang aj = a->j + ii[i]; 169097952fefSHong Zhang aa = a->a + ii[i]; 169197952fefSHong Zhang sum = y[*ridx]; 1692f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 169397952fefSHong Zhang z[*ridx++] = sum; 169497952fefSHong Zhang } 169597952fefSHong Zhang } else { /* do not use compressed row format */ 1696f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1697f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1698f15663dcSBarry Smith #else 169917ab2063SBarry Smith for (i=0; i<m; i++) { 1700f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1701f15663dcSBarry Smith aj = a->j + ii[i]; 1702f15663dcSBarry Smith aa = a->a + ii[i]; 170317ab2063SBarry Smith sum = y[i]; 1704f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 170517ab2063SBarry Smith z[i] = sum; 170617ab2063SBarry Smith } 170702ab625aSSatish Balay #endif 1708f15663dcSBarry Smith } 1709dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1710f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 17111ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 17122e8a6d31SBarry Smith if (zz != yy) { 17131ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 17142e8a6d31SBarry Smith } 17158154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 17166b375ea7SVictor Minden /* 1717918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1718918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1719918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 17206b375ea7SVictor Minden */ 1721918e98c3SVictor Minden #endif 17223a40ed3dSBarry Smith PetscFunctionReturn(0); 172317ab2063SBarry Smith } 172417ab2063SBarry Smith 172517ab2063SBarry Smith /* 172617ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 172717ab2063SBarry Smith */ 17284a2ae208SSatish Balay #undef __FUNCT__ 17294a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1730dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 173117ab2063SBarry Smith { 1732416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17336849ba73SBarry Smith PetscErrorCode ierr; 1734d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 173517ab2063SBarry Smith 17363a40ed3dSBarry Smith PetscFunctionBegin; 173709f38230SBarry Smith if (!a->diag) { 1738785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17393bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 174009f38230SBarry Smith } 1741d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 174209f38230SBarry Smith a->diag[i] = a->i[i+1]; 1743bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1744bfeeae90SHong Zhang if (a->j[j] == i) { 174509f38230SBarry Smith a->diag[i] = j; 174617ab2063SBarry Smith break; 174717ab2063SBarry Smith } 174817ab2063SBarry Smith } 174917ab2063SBarry Smith } 17503a40ed3dSBarry Smith PetscFunctionReturn(0); 175117ab2063SBarry Smith } 175217ab2063SBarry Smith 1753be5855fcSBarry Smith /* 1754be5855fcSBarry Smith Checks for missing diagonals 1755be5855fcSBarry Smith */ 17564a2ae208SSatish Balay #undef __FUNCT__ 17574a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1758ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1759be5855fcSBarry Smith { 1760be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 176197f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1762be5855fcSBarry Smith 1763be5855fcSBarry Smith PetscFunctionBegin; 176409f38230SBarry Smith *missing = PETSC_FALSE; 1765d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 176609f38230SBarry Smith *missing = PETSC_TRUE; 176709f38230SBarry Smith if (d) *d = 0; 1768358d2f5dSShri Abhyankar PetscInfo(A,"Matrix has no entries therefore is missing diagonal"); 176909f38230SBarry Smith } else { 1770f1e2ffcdSBarry Smith diag = a->diag; 1771d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1772bfeeae90SHong Zhang if (jj[diag[i]] != i) { 177309f38230SBarry Smith *missing = PETSC_TRUE; 177409f38230SBarry Smith if (d) *d = i; 177509f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 1776358d2f5dSShri Abhyankar break; 177709f38230SBarry Smith } 1778be5855fcSBarry Smith } 1779be5855fcSBarry Smith } 1780be5855fcSBarry Smith PetscFunctionReturn(0); 1781be5855fcSBarry Smith } 1782be5855fcSBarry Smith 178371f1c65dSBarry Smith #undef __FUNCT__ 178471f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 17857087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 178671f1c65dSBarry Smith { 178771f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 178871f1c65dSBarry Smith PetscErrorCode ierr; 1789d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 179054f21887SBarry Smith MatScalar *v = a->a; 179154f21887SBarry Smith PetscScalar *idiag,*mdiag; 179271f1c65dSBarry Smith 179371f1c65dSBarry Smith PetscFunctionBegin; 179471f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 179571f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 179671f1c65dSBarry Smith diag = a->diag; 179771f1c65dSBarry Smith if (!a->idiag) { 1798dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 17993bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 180071f1c65dSBarry Smith v = a->a; 180171f1c65dSBarry Smith } 180271f1c65dSBarry Smith mdiag = a->mdiag; 180371f1c65dSBarry Smith idiag = a->idiag; 180471f1c65dSBarry Smith 1805028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 180671f1c65dSBarry Smith for (i=0; i<m; i++) { 180771f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1808e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 180971f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 181071f1c65dSBarry Smith } 181171f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 181271f1c65dSBarry Smith } else { 181371f1c65dSBarry Smith for (i=0; i<m; i++) { 181471f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 181571f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 181671f1c65dSBarry Smith } 1817dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 181871f1c65dSBarry Smith } 181971f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 182071f1c65dSBarry Smith PetscFunctionReturn(0); 182171f1c65dSBarry Smith } 182271f1c65dSBarry Smith 1823c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 18244a2ae208SSatish Balay #undef __FUNCT__ 182541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 182641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 182717ab2063SBarry Smith { 1828416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1829e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1830e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 183154f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1832dfbe8321SBarry Smith PetscErrorCode ierr; 1833d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 183497f1f81fSBarry Smith const PetscInt *idx,*diag; 183517ab2063SBarry Smith 18363a40ed3dSBarry Smith PetscFunctionBegin; 1837b965ef7fSBarry Smith its = its*lits; 183891723122SBarry Smith 183971f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 184071f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 184171f1c65dSBarry Smith a->fshift = fshift; 184271f1c65dSBarry Smith a->omega = omega; 1843ed480e8bSBarry Smith 184471f1c65dSBarry Smith diag = a->diag; 184571f1c65dSBarry Smith t = a->ssor_work; 1846ed480e8bSBarry Smith idiag = a->idiag; 184771f1c65dSBarry Smith mdiag = a->mdiag; 1848ed480e8bSBarry Smith 18491ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 18503649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1851ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 185217ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 185317ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1854ed480e8bSBarry Smith bs = b; 185517ab2063SBarry Smith for (i=0; i<m; i++) { 185671f1c65dSBarry Smith d = fshift + mdiag[i]; 1857416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1858ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1859ed480e8bSBarry Smith v = a->a + diag[i] + 1; 186017ab2063SBarry Smith sum = b[i]*d/omega; 1861003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 186217ab2063SBarry Smith x[i] = sum; 186317ab2063SBarry Smith } 18641ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 18653649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1866efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 18673a40ed3dSBarry Smith PetscFunctionReturn(0); 186817ab2063SBarry Smith } 1869c783ea89SBarry Smith 18702205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 18712205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 187217ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1873887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 187417ab2063SBarry Smith 187517ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 187617ab2063SBarry Smith 1877887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 187817ab2063SBarry Smith */ 187917ab2063SBarry Smith scale = (2.0/omega) - 1.0; 188017ab2063SBarry Smith 188117ab2063SBarry Smith /* x = (E + U)^{-1} b */ 188217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1883416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1884ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1885ed480e8bSBarry Smith v = a->a + diag[i] + 1; 188617ab2063SBarry Smith sum = b[i]; 1887e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1888ed480e8bSBarry Smith x[i] = sum*idiag[i]; 188917ab2063SBarry Smith } 189017ab2063SBarry Smith 189117ab2063SBarry Smith /* t = b - (2*E - D)x */ 1892416022c9SBarry Smith v = a->a; 18932205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 189417ab2063SBarry Smith 189517ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1896ed480e8bSBarry Smith ts = t; 1897416022c9SBarry Smith diag = a->diag; 189817ab2063SBarry Smith for (i=0; i<m; i++) { 1899416022c9SBarry Smith n = diag[i] - a->i[i]; 1900ed480e8bSBarry Smith idx = a->j + a->i[i]; 1901ed480e8bSBarry Smith v = a->a + a->i[i]; 190217ab2063SBarry Smith sum = t[i]; 1903003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1904ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1905733d66baSBarry Smith /* x = x + t */ 1906733d66baSBarry Smith x[i] += t[i]; 190717ab2063SBarry Smith } 190817ab2063SBarry Smith 1909dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 19101ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19113649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 19123a40ed3dSBarry Smith PetscFunctionReturn(0); 191317ab2063SBarry Smith } 191417ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 191517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 191617ab2063SBarry Smith for (i=0; i<m; i++) { 1917416022c9SBarry Smith n = diag[i] - a->i[i]; 1918ed480e8bSBarry Smith idx = a->j + a->i[i]; 1919ed480e8bSBarry Smith v = a->a + a->i[i]; 192017ab2063SBarry Smith sum = b[i]; 1921e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 19225c99c7daSBarry Smith t[i] = sum; 1923ed480e8bSBarry Smith x[i] = sum*idiag[i]; 192417ab2063SBarry Smith } 19255c99c7daSBarry Smith xb = t; 1926efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 19273a40ed3dSBarry Smith } else xb = b; 192817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 192917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1930416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1931ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1932ed480e8bSBarry Smith v = a->a + diag[i] + 1; 193317ab2063SBarry Smith sum = xb[i]; 1934e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 19355c99c7daSBarry Smith if (xb == b) { 1936ed480e8bSBarry Smith x[i] = sum*idiag[i]; 19375c99c7daSBarry Smith } else { 1938b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 193917ab2063SBarry Smith } 19405c99c7daSBarry Smith } 1941b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 194217ab2063SBarry Smith } 194317ab2063SBarry Smith its--; 194417ab2063SBarry Smith } 194517ab2063SBarry Smith while (its--) { 194617ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 194717ab2063SBarry Smith for (i=0; i<m; i++) { 1948b19a5dc2SMark Adams /* lower */ 1949b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1950ed480e8bSBarry Smith idx = a->j + a->i[i]; 1951ed480e8bSBarry Smith v = a->a + a->i[i]; 195217ab2063SBarry Smith sum = b[i]; 1953e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1954b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1955b19a5dc2SMark Adams /* upper */ 1956b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1957b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1958b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1959b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1960b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 196117ab2063SBarry Smith } 1962b19a5dc2SMark Adams xb = t; 19639f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1964b19a5dc2SMark Adams } else xb = b; 196517ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 196617ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1967b19a5dc2SMark Adams sum = xb[i]; 1968b19a5dc2SMark Adams if (xb == b) { 1969b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1970416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1971ed480e8bSBarry Smith idx = a->j + a->i[i]; 1972ed480e8bSBarry Smith v = a->a + a->i[i]; 1973e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1974ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1975b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1976b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1977b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1978b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1979b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1980b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 198117ab2063SBarry Smith } 1982b19a5dc2SMark Adams } 1983b19a5dc2SMark Adams if (xb == b) { 19849f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1985b19a5dc2SMark Adams } else { 1986b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1987b19a5dc2SMark Adams } 198817ab2063SBarry Smith } 198917ab2063SBarry Smith } 19901ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19913649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1992365a8a9eSBarry Smith PetscFunctionReturn(0); 199317ab2063SBarry Smith } 199417ab2063SBarry Smith 19952af78befSBarry Smith 19964a2ae208SSatish Balay #undef __FUNCT__ 19974a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1998dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 199917ab2063SBarry Smith { 2000416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20014e220ebcSLois Curfman McInnes 20023a40ed3dSBarry Smith PetscFunctionBegin; 20034e220ebcSLois Curfman McInnes info->block_size = 1.0; 20044e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 20054e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 20064e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 20074e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 20088e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 20097adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2010d5f3da31SBarry Smith if (A->factortype) { 20114e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 20124e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 20134e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 20144e220ebcSLois Curfman McInnes } else { 20154e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 20164e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 20174e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 20184e220ebcSLois Curfman McInnes } 20193a40ed3dSBarry Smith PetscFunctionReturn(0); 202017ab2063SBarry Smith } 202117ab2063SBarry Smith 20224a2ae208SSatish Balay #undef __FUNCT__ 20234a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 20242b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 202517ab2063SBarry Smith { 2026416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20273b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 20286849ba73SBarry Smith PetscErrorCode ierr; 202997b48c8fSBarry Smith const PetscScalar *xx; 203097b48c8fSBarry Smith PetscScalar *bb; 2031ace3abfcSBarry Smith PetscBool missing; 203217ab2063SBarry Smith 20333a40ed3dSBarry Smith PetscFunctionBegin; 203497b48c8fSBarry Smith if (x && b) { 203597b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 203697b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 203797b48c8fSBarry Smith for (i=0; i<N; i++) { 203897b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 203997b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 204097b48c8fSBarry Smith } 204197b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 204297b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 204397b48c8fSBarry Smith } 204497b48c8fSBarry Smith 2045a9817697SBarry Smith if (a->keepnonzeropattern) { 2046f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2047e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2048bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 2049f1e2ffcdSBarry Smith } 2050f4df32b1SMatthew Knepley if (diag != 0.0) { 205109f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 2052e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 2053f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2054f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 2055f1e2ffcdSBarry Smith } 2056f1e2ffcdSBarry Smith } 205788e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 2058f1e2ffcdSBarry Smith } else { 2059f4df32b1SMatthew Knepley if (diag != 0.0) { 206017ab2063SBarry Smith for (i=0; i<N; i++) { 2061e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 20627ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2063416022c9SBarry Smith a->ilen[rows[i]] = 1; 2064f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 2065bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 20667ae801bdSBarry Smith } else { /* in case row was completely empty */ 2067f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 206817ab2063SBarry Smith } 206917ab2063SBarry Smith } 20703a40ed3dSBarry Smith } else { 207117ab2063SBarry Smith for (i=0; i<N; i++) { 2072e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2073416022c9SBarry Smith a->ilen[rows[i]] = 0; 207417ab2063SBarry Smith } 207517ab2063SBarry Smith } 207688e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 2077f1e2ffcdSBarry Smith } 207843a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20793a40ed3dSBarry Smith PetscFunctionReturn(0); 208017ab2063SBarry Smith } 208117ab2063SBarry Smith 20824a2ae208SSatish Balay #undef __FUNCT__ 20836e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 20846e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 20856e169961SBarry Smith { 20866e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 20876e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 20886e169961SBarry Smith PetscErrorCode ierr; 20892b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 20906e169961SBarry Smith const PetscScalar *xx; 20916e169961SBarry Smith PetscScalar *bb; 20926e169961SBarry Smith 20936e169961SBarry Smith PetscFunctionBegin; 20946e169961SBarry Smith if (x && b) { 20956e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 20966e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 20972b40b63fSBarry Smith vecs = PETSC_TRUE; 20986e169961SBarry Smith } 20991795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 21006e169961SBarry Smith for (i=0; i<N; i++) { 21016e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 21026e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 21032205254eSKarl Rupp 21046e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 21056e169961SBarry Smith } 21066e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 21076e169961SBarry Smith if (!zeroed[i]) { 21086e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 21096e169961SBarry Smith if (zeroed[a->j[j]]) { 21102b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 21116e169961SBarry Smith a->a[j] = 0.0; 21126e169961SBarry Smith } 21136e169961SBarry Smith } 21142b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 21156e169961SBarry Smith } 21166e169961SBarry Smith if (x && b) { 21176e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 21186e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 21196e169961SBarry Smith } 21206e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 21216e169961SBarry Smith if (diag != 0.0) { 21226e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 21236e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 21246e169961SBarry Smith for (i=0; i<N; i++) { 21256e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 21266e169961SBarry Smith } 21276e169961SBarry Smith } 21286e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 21296e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21306e169961SBarry Smith PetscFunctionReturn(0); 21316e169961SBarry Smith } 21326e169961SBarry Smith 21336e169961SBarry Smith #undef __FUNCT__ 21344a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 2135a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 213617ab2063SBarry Smith { 2137416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 213897f1f81fSBarry Smith PetscInt *itmp; 213917ab2063SBarry Smith 21403a40ed3dSBarry Smith PetscFunctionBegin; 2141e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 214217ab2063SBarry Smith 2143416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 2144bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 214517ab2063SBarry Smith if (idx) { 2146bfeeae90SHong Zhang itmp = a->j + a->i[row]; 214726fbe8dcSKarl Rupp if (*nz) *idx = itmp; 214817ab2063SBarry Smith else *idx = 0; 214917ab2063SBarry Smith } 21503a40ed3dSBarry Smith PetscFunctionReturn(0); 215117ab2063SBarry Smith } 215217ab2063SBarry Smith 2153bfeeae90SHong Zhang /* remove this function? */ 21544a2ae208SSatish Balay #undef __FUNCT__ 21554a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 2156a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 215717ab2063SBarry Smith { 21583a40ed3dSBarry Smith PetscFunctionBegin; 21593a40ed3dSBarry Smith PetscFunctionReturn(0); 216017ab2063SBarry Smith } 216117ab2063SBarry Smith 21624a2ae208SSatish Balay #undef __FUNCT__ 21634a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 2164dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 216517ab2063SBarry Smith { 2166416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 216754f21887SBarry Smith MatScalar *v = a->a; 216836db0b34SBarry Smith PetscReal sum = 0.0; 21696849ba73SBarry Smith PetscErrorCode ierr; 217097f1f81fSBarry Smith PetscInt i,j; 217117ab2063SBarry Smith 21723a40ed3dSBarry Smith PetscFunctionBegin; 217317ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2174416022c9SBarry Smith for (i=0; i<a->nz; i++) { 217536db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 217617ab2063SBarry Smith } 21778f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 21783a40ed3dSBarry Smith } else if (type == NORM_1) { 217936db0b34SBarry Smith PetscReal *tmp; 218097f1f81fSBarry Smith PetscInt *jj = a->j; 21811795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2182064f8208SBarry Smith *nrm = 0.0; 2183416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2184bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 218517ab2063SBarry Smith } 2186d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2187064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 218817ab2063SBarry Smith } 2189606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 21903a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2191064f8208SBarry Smith *nrm = 0.0; 2192d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2193bfeeae90SHong Zhang v = a->a + a->i[j]; 219417ab2063SBarry Smith sum = 0.0; 2195416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2196cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 219717ab2063SBarry Smith } 2198064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 219917ab2063SBarry Smith } 2200f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 22013a40ed3dSBarry Smith PetscFunctionReturn(0); 220217ab2063SBarry Smith } 220317ab2063SBarry Smith 22044e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 22054e938277SHong Zhang #undef __FUNCT__ 22064e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ" 22074e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 22084e938277SHong Zhang { 22094e938277SHong Zhang PetscErrorCode ierr; 22104e938277SHong Zhang PetscInt i,j,anzj; 22114e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 22124e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 22134e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 22144e938277SHong Zhang 22154e938277SHong Zhang PetscFunctionBegin; 22164e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 22171795a4d1SJed Brown ierr = PetscCalloc1((an+1),&ati);CHKERRQ(ierr); 2218785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2219785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 22204e938277SHong Zhang 22214e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 22224e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 222326fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 22244e938277SHong Zhang /* Form ati for csr format of A^T. */ 222526fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 22264e938277SHong Zhang 22274e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 22284e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 22294e938277SHong Zhang 22304e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 22314e938277SHong Zhang for (i=0;i<am;i++) { 22324e938277SHong Zhang anzj = ai[i+1] - ai[i]; 22334e938277SHong Zhang for (j=0;j<anzj;j++) { 22344e938277SHong Zhang atj[atfill[*aj]] = i; 22354e938277SHong Zhang atfill[*aj++] += 1; 22364e938277SHong Zhang } 22374e938277SHong Zhang } 22384e938277SHong Zhang 22394e938277SHong Zhang /* Clean up temporary space and complete requests. */ 22404e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2241ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 22422205254eSKarl Rupp 2243a2f3521dSMark F. Adams (*B)->rmap->bs = A->cmap->bs; 2244a2f3521dSMark F. Adams (*B)->cmap->bs = A->rmap->bs; 2245a2f3521dSMark F. Adams 22464e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 22474e938277SHong Zhang b->free_a = PETSC_FALSE; 22484e938277SHong Zhang b->free_ij = PETSC_TRUE; 22494e938277SHong Zhang b->nonew = 0; 22504e938277SHong Zhang PetscFunctionReturn(0); 22514e938277SHong Zhang } 22524e938277SHong Zhang 22534a2ae208SSatish Balay #undef __FUNCT__ 22544a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 2255fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 225617ab2063SBarry Smith { 2257416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2258416022c9SBarry Smith Mat C; 22596849ba73SBarry Smith PetscErrorCode ierr; 2260d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 226154f21887SBarry Smith MatScalar *array = a->a; 226217ab2063SBarry Smith 22633a40ed3dSBarry Smith PetscFunctionBegin; 2264e32f2f54SBarry 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"); 2265fc4dec0aSBarry Smith 2266fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 22671795a4d1SJed Brown ierr = PetscCalloc1((1+A->cmap->n),&col);CHKERRQ(ierr); 2268bfeeae90SHong Zhang 2269bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 2270ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2271d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 2272a2f3521dSMark F. Adams ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr); 22737adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2274ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2275606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2276a541d17aSBarry Smith } else { 2277a541d17aSBarry Smith C = *B; 2278a541d17aSBarry Smith } 2279a541d17aSBarry Smith 228017ab2063SBarry Smith for (i=0; i<m; i++) { 228117ab2063SBarry Smith len = ai[i+1]-ai[i]; 228287d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2283b9b97703SBarry Smith array += len; 2284b9b97703SBarry Smith aj += len; 228517ab2063SBarry Smith } 22866d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22876d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 228817ab2063SBarry Smith 2289815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 2290416022c9SBarry Smith *B = C; 229117ab2063SBarry Smith } else { 2292eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 229317ab2063SBarry Smith } 22943a40ed3dSBarry Smith PetscFunctionReturn(0); 229517ab2063SBarry Smith } 229617ab2063SBarry Smith 2297cd0d46ebSvictorle #undef __FUNCT__ 22985fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 22997087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2300cd0d46ebSvictorle { 2301cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 230254f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 230354f21887SBarry Smith MatScalar *va,*vb; 23046849ba73SBarry Smith PetscErrorCode ierr; 230597f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2306cd0d46ebSvictorle 2307cd0d46ebSvictorle PetscFunctionBegin; 2308cd0d46ebSvictorle bij = (Mat_SeqAIJ*) B->data; 2309cd0d46ebSvictorle 2310cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2311cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 23125485867bSBarry Smith if (ma!=nb || na!=mb) { 23135485867bSBarry Smith *f = PETSC_FALSE; 23145485867bSBarry Smith PetscFunctionReturn(0); 23155485867bSBarry Smith } 2316cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2317cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2318cd0d46ebSvictorle va = aij->a; vb = bij->a; 2319785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2320785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2321cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2322cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2323cd0d46ebSvictorle 2324cd0d46ebSvictorle *f = PETSC_TRUE; 2325cd0d46ebSvictorle for (i=0; i<ma; i++) { 2326cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 232797f1f81fSBarry Smith PetscInt idc,idr; 23285485867bSBarry Smith PetscScalar vc,vr; 2329cd0d46ebSvictorle /* column/row index/value */ 23305485867bSBarry Smith idc = adx[aptr[i]]; 23315485867bSBarry Smith idr = bdx[bptr[idc]]; 23325485867bSBarry Smith vc = va[aptr[i]]; 23335485867bSBarry Smith vr = vb[bptr[idc]]; 23345485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 23355485867bSBarry Smith *f = PETSC_FALSE; 23365485867bSBarry Smith goto done; 2337cd0d46ebSvictorle } else { 23385485867bSBarry Smith aptr[i]++; 23395485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2340cd0d46ebSvictorle } 2341cd0d46ebSvictorle } 2342cd0d46ebSvictorle } 2343cd0d46ebSvictorle done: 2344cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 23453aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2346cd0d46ebSvictorle PetscFunctionReturn(0); 2347cd0d46ebSvictorle } 2348cd0d46ebSvictorle 23491cbb95d3SBarry Smith #undef __FUNCT__ 23501cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 23517087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 23521cbb95d3SBarry Smith { 23531cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) A->data; 235454f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 235554f21887SBarry Smith MatScalar *va,*vb; 23561cbb95d3SBarry Smith PetscErrorCode ierr; 23571cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 23581cbb95d3SBarry Smith 23591cbb95d3SBarry Smith PetscFunctionBegin; 23601cbb95d3SBarry Smith bij = (Mat_SeqAIJ*) B->data; 23611cbb95d3SBarry Smith 23621cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 23631cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 23641cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 23651cbb95d3SBarry Smith *f = PETSC_FALSE; 23661cbb95d3SBarry Smith PetscFunctionReturn(0); 23671cbb95d3SBarry Smith } 23681cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 23691cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 23701cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2371785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2372785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 23731cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 23741cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 23751cbb95d3SBarry Smith 23761cbb95d3SBarry Smith *f = PETSC_TRUE; 23771cbb95d3SBarry Smith for (i=0; i<ma; i++) { 23781cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 23791cbb95d3SBarry Smith PetscInt idc,idr; 23801cbb95d3SBarry Smith PetscScalar vc,vr; 23811cbb95d3SBarry Smith /* column/row index/value */ 23821cbb95d3SBarry Smith idc = adx[aptr[i]]; 23831cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 23841cbb95d3SBarry Smith vc = va[aptr[i]]; 23851cbb95d3SBarry Smith vr = vb[bptr[idc]]; 23861cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 23871cbb95d3SBarry Smith *f = PETSC_FALSE; 23881cbb95d3SBarry Smith goto done; 23891cbb95d3SBarry Smith } else { 23901cbb95d3SBarry Smith aptr[i]++; 23911cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 23921cbb95d3SBarry Smith } 23931cbb95d3SBarry Smith } 23941cbb95d3SBarry Smith } 23951cbb95d3SBarry Smith done: 23961cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 23971cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 23981cbb95d3SBarry Smith PetscFunctionReturn(0); 23991cbb95d3SBarry Smith } 24001cbb95d3SBarry Smith 24019e29f15eSvictorle #undef __FUNCT__ 24029e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 2403ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24049e29f15eSvictorle { 2405dfbe8321SBarry Smith PetscErrorCode ierr; 24066e111a19SKarl Rupp 24079e29f15eSvictorle PetscFunctionBegin; 24085485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 24099e29f15eSvictorle PetscFunctionReturn(0); 24109e29f15eSvictorle } 24119e29f15eSvictorle 24124a2ae208SSatish Balay #undef __FUNCT__ 24131cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 2414ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24151cbb95d3SBarry Smith { 24161cbb95d3SBarry Smith PetscErrorCode ierr; 24176e111a19SKarl Rupp 24181cbb95d3SBarry Smith PetscFunctionBegin; 24191cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 24201cbb95d3SBarry Smith PetscFunctionReturn(0); 24211cbb95d3SBarry Smith } 24221cbb95d3SBarry Smith 24231cbb95d3SBarry Smith #undef __FUNCT__ 24244a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 2425dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 242617ab2063SBarry Smith { 2427416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 242854f21887SBarry Smith PetscScalar *l,*r,x; 242954f21887SBarry Smith MatScalar *v; 2430dfbe8321SBarry Smith PetscErrorCode ierr; 2431d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 243217ab2063SBarry Smith 24333a40ed3dSBarry Smith PetscFunctionBegin; 243417ab2063SBarry Smith if (ll) { 24353ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 24363ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2437e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2438e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 24391ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2440416022c9SBarry Smith v = a->a; 244117ab2063SBarry Smith for (i=0; i<m; i++) { 244217ab2063SBarry Smith x = l[i]; 2443416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 24442205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 244517ab2063SBarry Smith } 24461ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2447efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 244817ab2063SBarry Smith } 244917ab2063SBarry Smith if (rr) { 2450e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2451e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 24521ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2453416022c9SBarry Smith v = a->a; jj = a->j; 24542205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 24551ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2456efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 245717ab2063SBarry Smith } 2458acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 24593a40ed3dSBarry Smith PetscFunctionReturn(0); 246017ab2063SBarry Smith } 246117ab2063SBarry Smith 24624a2ae208SSatish Balay #undef __FUNCT__ 24634a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 246497f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 246517ab2063SBarry Smith { 2466db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 24676849ba73SBarry Smith PetscErrorCode ierr; 2468d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 246997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 24705d0c19d7SBarry Smith const PetscInt *irow,*icol; 24715d0c19d7SBarry Smith PetscInt nrows,ncols; 247297f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 247354f21887SBarry Smith MatScalar *a_new,*mat_a; 2474416022c9SBarry Smith Mat C; 2475ace3abfcSBarry Smith PetscBool stride,sorted; 247617ab2063SBarry Smith 24773a40ed3dSBarry Smith PetscFunctionBegin; 247814ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 2479e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 248014ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2481e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 248299141d43SSatish Balay 248317ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2484b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2485b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 248617ab2063SBarry Smith 2487fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2488251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2489fee21e36SBarry Smith if (stride && step == 1) { 249002834360SBarry Smith /* special case of contiguous rows */ 2491dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 249202834360SBarry Smith /* loop over new rows determining lens and starting points */ 249302834360SBarry Smith for (i=0; i<nrows; i++) { 2494bfeeae90SHong Zhang kstart = ai[irow[i]]; 2495a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 249602834360SBarry Smith for (k=kstart; k<kend; k++) { 2497bfeeae90SHong Zhang if (aj[k] >= first) { 249802834360SBarry Smith starts[i] = k; 249902834360SBarry Smith break; 250002834360SBarry Smith } 250102834360SBarry Smith } 2502a2744918SBarry Smith sum = 0; 250302834360SBarry Smith while (k < kend) { 2504bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2505a2744918SBarry Smith sum++; 250602834360SBarry Smith } 2507a2744918SBarry Smith lens[i] = sum; 250802834360SBarry Smith } 250902834360SBarry Smith /* create submatrix */ 2510cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 251197f1f81fSBarry Smith PetscInt n_cols,n_rows; 251208480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2513e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2514d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 251508480c60SBarry Smith C = *B; 25163a40ed3dSBarry Smith } else { 25173bef6203SJed Brown PetscInt rbs,cbs; 2518ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2519f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 25203bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 25213bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 25223bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 25237adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2524ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 252508480c60SBarry Smith } 2526db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2527db02288aSLois Curfman McInnes 252802834360SBarry Smith /* loop over rows inserting into submatrix */ 2529db02288aSLois Curfman McInnes a_new = c->a; 2530db02288aSLois Curfman McInnes j_new = c->j; 2531db02288aSLois Curfman McInnes i_new = c->i; 2532bfeeae90SHong Zhang 253302834360SBarry Smith for (i=0; i<nrows; i++) { 2534a2744918SBarry Smith ii = starts[i]; 2535a2744918SBarry Smith lensi = lens[i]; 2536a2744918SBarry Smith for (k=0; k<lensi; k++) { 2537a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 253802834360SBarry Smith } 253987828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2540a2744918SBarry Smith a_new += lensi; 2541a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2542a2744918SBarry Smith c->ilen[i] = lensi; 254302834360SBarry Smith } 25440e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 25453a40ed3dSBarry Smith } else { 254602834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 25471795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2548785e854fSJed Brown ierr = PetscMalloc1((1+nrows),&lens);CHKERRQ(ierr); 25494dcab191SBarry Smith for (i=0; i<ncols; i++) { 25504dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 25514dcab191SBarry 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); 25524dcab191SBarry Smith #endif 25534dcab191SBarry Smith smap[icol[i]] = i+1; 25544dcab191SBarry Smith } 25554dcab191SBarry Smith 255602834360SBarry Smith /* determine lens of each row */ 255702834360SBarry Smith for (i=0; i<nrows; i++) { 2558bfeeae90SHong Zhang kstart = ai[irow[i]]; 255902834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 256002834360SBarry Smith lens[i] = 0; 256102834360SBarry Smith for (k=kstart; k<kend; k++) { 2562bfeeae90SHong Zhang if (smap[aj[k]]) { 256302834360SBarry Smith lens[i]++; 256402834360SBarry Smith } 256502834360SBarry Smith } 256602834360SBarry Smith } 256717ab2063SBarry Smith /* Create and fill new matrix */ 2568a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2569ace3abfcSBarry Smith PetscBool equal; 25700f5bd95cSBarry Smith 257199141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2572e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2573d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2574f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2575d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 257608480c60SBarry Smith C = *B; 25773a40ed3dSBarry Smith } else { 25783bef6203SJed Brown PetscInt rbs,cbs; 2579ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2580f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 25813bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 25823bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 25833bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 25847adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2585ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 258608480c60SBarry Smith } 258799141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 258817ab2063SBarry Smith for (i=0; i<nrows; i++) { 258999141d43SSatish Balay row = irow[i]; 2590bfeeae90SHong Zhang kstart = ai[row]; 259199141d43SSatish Balay kend = kstart + a->ilen[row]; 2592bfeeae90SHong Zhang mat_i = c->i[i]; 259399141d43SSatish Balay mat_j = c->j + mat_i; 259499141d43SSatish Balay mat_a = c->a + mat_i; 259599141d43SSatish Balay mat_ilen = c->ilen + i; 259617ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2597bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2598ed480e8bSBarry Smith *mat_j++ = tcol - 1; 259999141d43SSatish Balay *mat_a++ = a->a[k]; 260099141d43SSatish Balay (*mat_ilen)++; 260199141d43SSatish Balay 260217ab2063SBarry Smith } 260317ab2063SBarry Smith } 260417ab2063SBarry Smith } 260502834360SBarry Smith /* Free work space */ 260602834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2607606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2608606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 260902834360SBarry Smith } 26106d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26116d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 261217ab2063SBarry Smith 261317ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2614416022c9SBarry Smith *B = C; 26153a40ed3dSBarry Smith PetscFunctionReturn(0); 261617ab2063SBarry Smith } 261717ab2063SBarry Smith 26181df811f5SHong Zhang #undef __FUNCT__ 261982d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 2620fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 262182d44351SHong Zhang { 262282d44351SHong Zhang PetscErrorCode ierr; 262382d44351SHong Zhang Mat B; 262482d44351SHong Zhang 262582d44351SHong Zhang PetscFunctionBegin; 2626c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 262782d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 262882d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 2629a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs);CHKERRQ(ierr); 263082d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 263182d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 263282d44351SHong Zhang *subMat = B; 2633c2d650bdSHong Zhang } else { 2634c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2635c2d650bdSHong Zhang } 263682d44351SHong Zhang PetscFunctionReturn(0); 263782d44351SHong Zhang } 263882d44351SHong Zhang 263982d44351SHong Zhang #undef __FUNCT__ 26404a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 26410481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2642a871dcd8SBarry Smith { 264363b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2644dfbe8321SBarry Smith PetscErrorCode ierr; 264563b91edcSBarry Smith Mat outA; 2646ace3abfcSBarry Smith PetscBool row_identity,col_identity; 264763b91edcSBarry Smith 26483a40ed3dSBarry Smith PetscFunctionBegin; 2649e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 26501df811f5SHong Zhang 2651b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2652b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2653a871dcd8SBarry Smith 265463b91edcSBarry Smith outA = inA; 2655d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 26562205254eSKarl Rupp 2657c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 26586bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 26592205254eSKarl Rupp 2660c3122656SLisandro Dalcin a->row = row; 26612205254eSKarl Rupp 2662c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 26636bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 26642205254eSKarl Rupp 2665c3122656SLisandro Dalcin a->col = col; 266663b91edcSBarry Smith 266736db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 26686bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 26694c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 26703bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2671f0ec6fceSSatish Balay 267294a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2673785e854fSJed Brown ierr = PetscMalloc1((inA->rmap->n+1),&a->solve_work);CHKERRQ(ierr); 26743bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 267594a9d846SBarry Smith } 267663b91edcSBarry Smith 2677f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2678137fb511SHong Zhang if (row_identity && col_identity) { 2679ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2680137fb511SHong Zhang } else { 2681719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2682137fb511SHong Zhang } 26833a40ed3dSBarry Smith PetscFunctionReturn(0); 2684a871dcd8SBarry Smith } 2685a871dcd8SBarry Smith 26864a2ae208SSatish Balay #undef __FUNCT__ 26874a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2688f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2689f0b747eeSBarry Smith { 2690f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2691f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2692efee365bSSatish Balay PetscErrorCode ierr; 2693c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 26943a40ed3dSBarry Smith 26953a40ed3dSBarry Smith PetscFunctionBegin; 2696c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 26978b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2698efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2699acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 27003a40ed3dSBarry Smith PetscFunctionReturn(0); 2701f0b747eeSBarry Smith } 2702f0b747eeSBarry Smith 27034a2ae208SSatish Balay #undef __FUNCT__ 27044a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 270597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2706cddf8d76SBarry Smith { 2707dfbe8321SBarry Smith PetscErrorCode ierr; 270897f1f81fSBarry Smith PetscInt i; 2709cddf8d76SBarry Smith 27103a40ed3dSBarry Smith PetscFunctionBegin; 2711cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2712785e854fSJed Brown ierr = PetscMalloc1((n+1),B);CHKERRQ(ierr); 2713cddf8d76SBarry Smith } 2714cddf8d76SBarry Smith 2715cddf8d76SBarry Smith for (i=0; i<n; i++) { 27166a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2717cddf8d76SBarry Smith } 27183a40ed3dSBarry Smith PetscFunctionReturn(0); 2719cddf8d76SBarry Smith } 2720cddf8d76SBarry Smith 27214a2ae208SSatish Balay #undef __FUNCT__ 27224a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 272397f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 27244dcbc457SBarry Smith { 2725e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27266849ba73SBarry Smith PetscErrorCode ierr; 27275d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 27285d0c19d7SBarry Smith const PetscInt *idx; 272997f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2730f1af5d2fSBarry Smith PetscBT table; 2731bbd702dbSSatish Balay 27323a40ed3dSBarry Smith PetscFunctionBegin; 2733d0f46423SBarry Smith m = A->rmap->n; 2734e4d965acSSatish Balay ai = a->i; 2735bfeeae90SHong Zhang aj = a->j; 27368a047759SSatish Balay 2737e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 273806763907SSatish Balay 2739785e854fSJed Brown ierr = PetscMalloc1((m+1),&nidx);CHKERRQ(ierr); 274053b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 274106763907SSatish Balay 2742e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2743b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2744e4d965acSSatish Balay isz = 0; 27456831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2746e4d965acSSatish Balay 2747e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 27484dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2749b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2750e4d965acSSatish Balay 2751dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2752e4d965acSSatish Balay for (j=0; j<n; ++j) { 27532205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 27544dcbc457SBarry Smith } 275506763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 27566bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2757e4d965acSSatish Balay 275804a348a9SBarry Smith k = 0; 275904a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 276004a348a9SBarry Smith n = isz; 276106763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2762e4d965acSSatish Balay row = nidx[k]; 2763e4d965acSSatish Balay start = ai[row]; 2764e4d965acSSatish Balay end = ai[row+1]; 276504a348a9SBarry Smith for (l = start; l<end; l++) { 2766efb16452SHong Zhang val = aj[l]; 27672205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2768e4d965acSSatish Balay } 2769e4d965acSSatish Balay } 2770e4d965acSSatish Balay } 277170b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2772e4d965acSSatish Balay } 277394bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2774606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 27753a40ed3dSBarry Smith PetscFunctionReturn(0); 27764dcbc457SBarry Smith } 277717ab2063SBarry Smith 27780513a670SBarry Smith /* -------------------------------------------------------------- */ 27794a2ae208SSatish Balay #undef __FUNCT__ 27804a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2781dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 27820513a670SBarry Smith { 27830513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27846849ba73SBarry Smith PetscErrorCode ierr; 27853b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 27865d0c19d7SBarry Smith const PetscInt *row,*col; 27875d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 278856cd22aeSBarry Smith IS icolp,irowp; 27890298fd71SBarry Smith PetscInt *cwork = NULL; 27900298fd71SBarry Smith PetscScalar *vwork = NULL; 27910513a670SBarry Smith 27923a40ed3dSBarry Smith PetscFunctionBegin; 27934c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 279456cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 27954c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 279656cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 27970513a670SBarry Smith 27980513a670SBarry Smith /* determine lengths of permuted rows */ 2799785e854fSJed Brown ierr = PetscMalloc1((m+1),&lens);CHKERRQ(ierr); 28002205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2801ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2802f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 2803a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 28047adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2805ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2806606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 28070513a670SBarry Smith 2808785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 28090513a670SBarry Smith for (i=0; i<m; i++) { 281032ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28112205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2812cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 281332ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 28140513a670SBarry Smith } 2815606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 28162205254eSKarl Rupp 28173c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 28182205254eSKarl Rupp 28190513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28200513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 282156cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 282256cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 28236bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 28246bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 28253a40ed3dSBarry Smith PetscFunctionReturn(0); 28260513a670SBarry Smith } 28270513a670SBarry Smith 28284a2ae208SSatish Balay #undef __FUNCT__ 28294a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2830dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2831cb5b572fSBarry Smith { 2832dfbe8321SBarry Smith PetscErrorCode ierr; 2833cb5b572fSBarry Smith 2834cb5b572fSBarry Smith PetscFunctionBegin; 283533f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 283633f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2837be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2838be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2839be6bf707SBarry Smith 2840700c5bfcSBarry 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"); 2841d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2842cb5b572fSBarry Smith } else { 2843cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2844cb5b572fSBarry Smith } 2845cb5b572fSBarry Smith PetscFunctionReturn(0); 2846cb5b572fSBarry Smith } 2847cb5b572fSBarry Smith 28484a2ae208SSatish Balay #undef __FUNCT__ 28494994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ" 28504994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2851273d9f13SBarry Smith { 2852dfbe8321SBarry Smith PetscErrorCode ierr; 2853273d9f13SBarry Smith 2854273d9f13SBarry Smith PetscFunctionBegin; 2855ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2856273d9f13SBarry Smith PetscFunctionReturn(0); 2857273d9f13SBarry Smith } 2858273d9f13SBarry Smith 28594a2ae208SSatish Balay #undef __FUNCT__ 28608c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray_SeqAIJ" 28618c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 28626c0721eeSBarry Smith { 28636c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 28646e111a19SKarl Rupp 28656c0721eeSBarry Smith PetscFunctionBegin; 28666c0721eeSBarry Smith *array = a->a; 28676c0721eeSBarry Smith PetscFunctionReturn(0); 28686c0721eeSBarry Smith } 28696c0721eeSBarry Smith 28704a2ae208SSatish Balay #undef __FUNCT__ 28718c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray_SeqAIJ" 28728c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 28736c0721eeSBarry Smith { 28746c0721eeSBarry Smith PetscFunctionBegin; 28756c0721eeSBarry Smith PetscFunctionReturn(0); 28766c0721eeSBarry Smith } 2877273d9f13SBarry Smith 28788229c054SShri Abhyankar /* 28798229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 28808229c054SShri Abhyankar have different nonzero structure. 28818229c054SShri Abhyankar */ 2882ac90fabeSBarry Smith #undef __FUNCT__ 28838229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 28848229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2885ec7775f6SShri Abhyankar { 28868229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 2887ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2888ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2889ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 2890ec7775f6SShri Abhyankar 2891ec7775f6SShri Abhyankar PetscFunctionBegin; 2892ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2893ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 28948af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 28958af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 28968af7cee1SJed Brown nnz[i] = 0; 28978af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 28988af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 28998af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 29008af7cee1SJed Brown nnz[i]++; 29018af7cee1SJed Brown } 29028af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2903ec7775f6SShri Abhyankar } 2904ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2905ec7775f6SShri Abhyankar } 2906ec7775f6SShri Abhyankar 2907ec7775f6SShri Abhyankar #undef __FUNCT__ 2908ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2909f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2910ac90fabeSBarry Smith { 2911dfbe8321SBarry Smith PetscErrorCode ierr; 291297f1f81fSBarry Smith PetscInt i; 2913ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2914c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2915ac90fabeSBarry Smith 2916ac90fabeSBarry Smith PetscFunctionBegin; 2917c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2918ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2919f4df32b1SMatthew Knepley PetscScalar alpha = a; 29208b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2921acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2922c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2923a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2924a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 29256bf464f9SBarry Smith ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr); 2926a30b2313SHong Zhang } 2927a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 29280298fd71SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,NULL, y->i,y->j,NULL, &y->xtoy);CHKERRQ(ierr); 2929a30b2313SHong Zhang y->XtoY = X; 2930407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2931c537a176SHong Zhang } 2932f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 2933ba0e910bSBarry 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); 2934ac90fabeSBarry Smith } else { 29358229c054SShri Abhyankar Mat B; 29368229c054SShri Abhyankar PetscInt *nnz; 2937785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2938ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2939bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 29404aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 2941a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr); 2942176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 29438229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2944ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2945ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2946ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 29478229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2948ac90fabeSBarry Smith } 2949ac90fabeSBarry Smith PetscFunctionReturn(0); 2950ac90fabeSBarry Smith } 2951ac90fabeSBarry Smith 2952521d7252SBarry Smith #undef __FUNCT__ 2953354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 29547087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2955354c94deSBarry Smith { 2956354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2957354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2958354c94deSBarry Smith PetscInt i,nz; 2959354c94deSBarry Smith PetscScalar *a; 2960354c94deSBarry Smith 2961354c94deSBarry Smith PetscFunctionBegin; 2962354c94deSBarry Smith nz = aij->nz; 2963354c94deSBarry Smith a = aij->a; 29642205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2965354c94deSBarry Smith #else 2966354c94deSBarry Smith PetscFunctionBegin; 2967354c94deSBarry Smith #endif 2968354c94deSBarry Smith PetscFunctionReturn(0); 2969354c94deSBarry Smith } 2970354c94deSBarry Smith 2971e34fafa9SBarry Smith #undef __FUNCT__ 2972985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2973985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2974e34fafa9SBarry Smith { 2975e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2976e34fafa9SBarry Smith PetscErrorCode ierr; 2977d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2978e34fafa9SBarry Smith PetscReal atmp; 2979985db425SBarry Smith PetscScalar *x; 2980e34fafa9SBarry Smith MatScalar *aa; 2981e34fafa9SBarry Smith 2982e34fafa9SBarry Smith PetscFunctionBegin; 2983e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2984e34fafa9SBarry Smith aa = a->a; 2985e34fafa9SBarry Smith ai = a->i; 2986e34fafa9SBarry Smith aj = a->j; 2987e34fafa9SBarry Smith 2988985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2989e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2990e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2991e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2992e34fafa9SBarry Smith for (i=0; i<m; i++) { 2993e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 29949189402eSHong Zhang x[i] = 0.0; 2995e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2996985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2997985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2998985db425SBarry Smith aa++; aj++; 2999985db425SBarry Smith } 3000985db425SBarry Smith } 3001985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3002985db425SBarry Smith PetscFunctionReturn(0); 3003985db425SBarry Smith } 3004985db425SBarry Smith 3005985db425SBarry Smith #undef __FUNCT__ 3006985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 3007985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3008985db425SBarry Smith { 3009985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3010985db425SBarry Smith PetscErrorCode ierr; 3011d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3012985db425SBarry Smith PetscScalar *x; 3013985db425SBarry Smith MatScalar *aa; 3014985db425SBarry Smith 3015985db425SBarry Smith PetscFunctionBegin; 3016e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3017985db425SBarry Smith aa = a->a; 3018985db425SBarry Smith ai = a->i; 3019985db425SBarry Smith aj = a->j; 3020985db425SBarry Smith 3021985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3022985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3023985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3024e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3025985db425SBarry Smith for (i=0; i<m; i++) { 3026985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3027d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3028985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3029985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3030985db425SBarry Smith x[i] = 0.0; 3031985db425SBarry Smith if (idx) { 3032985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3033985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 3034985db425SBarry Smith if (aj[j] > j) { 3035985db425SBarry Smith idx[i] = j; 3036985db425SBarry Smith break; 3037985db425SBarry Smith } 3038985db425SBarry Smith } 3039985db425SBarry Smith } 3040985db425SBarry Smith } 3041985db425SBarry Smith for (j=0; j<ncols; j++) { 3042985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3043985db425SBarry Smith aa++; aj++; 3044985db425SBarry Smith } 3045985db425SBarry Smith } 3046985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3047985db425SBarry Smith PetscFunctionReturn(0); 3048985db425SBarry Smith } 3049985db425SBarry Smith 3050985db425SBarry Smith #undef __FUNCT__ 3051c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 3052c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3053c87e5d42SMatthew Knepley { 3054c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3055c87e5d42SMatthew Knepley PetscErrorCode ierr; 3056c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3057c87e5d42SMatthew Knepley PetscReal atmp; 3058c87e5d42SMatthew Knepley PetscScalar *x; 3059c87e5d42SMatthew Knepley MatScalar *aa; 3060c87e5d42SMatthew Knepley 3061c87e5d42SMatthew Knepley PetscFunctionBegin; 3062e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3063c87e5d42SMatthew Knepley aa = a->a; 3064c87e5d42SMatthew Knepley ai = a->i; 3065c87e5d42SMatthew Knepley aj = a->j; 3066c87e5d42SMatthew Knepley 3067c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3068c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3069c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 30703bb78c5cSMatthew 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); 3071c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3072c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3073289a08f5SMatthew Knepley if (ncols) { 3074289a08f5SMatthew Knepley /* Get first nonzero */ 3075289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 3076289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 30772205254eSKarl Rupp if (atmp > 1.0e-12) { 30782205254eSKarl Rupp x[i] = atmp; 30792205254eSKarl Rupp if (idx) idx[i] = aj[j]; 30802205254eSKarl Rupp break; 30812205254eSKarl Rupp } 3082289a08f5SMatthew Knepley } 308312431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 3084289a08f5SMatthew Knepley } else { 3085289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 3086289a08f5SMatthew Knepley } 3087c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 3088c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 3089289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3090c87e5d42SMatthew Knepley aa++; aj++; 3091c87e5d42SMatthew Knepley } 3092c87e5d42SMatthew Knepley } 3093c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3094c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3095c87e5d42SMatthew Knepley } 3096c87e5d42SMatthew Knepley 3097c87e5d42SMatthew Knepley #undef __FUNCT__ 3098985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 3099985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3100985db425SBarry Smith { 3101985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3102985db425SBarry Smith PetscErrorCode ierr; 3103d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3104985db425SBarry Smith PetscScalar *x; 3105985db425SBarry Smith MatScalar *aa; 3106985db425SBarry Smith 3107985db425SBarry Smith PetscFunctionBegin; 3108e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3109985db425SBarry Smith aa = a->a; 3110985db425SBarry Smith ai = a->i; 3111985db425SBarry Smith aj = a->j; 3112985db425SBarry Smith 3113985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3114985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 3115985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3116e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3117985db425SBarry Smith for (i=0; i<m; i++) { 3118985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3119d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3120985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3121985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3122985db425SBarry Smith x[i] = 0.0; 3123985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3124985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 3125985db425SBarry Smith for (j=0; j<ncols; j++) { 3126985db425SBarry Smith if (aj[j] > j) { 3127985db425SBarry Smith idx[i] = j; 3128985db425SBarry Smith break; 3129985db425SBarry Smith } 3130985db425SBarry Smith } 3131985db425SBarry Smith } 3132985db425SBarry Smith } 3133985db425SBarry Smith for (j=0; j<ncols; j++) { 3134985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3135985db425SBarry Smith aa++; aj++; 3136e34fafa9SBarry Smith } 3137e34fafa9SBarry Smith } 3138e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 3139e34fafa9SBarry Smith PetscFunctionReturn(0); 3140e34fafa9SBarry Smith } 3141bbead8a2SBarry Smith 3142bbead8a2SBarry Smith #include <petscblaslapack.h> 314306873bf2SBarry Smith #include <petsc-private/kernels/blockinvert.h> 3144bbead8a2SBarry Smith 3145bbead8a2SBarry Smith #undef __FUNCT__ 3146bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ" 3147713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3148bbead8a2SBarry Smith { 3149bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3150bbead8a2SBarry Smith PetscErrorCode ierr; 315134fc4b71SJed 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; 3152bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 3153bbead8a2SBarry Smith PetscReal shift = 0.0; 3154bbead8a2SBarry Smith 3155bbead8a2SBarry Smith PetscFunctionBegin; 31564a0d0026SBarry Smith if (a->ibdiagvalid) { 31574a0d0026SBarry Smith if (values) *values = a->ibdiag; 31584a0d0026SBarry Smith PetscFunctionReturn(0); 31594a0d0026SBarry Smith } 3160bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3161bbead8a2SBarry Smith if (!a->ibdiag) { 3162785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 31633bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3164bbead8a2SBarry Smith } 3165bbead8a2SBarry Smith diag = a->ibdiag; 3166bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3167bbead8a2SBarry Smith /* factor and invert each block */ 3168bbead8a2SBarry Smith switch (bs) { 3169bbead8a2SBarry Smith case 1: 3170bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3171bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3172bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3173bbead8a2SBarry Smith } 3174bbead8a2SBarry Smith break; 3175bbead8a2SBarry Smith case 2: 3176bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3177bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3178bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 317996b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr); 318096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3181bbead8a2SBarry Smith diag += 4; 3182bbead8a2SBarry Smith } 3183bbead8a2SBarry Smith break; 3184bbead8a2SBarry Smith case 3: 3185bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3186bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3187bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 318896b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr); 318996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3190bbead8a2SBarry Smith diag += 9; 3191bbead8a2SBarry Smith } 3192bbead8a2SBarry Smith break; 3193bbead8a2SBarry Smith case 4: 3194bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3195bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3196bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 319796b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr); 319896b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3199bbead8a2SBarry Smith diag += 16; 3200bbead8a2SBarry Smith } 3201bbead8a2SBarry Smith break; 3202bbead8a2SBarry Smith case 5: 3203bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3204bbead8a2SBarry 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; 3205bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 320696b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr); 320796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3208bbead8a2SBarry Smith diag += 25; 3209bbead8a2SBarry Smith } 3210bbead8a2SBarry Smith break; 3211bbead8a2SBarry Smith case 6: 3212bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3213bbead8a2SBarry 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; 3214bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 321596b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr); 321696b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3217bbead8a2SBarry Smith diag += 36; 3218bbead8a2SBarry Smith } 3219bbead8a2SBarry Smith break; 3220bbead8a2SBarry Smith case 7: 3221bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3222bbead8a2SBarry 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; 3223bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 322496b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr); 322596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3226bbead8a2SBarry Smith diag += 49; 3227bbead8a2SBarry Smith } 3228bbead8a2SBarry Smith break; 3229bbead8a2SBarry Smith default: 3230dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3231bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3232bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3233bbead8a2SBarry Smith IJ[j] = bs*i + j; 3234bbead8a2SBarry Smith } 3235bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 323696b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr); 323796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3238bbead8a2SBarry Smith diag += bs2; 3239bbead8a2SBarry Smith } 3240bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3241bbead8a2SBarry Smith } 3242bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3243bbead8a2SBarry Smith PetscFunctionReturn(0); 3244bbead8a2SBarry Smith } 3245bbead8a2SBarry Smith 324673a71a0fSBarry Smith #undef __FUNCT__ 324773a71a0fSBarry Smith #define __FUNCT__ "MatSetRandom_SeqAIJ" 324873a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 324973a71a0fSBarry Smith { 325073a71a0fSBarry Smith PetscErrorCode ierr; 325173a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 325273a71a0fSBarry Smith PetscScalar a; 325373a71a0fSBarry Smith PetscInt m,n,i,j,col; 325473a71a0fSBarry Smith 325573a71a0fSBarry Smith PetscFunctionBegin; 325673a71a0fSBarry Smith if (!x->assembled) { 325773a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 325873a71a0fSBarry Smith for (i=0; i<m; i++) { 325973a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 326073a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 326173a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 326273a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 326373a71a0fSBarry Smith } 326473a71a0fSBarry Smith } 326573a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 326673a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 326773a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 326873a71a0fSBarry Smith PetscFunctionReturn(0); 326973a71a0fSBarry Smith } 327073a71a0fSBarry Smith 3271682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 32720a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3273cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3274cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3275cb5b572fSBarry Smith MatMult_SeqAIJ, 327697304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 32777c922b88SBarry Smith MatMultTranspose_SeqAIJ, 32787c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3279db4efbfdSBarry Smith 0, 3280db4efbfdSBarry Smith 0, 3281db4efbfdSBarry Smith 0, 3282db4efbfdSBarry Smith /* 10*/ 0, 3283cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3284cb5b572fSBarry Smith 0, 328541f059aeSBarry Smith MatSOR_SeqAIJ, 328617ab2063SBarry Smith MatTranspose_SeqAIJ, 328797304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3288cb5b572fSBarry Smith MatEqual_SeqAIJ, 3289cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3290cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3291cb5b572fSBarry Smith MatNorm_SeqAIJ, 329297304618SKris Buschelman /* 20*/ 0, 3293cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3294cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3295cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3296d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3297db4efbfdSBarry Smith 0, 3298db4efbfdSBarry Smith 0, 3299db4efbfdSBarry Smith 0, 3300db4efbfdSBarry Smith 0, 33014994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3302db4efbfdSBarry Smith 0, 3303db4efbfdSBarry Smith 0, 33048c778c55SBarry Smith 0, 33058c778c55SBarry Smith 0, 3306d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3307cb5b572fSBarry Smith 0, 3308cb5b572fSBarry Smith 0, 3309cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3310cb5b572fSBarry Smith 0, 3311d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 3312cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3313cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3314cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3315cb5b572fSBarry Smith MatCopy_SeqAIJ, 3316d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3317cb5b572fSBarry Smith MatScale_SeqAIJ, 3318cb5b572fSBarry Smith 0, 331979299369SBarry Smith MatDiagonalSet_SeqAIJ, 33206e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 332173a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 33223b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 33233b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 33243b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3325a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 332693dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3327b9617806SBarry Smith 0, 33280513a670SBarry Smith 0, 3329cda55fadSBarry Smith MatPermute_SeqAIJ, 3330cda55fadSBarry Smith 0, 3331d519adbfSMatthew Knepley /* 59*/ 0, 3332b9b97703SBarry Smith MatDestroy_SeqAIJ, 3333b9b97703SBarry Smith MatView_SeqAIJ, 3334357abbc8SBarry Smith 0, 3335321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3336321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3337321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3338ee4f033dSBarry Smith 0, 3339ee4f033dSBarry Smith 0, 3340ee4f033dSBarry Smith 0, 3341d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3342c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3343ee4f033dSBarry Smith 0, 3344ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 3345dcf5cc72SBarry Smith 0, 3346d519adbfSMatthew Knepley /* 74*/ MatSetValuesAdifor_SeqAIJ, 33473acb8795SBarry Smith MatFDColoringApply_AIJ, 334897304618SKris Buschelman 0, 334997304618SKris Buschelman 0, 335097304618SKris Buschelman 0, 33516ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 335297304618SKris Buschelman 0, 335397304618SKris Buschelman 0, 335497304618SKris Buschelman 0, 3355bc011b1eSHong Zhang MatLoad_SeqAIJ, 3356d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 33571cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 33586284ec50SHong Zhang 0, 33596284ec50SHong Zhang 0, 3360bc011b1eSHong Zhang 0, 3361d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 336226be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 336326be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 336465e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 33654a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 336665e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 33676fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 33686fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 33696fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 33702121bac1SHong Zhang 0, 33712121bac1SHong Zhang /* 99*/ 0, 3372609c6c4dSKris Buschelman 0, 3373609c6c4dSKris Buschelman 0, 337487d4246cSBarry Smith MatConjugate_SeqAIJ, 337587d4246cSBarry Smith 0, 3376d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 337799cafbc1SBarry Smith MatRealPart_SeqAIJ, 3378f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3379f5edf698SHong Zhang 0, 33802bebee5dSHong Zhang 0, 3381cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3382985db425SBarry Smith 0, 33832af78befSBarry Smith MatGetRowMin_SeqAIJ, 33842af78befSBarry Smith 0, 3385599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3386d519adbfSMatthew Knepley /*114*/ 0, 3387599ef60dSHong Zhang 0, 33883c2a7987SHong Zhang 0, 3389fe97e370SBarry Smith 0, 3390fbdbba38SShri Abhyankar 0, 3391fbdbba38SShri Abhyankar /*119*/ 0, 3392fbdbba38SShri Abhyankar 0, 3393fbdbba38SShri Abhyankar 0, 339482d44351SHong Zhang 0, 3395b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 33960716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3397bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 339837868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 339937868618SMatthew G Knepley 0, 340037868618SMatthew G Knepley 0, 34015df89d91SHong Zhang /*129*/ 0, 340275648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 340375648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 340475648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3405b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3406b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 34072b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 34082b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 34092b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 34103964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 34113964eb88SJed Brown /*139*/0, 3412f9426fe0SMark Adams 0, 34131919a2e2SJed Brown 0, 34143a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 34153a062f41SBarry Smith MatFindOffBlockDiagonalEntries_SeqAIJ 34169e29f15eSvictorle }; 341717ab2063SBarry Smith 34184a2ae208SSatish Balay #undef __FUNCT__ 34194a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 34207087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3421bef8e0ddSBarry Smith { 3422bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 342397f1f81fSBarry Smith PetscInt i,nz,n; 3424bef8e0ddSBarry Smith 3425bef8e0ddSBarry Smith PetscFunctionBegin; 3426bef8e0ddSBarry Smith nz = aij->maxnz; 3427d0f46423SBarry Smith n = mat->rmap->n; 3428bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3429bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3430bef8e0ddSBarry Smith } 3431bef8e0ddSBarry Smith aij->nz = nz; 3432bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3433bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3434bef8e0ddSBarry Smith } 3435bef8e0ddSBarry Smith PetscFunctionReturn(0); 3436bef8e0ddSBarry Smith } 3437bef8e0ddSBarry Smith 34384a2ae208SSatish Balay #undef __FUNCT__ 34394a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3440bef8e0ddSBarry Smith /*@ 3441bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3442bef8e0ddSBarry Smith in the matrix. 3443bef8e0ddSBarry Smith 3444bef8e0ddSBarry Smith Input Parameters: 3445bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3446bef8e0ddSBarry Smith - indices - the column indices 3447bef8e0ddSBarry Smith 344815091d37SBarry Smith Level: advanced 344915091d37SBarry Smith 3450bef8e0ddSBarry Smith Notes: 3451bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3452bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3453bef8e0ddSBarry Smith of the MatSetValues() operation. 3454bef8e0ddSBarry Smith 3455bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3456d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3457bef8e0ddSBarry Smith 3458bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3459bef8e0ddSBarry Smith 3460b9617806SBarry Smith The indices should start with zero, not one. 3461b9617806SBarry Smith 3462bef8e0ddSBarry Smith @*/ 34637087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3464bef8e0ddSBarry Smith { 34654ac538c5SBarry Smith PetscErrorCode ierr; 3466bef8e0ddSBarry Smith 3467bef8e0ddSBarry Smith PetscFunctionBegin; 34680700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 34694482741eSBarry Smith PetscValidPointer(indices,2); 34704ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3471bef8e0ddSBarry Smith PetscFunctionReturn(0); 3472bef8e0ddSBarry Smith } 3473bef8e0ddSBarry Smith 3474be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3475be6bf707SBarry Smith 34764a2ae208SSatish Balay #undef __FUNCT__ 34774a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 34787087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3479be6bf707SBarry Smith { 3480be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 34816849ba73SBarry Smith PetscErrorCode ierr; 3482d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3483be6bf707SBarry Smith 3484be6bf707SBarry Smith PetscFunctionBegin; 3485169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3486be6bf707SBarry Smith 3487be6bf707SBarry Smith /* allocate space for values if not already there */ 3488be6bf707SBarry Smith if (!aij->saved_values) { 3489785e854fSJed Brown ierr = PetscMalloc1((nz+1),&aij->saved_values);CHKERRQ(ierr); 34903bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3491be6bf707SBarry Smith } 3492be6bf707SBarry Smith 3493be6bf707SBarry Smith /* copy values over */ 349487828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3495be6bf707SBarry Smith PetscFunctionReturn(0); 3496be6bf707SBarry Smith } 3497be6bf707SBarry Smith 34984a2ae208SSatish Balay #undef __FUNCT__ 3499b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3500be6bf707SBarry Smith /*@ 3501be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3502be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3503be6bf707SBarry Smith nonlinear portion. 3504be6bf707SBarry Smith 3505be6bf707SBarry Smith Collect on Mat 3506be6bf707SBarry Smith 3507be6bf707SBarry Smith Input Parameters: 35080e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3509be6bf707SBarry Smith 351015091d37SBarry Smith Level: advanced 351115091d37SBarry Smith 3512be6bf707SBarry Smith Common Usage, with SNESSolve(): 3513be6bf707SBarry Smith $ Create Jacobian matrix 3514be6bf707SBarry Smith $ Set linear terms into matrix 3515be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3516be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3517be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3518512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3519be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3520be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3521be6bf707SBarry Smith $ In your Jacobian routine 3522be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3523be6bf707SBarry Smith $ Set nonlinear terms in matrix 3524be6bf707SBarry Smith 3525be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3526be6bf707SBarry Smith $ // build linear portion of Jacobian 3527512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3528be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3529be6bf707SBarry Smith $ loop over nonlinear iterations 3530be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3531be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3532be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3533be6bf707SBarry Smith $ Solve linear system with Jacobian 3534be6bf707SBarry Smith $ endloop 3535be6bf707SBarry Smith 3536be6bf707SBarry Smith Notes: 3537be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3538512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3539be6bf707SBarry Smith calling this routine. 3540be6bf707SBarry Smith 35410c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 35420c468ba9SBarry Smith and does not allocated additional space. 35430c468ba9SBarry Smith 3544be6bf707SBarry Smith .seealso: MatRetrieveValues() 3545be6bf707SBarry Smith 3546be6bf707SBarry Smith @*/ 35477087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3548be6bf707SBarry Smith { 35494ac538c5SBarry Smith PetscErrorCode ierr; 3550be6bf707SBarry Smith 3551be6bf707SBarry Smith PetscFunctionBegin; 35520700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3553e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3554e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 35554ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3556be6bf707SBarry Smith PetscFunctionReturn(0); 3557be6bf707SBarry Smith } 3558be6bf707SBarry Smith 35594a2ae208SSatish Balay #undef __FUNCT__ 35604a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 35617087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3562be6bf707SBarry Smith { 3563be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 35646849ba73SBarry Smith PetscErrorCode ierr; 3565d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3566be6bf707SBarry Smith 3567be6bf707SBarry Smith PetscFunctionBegin; 3568169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3569f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3570be6bf707SBarry Smith /* copy values over */ 357187828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3572be6bf707SBarry Smith PetscFunctionReturn(0); 3573be6bf707SBarry Smith } 3574be6bf707SBarry Smith 35754a2ae208SSatish Balay #undef __FUNCT__ 35764a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3577be6bf707SBarry Smith /*@ 3578be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3579be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3580be6bf707SBarry Smith nonlinear portion. 3581be6bf707SBarry Smith 3582be6bf707SBarry Smith Collect on Mat 3583be6bf707SBarry Smith 3584be6bf707SBarry Smith Input Parameters: 3585be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3586be6bf707SBarry Smith 358715091d37SBarry Smith Level: advanced 358815091d37SBarry Smith 3589be6bf707SBarry Smith .seealso: MatStoreValues() 3590be6bf707SBarry Smith 3591be6bf707SBarry Smith @*/ 35927087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3593be6bf707SBarry Smith { 35944ac538c5SBarry Smith PetscErrorCode ierr; 3595be6bf707SBarry Smith 3596be6bf707SBarry Smith PetscFunctionBegin; 35970700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3598e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3599e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 36004ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3601be6bf707SBarry Smith PetscFunctionReturn(0); 3602be6bf707SBarry Smith } 3603be6bf707SBarry Smith 3604f83d6046SBarry Smith 3605be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 36064a2ae208SSatish Balay #undef __FUNCT__ 36074a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 360817ab2063SBarry Smith /*@C 3609682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 36100d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 36116e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 361251c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 36132bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 361417ab2063SBarry Smith 3615db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3616db81eaa0SLois Curfman McInnes 361717ab2063SBarry Smith Input Parameters: 3618db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 361917ab2063SBarry Smith . m - number of rows 362017ab2063SBarry Smith . n - number of columns 362117ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 362251c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 36230298fd71SBarry Smith (possibly different for each row) or NULL 362417ab2063SBarry Smith 362517ab2063SBarry Smith Output Parameter: 3626416022c9SBarry Smith . A - the matrix 362717ab2063SBarry Smith 3628175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3629ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3630175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3631175b88e8SBarry Smith 3632b259b22eSLois Curfman McInnes Notes: 363349a6f317SBarry Smith If nnz is given then nz is ignored 363449a6f317SBarry Smith 363517ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 363617ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 36370002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 363844cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 363917ab2063SBarry Smith 364017ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 36410298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 36423d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 36436da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 364417ab2063SBarry Smith 3645682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 36464fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3647682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 36486c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 36496c7ebb05SLois Curfman McInnes 36506c7ebb05SLois Curfman McInnes Options Database Keys: 3651698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 36529db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 365317ab2063SBarry Smith 3654027ccd11SLois Curfman McInnes Level: intermediate 3655027ccd11SLois Curfman McInnes 365669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 365736db0b34SBarry Smith 365817ab2063SBarry Smith @*/ 36597087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 366017ab2063SBarry Smith { 3661dfbe8321SBarry Smith PetscErrorCode ierr; 36626945ee14SBarry Smith 36633a40ed3dSBarry Smith PetscFunctionBegin; 3664f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3665117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3666c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3667d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3668273d9f13SBarry Smith PetscFunctionReturn(0); 3669273d9f13SBarry Smith } 3670273d9f13SBarry Smith 36714a2ae208SSatish Balay #undef __FUNCT__ 36724a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3673273d9f13SBarry Smith /*@C 3674273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3675273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3676273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3677273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3678273d9f13SBarry Smith 3679273d9f13SBarry Smith Collective on MPI_Comm 3680273d9f13SBarry Smith 3681273d9f13SBarry Smith Input Parameters: 3682117016b1SBarry Smith + B - The matrix-free 3683273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3684273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 36850298fd71SBarry Smith (possibly different for each row) or NULL 3686273d9f13SBarry Smith 3687273d9f13SBarry Smith Notes: 368849a6f317SBarry Smith If nnz is given then nz is ignored 368949a6f317SBarry Smith 3690273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3691273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3692273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3693273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3694273d9f13SBarry Smith 3695273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 36960298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3697273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3698273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3699273d9f13SBarry Smith 3700aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3701aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3702aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3703aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3704aa95bbe8SBarry Smith 3705a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3706a96a251dSBarry Smith entries or columns indices 3707a96a251dSBarry Smith 3708273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3709273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3710273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3711273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3712273d9f13SBarry Smith 3713273d9f13SBarry Smith Options Database Keys: 3714698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3715698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3716273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3717273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3718273d9f13SBarry Smith the user still MUST index entries starting at 0! 3719273d9f13SBarry Smith 3720273d9f13SBarry Smith Level: intermediate 3721273d9f13SBarry Smith 372269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3723273d9f13SBarry Smith 3724273d9f13SBarry Smith @*/ 37257087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3726273d9f13SBarry Smith { 37274ac538c5SBarry Smith PetscErrorCode ierr; 3728a23d5eceSKris Buschelman 3729a23d5eceSKris Buschelman PetscFunctionBegin; 37306ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 37316ba663aaSJed Brown PetscValidType(B,1); 37324ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3733a23d5eceSKris Buschelman PetscFunctionReturn(0); 3734a23d5eceSKris Buschelman } 3735a23d5eceSKris Buschelman 3736a23d5eceSKris Buschelman #undef __FUNCT__ 3737a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 37387087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3739a23d5eceSKris Buschelman { 3740273d9f13SBarry Smith Mat_SeqAIJ *b; 37412576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 37426849ba73SBarry Smith PetscErrorCode ierr; 374397f1f81fSBarry Smith PetscInt i; 3744273d9f13SBarry Smith 3745273d9f13SBarry Smith PetscFunctionBegin; 37462576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3747a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3748c461c341SBarry Smith skipallocation = PETSC_TRUE; 3749c461c341SBarry Smith nz = 0; 3750c461c341SBarry Smith } 3751c461c341SBarry Smith 375226283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 375326283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3754899cda47SBarry Smith 3755435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3756e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3757b73539f3SBarry Smith if (nnz) { 3758d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3759e32f2f54SBarry 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]); 3760e32f2f54SBarry 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); 3761b73539f3SBarry Smith } 3762b73539f3SBarry Smith } 3763b73539f3SBarry Smith 3764273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 37652205254eSKarl Rupp 3766273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3767273d9f13SBarry Smith 3768ab93d7beSBarry Smith if (!skipallocation) { 37692ee49352SLisandro Dalcin if (!b->imax) { 3770dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 37713bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 37722ee49352SLisandro Dalcin } 3773273d9f13SBarry Smith if (!nnz) { 3774435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3775c62bd62aSJed Brown else if (nz < 0) nz = 1; 3776d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3777d0f46423SBarry Smith nz = nz*B->rmap->n; 3778273d9f13SBarry Smith } else { 3779273d9f13SBarry Smith nz = 0; 3780d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3781273d9f13SBarry Smith } 3782ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 37832205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3784ab93d7beSBarry Smith 3785273d9f13SBarry Smith /* allocate the matrix space */ 37862ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3787dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 37883bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3789bfeeae90SHong Zhang b->i[0] = 0; 3790d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 37915da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 37925da197adSKris Buschelman } 3793273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3794e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3795e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3796b31eba2aSShri Abhyankar #if defined(PETSC_THREADCOMM_ACTIVE) 3797b31eba2aSShri Abhyankar ierr = MatZeroEntries_SeqAIJ(B);CHKERRQ(ierr); 3798b31eba2aSShri Abhyankar #endif 3799c461c341SBarry Smith } else { 3800e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3801e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3802c461c341SBarry Smith } 3803273d9f13SBarry Smith 3804273d9f13SBarry Smith b->nz = 0; 3805273d9f13SBarry Smith b->maxnz = nz; 3806273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 38072205254eSKarl Rupp if (realalloc) { 38082205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 38092205254eSKarl Rupp } 3810273d9f13SBarry Smith PetscFunctionReturn(0); 3811273d9f13SBarry Smith } 3812273d9f13SBarry Smith 3813a1661176SMatthew Knepley #undef __FUNCT__ 3814a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 381558d36128SBarry Smith /*@ 3816a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3817a1661176SMatthew Knepley 3818a1661176SMatthew Knepley Input Parameters: 3819a1661176SMatthew Knepley + B - the matrix 3820a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3821a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3822a1661176SMatthew Knepley - v - optional values in the matrix 3823a1661176SMatthew Knepley 3824a1661176SMatthew Knepley Level: developer 3825a1661176SMatthew Knepley 382658d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 382758d36128SBarry Smith 3828a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3829a1661176SMatthew Knepley 3830a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3831a1661176SMatthew Knepley @*/ 3832a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3833a1661176SMatthew Knepley { 3834a1661176SMatthew Knepley PetscErrorCode ierr; 3835a1661176SMatthew Knepley 3836a1661176SMatthew Knepley PetscFunctionBegin; 38370700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 38386ba663aaSJed Brown PetscValidType(B,1); 38394ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3840a1661176SMatthew Knepley PetscFunctionReturn(0); 3841a1661176SMatthew Knepley } 3842a1661176SMatthew Knepley 3843a1661176SMatthew Knepley #undef __FUNCT__ 3844a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 38457087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3846a1661176SMatthew Knepley { 3847a1661176SMatthew Knepley PetscInt i; 3848a1661176SMatthew Knepley PetscInt m,n; 3849a1661176SMatthew Knepley PetscInt nz; 3850a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3851a1661176SMatthew Knepley PetscScalar *values; 3852a1661176SMatthew Knepley PetscErrorCode ierr; 3853a1661176SMatthew Knepley 3854a1661176SMatthew Knepley PetscFunctionBegin; 385565e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3856779a8d59SSatish Balay 3857779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3858779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3859779a8d59SSatish Balay 3860779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3861785e854fSJed Brown ierr = PetscMalloc1((m+1), &nnz);CHKERRQ(ierr); 3862a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3863b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3864a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 386565e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3866a1661176SMatthew Knepley nnz[i] = nz; 3867a1661176SMatthew Knepley } 3868a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3869a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3870a1661176SMatthew Knepley 3871a1661176SMatthew Knepley if (v) { 3872a1661176SMatthew Knepley values = (PetscScalar*) v; 3873a1661176SMatthew Knepley } else { 38741795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3875a1661176SMatthew Knepley } 3876a1661176SMatthew Knepley 3877a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3878b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3879b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3880a1661176SMatthew Knepley } 3881a1661176SMatthew Knepley 3882a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3883a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3884a1661176SMatthew Knepley 3885a1661176SMatthew Knepley if (!v) { 3886a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3887a1661176SMatthew Knepley } 38887827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3889a1661176SMatthew Knepley PetscFunctionReturn(0); 3890a1661176SMatthew Knepley } 3891a1661176SMatthew Knepley 3892c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 389306873bf2SBarry Smith #include <petsc-private/kernels/petscaxpy.h> 3894170fe5c8SBarry Smith 3895170fe5c8SBarry Smith #undef __FUNCT__ 3896170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 3897170fe5c8SBarry Smith /* 3898170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3899170fe5c8SBarry Smith 3900170fe5c8SBarry Smith n p p 3901170fe5c8SBarry Smith ( ) ( ) ( ) 3902170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3903170fe5c8SBarry Smith ( ) ( ) ( ) 3904170fe5c8SBarry Smith 3905170fe5c8SBarry Smith */ 3906170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3907170fe5c8SBarry Smith { 3908170fe5c8SBarry Smith PetscErrorCode ierr; 3909170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3910170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3911170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 39121de00fd4SBarry Smith PetscInt i,n,m,q,p; 3913170fe5c8SBarry Smith const PetscInt *ii,*idx; 3914170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3915170fe5c8SBarry Smith PetscScalar *c,*c_q; 3916170fe5c8SBarry Smith 3917170fe5c8SBarry Smith PetscFunctionBegin; 3918d0f46423SBarry Smith m = A->rmap->n; 3919d0f46423SBarry Smith n = A->cmap->n; 3920d0f46423SBarry Smith p = B->cmap->n; 3921170fe5c8SBarry Smith a = sub_a->v; 3922170fe5c8SBarry Smith b = sub_b->a; 3923170fe5c8SBarry Smith c = sub_c->v; 3924170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3925170fe5c8SBarry Smith 3926170fe5c8SBarry Smith ii = sub_b->i; 3927170fe5c8SBarry Smith idx = sub_b->j; 3928170fe5c8SBarry Smith for (i=0; i<n; i++) { 3929170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3930170fe5c8SBarry Smith while (q-->0) { 3931170fe5c8SBarry Smith c_q = c + m*(*idx); 3932170fe5c8SBarry Smith a_q = a + m*i; 3933854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3934170fe5c8SBarry Smith idx++; 3935170fe5c8SBarry Smith b++; 3936170fe5c8SBarry Smith } 3937170fe5c8SBarry Smith } 3938170fe5c8SBarry Smith PetscFunctionReturn(0); 3939170fe5c8SBarry Smith } 3940170fe5c8SBarry Smith 3941170fe5c8SBarry Smith #undef __FUNCT__ 3942170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 3943170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3944170fe5c8SBarry Smith { 3945170fe5c8SBarry Smith PetscErrorCode ierr; 3946d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3947170fe5c8SBarry Smith Mat Cmat; 3948170fe5c8SBarry Smith 3949170fe5c8SBarry Smith PetscFunctionBegin; 3950e32f2f54SBarry 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); 3951ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3952170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 3953a2f3521dSMark F. Adams ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr); 3954170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 39550298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3956d73949e8SHong Zhang 3957d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 39582205254eSKarl Rupp 3959170fe5c8SBarry Smith *C = Cmat; 3960170fe5c8SBarry Smith PetscFunctionReturn(0); 3961170fe5c8SBarry Smith } 3962170fe5c8SBarry Smith 3963170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3964170fe5c8SBarry Smith #undef __FUNCT__ 3965170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 3966170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3967170fe5c8SBarry Smith { 3968170fe5c8SBarry Smith PetscErrorCode ierr; 3969170fe5c8SBarry Smith 3970170fe5c8SBarry Smith PetscFunctionBegin; 3971170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 39723ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3973170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 39743ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3975170fe5c8SBarry Smith } 39763ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3977170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 39783ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3979170fe5c8SBarry Smith PetscFunctionReturn(0); 3980170fe5c8SBarry Smith } 3981170fe5c8SBarry Smith 3982170fe5c8SBarry Smith 39830bad9183SKris Buschelman /*MC 3984fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 39850bad9183SKris Buschelman based on compressed sparse row format. 39860bad9183SKris Buschelman 39870bad9183SKris Buschelman Options Database Keys: 39880bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 39890bad9183SKris Buschelman 39900bad9183SKris Buschelman Level: beginner 39910bad9183SKris Buschelman 3992f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 39930bad9183SKris Buschelman M*/ 39940bad9183SKris Buschelman 3995ccd284c7SBarry Smith /*MC 3996ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3997ccd284c7SBarry Smith 3998ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3999ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 4000ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 4001ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4002ccd284c7SBarry Smith the above preallocation routines for simplicity. 4003ccd284c7SBarry Smith 4004ccd284c7SBarry Smith Options Database Keys: 4005ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4006ccd284c7SBarry Smith 4007ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 4008ccd284c7SBarry Smith enough exist. 4009ccd284c7SBarry Smith 4010ccd284c7SBarry Smith Level: beginner 4011ccd284c7SBarry Smith 4012ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4013ccd284c7SBarry Smith M*/ 4014ccd284c7SBarry Smith 4015ccd284c7SBarry Smith /*MC 4016ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4017ccd284c7SBarry Smith 4018ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4019ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4020ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4021ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4022ccd284c7SBarry Smith the above preallocation routines for simplicity. 4023ccd284c7SBarry Smith 4024ccd284c7SBarry Smith Options Database Keys: 4025ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4026ccd284c7SBarry Smith 4027ccd284c7SBarry Smith Level: beginner 4028ccd284c7SBarry Smith 4029ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4030ccd284c7SBarry Smith M*/ 4031ccd284c7SBarry Smith 4032b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 40338cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 4034b5e56a35SBarry Smith #endif 4035ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 40368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat*); 4037af1023dbSSatish Balay #endif 40388cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 40398cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 40408cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 40417087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool*); 4042611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 40438cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 4044611f576cSBarry Smith #endif 4045611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 40468cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 4047611f576cSBarry Smith #endif 4048f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 40498cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 4050f3c0ef26SHong Zhang #endif 4051eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 40528cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 4053eb3b5408SSatish Balay #endif 4054586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 40558cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 4056586621ddSJed Brown #endif 4057719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 40588cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 4059719d5645SBarry Smith #endif 4060b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 40618cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 40627087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 40637087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 4064b3866ffcSBarry Smith #endif 406517f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE) 40668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatGetFactor_aij_clique(Mat,MatFactorType,Mat*); 406717f1a0eaSHong Zhang #endif 406817667f90SBarry Smith 4069c0c8ee5eSDmitry Karpeev 40708c778c55SBarry Smith #undef __FUNCT__ 40718c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJGetArray" 40728c778c55SBarry Smith /*@C 40738c778c55SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a SeqSeqAIJ matrix is stored 40748c778c55SBarry Smith 40758c778c55SBarry Smith Not Collective 40768c778c55SBarry Smith 40778c778c55SBarry Smith Input Parameter: 40788c778c55SBarry Smith . mat - a MATSEQDENSE matrix 40798c778c55SBarry Smith 40808c778c55SBarry Smith Output Parameter: 40818c778c55SBarry Smith . array - pointer to the data 40828c778c55SBarry Smith 40838c778c55SBarry Smith Level: intermediate 40848c778c55SBarry Smith 4085774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 40868c778c55SBarry Smith @*/ 40878c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 40888c778c55SBarry Smith { 40898c778c55SBarry Smith PetscErrorCode ierr; 40908c778c55SBarry Smith 40918c778c55SBarry Smith PetscFunctionBegin; 40928c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 40938c778c55SBarry Smith PetscFunctionReturn(0); 40948c778c55SBarry Smith } 40958c778c55SBarry Smith 40968c778c55SBarry Smith #undef __FUNCT__ 40978c778c55SBarry Smith #define __FUNCT__ "MatSeqAIJRestoreArray" 40988c778c55SBarry Smith /*@C 40998c778c55SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a SeqSeqAIJ matrix is stored obtained by MatSeqAIJGetArray() 41008c778c55SBarry Smith 41018c778c55SBarry Smith Not Collective 41028c778c55SBarry Smith 41038c778c55SBarry Smith Input Parameters: 41048c778c55SBarry Smith . mat - a MATSEQDENSE matrix 41058c778c55SBarry Smith . array - pointer to the data 41068c778c55SBarry Smith 41078c778c55SBarry Smith Level: intermediate 41088c778c55SBarry Smith 4109774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 41108c778c55SBarry Smith @*/ 41118c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 41128c778c55SBarry Smith { 41138c778c55SBarry Smith PetscErrorCode ierr; 41148c778c55SBarry Smith 41158c778c55SBarry Smith PetscFunctionBegin; 41168c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 41178c778c55SBarry Smith PetscFunctionReturn(0); 41188c778c55SBarry Smith } 41198c778c55SBarry Smith 41204a2ae208SSatish Balay #undef __FUNCT__ 41214a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 41228cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4123273d9f13SBarry Smith { 4124273d9f13SBarry Smith Mat_SeqAIJ *b; 4125dfbe8321SBarry Smith PetscErrorCode ierr; 412638baddfdSBarry Smith PetscMPIInt size; 4127273d9f13SBarry Smith 4128273d9f13SBarry Smith PetscFunctionBegin; 4129ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 4130e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4131273d9f13SBarry Smith 4132b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 41332205254eSKarl Rupp 4134b0a32e0cSBarry Smith B->data = (void*)b; 41352205254eSKarl Rupp 4136549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 41372205254eSKarl Rupp 4138416022c9SBarry Smith b->row = 0; 4139416022c9SBarry Smith b->col = 0; 414082bf6240SBarry Smith b->icol = 0; 4141b810aeb4SBarry Smith b->reallocs = 0; 414236db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4143f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4144416022c9SBarry Smith b->nonew = 0; 4145416022c9SBarry Smith b->diag = 0; 4146416022c9SBarry Smith b->solve_work = 0; 41472a1b7f2aSHong Zhang B->spptr = 0; 4148be6bf707SBarry Smith b->saved_values = 0; 4149d7f994e1SBarry Smith b->idiag = 0; 415071f1c65dSBarry Smith b->mdiag = 0; 415171f1c65dSBarry Smith b->ssor_work = 0; 415271f1c65dSBarry Smith b->omega = 1.0; 415371f1c65dSBarry Smith b->fshift = 0.0; 415471f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4155bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4156a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 4157a30b2313SHong Zhang b->xtoy = 0; 4158a30b2313SHong Zhang b->XtoY = 0; 415988e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 416017ab2063SBarry Smith 416135d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4162bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4163bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 41648c778c55SBarry Smith 4165b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4166bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_matlab_C",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 4167bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4168bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4169b3866ffcSBarry Smith #endif 4170b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 4171bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_pastix_C",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 4172b5e56a35SBarry Smith #endif 4173ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 4174bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_essl_C",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 4175719d5645SBarry Smith #endif 4176611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 4177bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_C",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 4178611f576cSBarry Smith #endif 4179f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 4180bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_superlu_dist_C",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 4181f3c0ef26SHong Zhang #endif 4182611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 4183bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_mumps_C",MatGetFactor_aij_mumps);CHKERRQ(ierr); 4184611f576cSBarry Smith #endif 4185eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 4186bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_umfpack_C",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 4187eb3b5408SSatish Balay #endif 4188586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 4189bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_cholmod_C",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 4190586621ddSJed Brown #endif 4191719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 4192bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_lusol_C",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 4193719d5645SBarry Smith #endif 419417f1a0eaSHong Zhang #if defined(PETSC_HAVE_CLIQUE) 4195bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_clique_C",MatGetFactor_aij_clique);CHKERRQ(ierr); 419617f1a0eaSHong Zhang #endif 419717f1a0eaSHong Zhang 4198bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_petsc_C",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 4199bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactorAvailable_petsc_C",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 4200bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatGetFactor_bas_C",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 4201bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4202bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4203bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4204bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4205bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4206bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 4207bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4208bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4209bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4210bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4211bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4212bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 4213bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 4214bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 4215bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 42164108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 421717667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 42183a40ed3dSBarry Smith PetscFunctionReturn(0); 421917ab2063SBarry Smith } 422017ab2063SBarry Smith 42214a2ae208SSatish Balay #undef __FUNCT__ 4222b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 4223b24902e0SBarry Smith /* 4224b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4225b24902e0SBarry Smith */ 4226ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 422717ab2063SBarry Smith { 4228416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 42296849ba73SBarry Smith PetscErrorCode ierr; 4230d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 423117ab2063SBarry Smith 42323a40ed3dSBarry Smith PetscFunctionBegin; 4233273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 4234273d9f13SBarry Smith 4235d5f3da31SBarry Smith C->factortype = A->factortype; 4236416022c9SBarry Smith c->row = 0; 4237416022c9SBarry Smith c->col = 0; 423882bf6240SBarry Smith c->icol = 0; 42396ad4291fSHong Zhang c->reallocs = 0; 424017ab2063SBarry Smith 42416ad4291fSHong Zhang C->assembled = PETSC_TRUE; 424217ab2063SBarry Smith 4243aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4244aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4245eec197d1SBarry Smith 4246dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 42473bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 424817ab2063SBarry Smith for (i=0; i<m; i++) { 4249416022c9SBarry Smith c->imax[i] = a->imax[i]; 4250416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 425117ab2063SBarry Smith } 425217ab2063SBarry Smith 425317ab2063SBarry Smith /* allocate the matrix space */ 4254f77e22a1SHong Zhang if (mallocmatspace) { 4255dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 42563bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 42572205254eSKarl Rupp 4258f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 42592205254eSKarl Rupp 426097f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 426117ab2063SBarry Smith if (m > 0) { 426297f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 4263be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4264bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 4265be6bf707SBarry Smith } else { 4266bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 426717ab2063SBarry Smith } 426808480c60SBarry Smith } 4269f77e22a1SHong Zhang } 427017ab2063SBarry Smith 42716ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4272416022c9SBarry Smith c->roworiented = a->roworiented; 4273416022c9SBarry Smith c->nonew = a->nonew; 4274416022c9SBarry Smith if (a->diag) { 4275785e854fSJed Brown ierr = PetscMalloc1((m+1),&c->diag);CHKERRQ(ierr); 42763bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 427717ab2063SBarry Smith for (i=0; i<m; i++) { 4278416022c9SBarry Smith c->diag[i] = a->diag[i]; 427917ab2063SBarry Smith } 42803a40ed3dSBarry Smith } else c->diag = 0; 42812205254eSKarl Rupp 42826ad4291fSHong Zhang c->solve_work = 0; 42836ad4291fSHong Zhang c->saved_values = 0; 42846ad4291fSHong Zhang c->idiag = 0; 428571f1c65dSBarry Smith c->ssor_work = 0; 4286a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4287e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4288e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 42896ad4291fSHong Zhang c->xtoy = 0; 42906ad4291fSHong Zhang c->XtoY = 0; 42916ad4291fSHong Zhang 4292893ad86cSHong Zhang c->rmax = a->rmax; 4293416022c9SBarry Smith c->nz = a->nz; 42948ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4295273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4296754ec7b1SSatish Balay 42976ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 42986ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4299cd6b891eSBarry Smith if (a->compressedrow.use) { 43006ad4291fSHong Zhang i = a->compressedrow.nrows; 4301dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 43026ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 43036ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 430427ea64f8SHong Zhang } else { 430527ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 43060298fd71SBarry Smith c->compressedrow.i = NULL; 43070298fd71SBarry Smith c->compressedrow.rindex = NULL; 43086ad4291fSHong Zhang } 430988e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 43104846f1f5SKris Buschelman 43112205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4312140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 43133a40ed3dSBarry Smith PetscFunctionReturn(0); 431417ab2063SBarry Smith } 431517ab2063SBarry Smith 43164a2ae208SSatish Balay #undef __FUNCT__ 4317b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 4318b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4319b24902e0SBarry Smith { 4320b24902e0SBarry Smith PetscErrorCode ierr; 4321b24902e0SBarry Smith 4322b24902e0SBarry Smith PetscFunctionBegin; 4323ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 43244b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4325cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 4326a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 4327cfd3f464SBarry Smith } 4328a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4329f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4330b24902e0SBarry Smith PetscFunctionReturn(0); 4331b24902e0SBarry Smith } 4332b24902e0SBarry Smith 4333b24902e0SBarry Smith #undef __FUNCT__ 43344a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 4335112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4336fbdbba38SShri Abhyankar { 4337fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4338fbdbba38SShri Abhyankar PetscErrorCode ierr; 4339fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4340fbdbba38SShri Abhyankar int fd; 4341fbdbba38SShri Abhyankar PetscMPIInt size; 4342fbdbba38SShri Abhyankar MPI_Comm comm; 4343bbead8a2SBarry Smith PetscInt bs = 1; 4344fbdbba38SShri Abhyankar 4345fbdbba38SShri Abhyankar PetscFunctionBegin; 4346fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4347fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4348fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4349bbead8a2SBarry Smith 43500298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 43510298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4352bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 43531814747fSJed Brown if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);} 4354bbead8a2SBarry Smith 4355fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4356fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4357fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4358fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4359fbdbba38SShri Abhyankar 4360bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4361fbdbba38SShri Abhyankar 4362fbdbba38SShri Abhyankar /* read in row lengths */ 4363785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4364fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4365fbdbba38SShri Abhyankar 4366fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4367fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 4368fbdbba38SShri 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); 4369fbdbba38SShri Abhyankar 4370fbdbba38SShri Abhyankar /* set global size if not set already*/ 4371f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4372fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4373aabbc4fbSShri Abhyankar } else { 4374fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 4375fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 43764c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 43774c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 43784c5b953cSHong Zhang } 4379f501eaabSShri 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); 4380aabbc4fbSShri Abhyankar } 4381fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4382fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4383fbdbba38SShri Abhyankar 4384fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4385fbdbba38SShri Abhyankar 4386fbdbba38SShri Abhyankar /* read in nonzero values */ 4387fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4388fbdbba38SShri Abhyankar 4389fbdbba38SShri Abhyankar /* set matrix "i" values */ 4390fbdbba38SShri Abhyankar a->i[0] = 0; 4391fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4392fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4393fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4394fbdbba38SShri Abhyankar } 4395fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4396fbdbba38SShri Abhyankar 4397fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4398fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4399fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4400fbdbba38SShri Abhyankar } 4401fbdbba38SShri Abhyankar 4402fbdbba38SShri Abhyankar #undef __FUNCT__ 4403b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 4404ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 44057264ac53SSatish Balay { 44067264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4407dfbe8321SBarry Smith PetscErrorCode ierr; 4408eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4409eeffb40dSHong Zhang PetscInt k; 4410eeffb40dSHong Zhang #endif 44117264ac53SSatish Balay 44123a40ed3dSBarry Smith PetscFunctionBegin; 4413bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4414d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4415ca44d042SBarry Smith *flg = PETSC_FALSE; 4416ca44d042SBarry Smith PetscFunctionReturn(0); 4417bcd2baecSBarry Smith } 44187264ac53SSatish Balay 44197264ac53SSatish Balay /* if the a->i are the same */ 4420d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4421abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 44227264ac53SSatish Balay 44237264ac53SSatish Balay /* if a->j are the same */ 442497f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4425abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4426bcd2baecSBarry Smith 4427bcd2baecSBarry Smith /* if a->a are the same */ 4428eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4429eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4430eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4431eeffb40dSHong Zhang *flg = PETSC_FALSE; 44323a40ed3dSBarry Smith PetscFunctionReturn(0); 4433eeffb40dSHong Zhang } 4434eeffb40dSHong Zhang } 4435eeffb40dSHong Zhang #else 4436eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4437eeffb40dSHong Zhang #endif 4438eeffb40dSHong Zhang PetscFunctionReturn(0); 44397264ac53SSatish Balay } 444036db0b34SBarry Smith 44414a2ae208SSatish Balay #undef __FUNCT__ 44424a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 444305869f15SSatish Balay /*@ 444436db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 444536db0b34SBarry Smith provided by the user. 444636db0b34SBarry Smith 4447c75a6043SHong Zhang Collective on MPI_Comm 444836db0b34SBarry Smith 444936db0b34SBarry Smith Input Parameters: 445036db0b34SBarry Smith + comm - must be an MPI communicator of size 1 445136db0b34SBarry Smith . m - number of rows 445236db0b34SBarry Smith . n - number of columns 445336db0b34SBarry Smith . i - row indices 445436db0b34SBarry Smith . j - column indices 445536db0b34SBarry Smith - a - matrix values 445636db0b34SBarry Smith 445736db0b34SBarry Smith Output Parameter: 445836db0b34SBarry Smith . mat - the matrix 445936db0b34SBarry Smith 446036db0b34SBarry Smith Level: intermediate 446136db0b34SBarry Smith 446236db0b34SBarry Smith Notes: 44630551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4464292fb18eSBarry Smith once the matrix is destroyed and not before 446536db0b34SBarry Smith 446636db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 446736db0b34SBarry Smith 4468bfeeae90SHong Zhang The i and j indices are 0 based 446936db0b34SBarry Smith 4470a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4471a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4472a4552177SSatish Balay as shown: 4473a4552177SSatish Balay 4474a4552177SSatish Balay 1 0 0 4475a4552177SSatish Balay 2 0 3 4476a4552177SSatish Balay 4 5 6 4477a4552177SSatish Balay 4478a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 44799985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4480a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4481a4552177SSatish Balay 44829985e31cSBarry Smith 448369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 448436db0b34SBarry Smith 448536db0b34SBarry Smith @*/ 44867087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat) 448736db0b34SBarry Smith { 4488dfbe8321SBarry Smith PetscErrorCode ierr; 4489cbcfb4deSHong Zhang PetscInt ii; 449036db0b34SBarry Smith Mat_SeqAIJ *aij; 4491cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4492cbcfb4deSHong Zhang PetscInt jj; 4493cbcfb4deSHong Zhang #endif 449436db0b34SBarry Smith 449536db0b34SBarry Smith PetscFunctionBegin; 4496f23aa3ddSBarry Smith if (i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4497f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4498f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4499a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4500ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4501ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4502ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4503dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4504ab93d7beSBarry Smith 450536db0b34SBarry Smith aij->i = i; 450636db0b34SBarry Smith aij->j = j; 450736db0b34SBarry Smith aij->a = a; 450836db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 450936db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4510e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4511e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 451236db0b34SBarry Smith 451336db0b34SBarry Smith for (ii=0; ii<m; ii++) { 451436db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 45152515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 4516e32f2f54SBarry 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]); 45179985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4518e32f2f54SBarry 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); 4519e32f2f54SBarry 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); 45209985e31cSBarry Smith } 452136db0b34SBarry Smith #endif 452236db0b34SBarry Smith } 45232515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 452436db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 4525e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 4526e32f2f54SBarry 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]); 452736db0b34SBarry Smith } 452836db0b34SBarry Smith #endif 452936db0b34SBarry Smith 4530b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4531b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 453236db0b34SBarry Smith PetscFunctionReturn(0); 453336db0b34SBarry Smith } 45348a0b0e6bSVictor Minden #undef __FUNCT__ 45358a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple" 453680ef6e79SMatthew G Knepley /*@C 4537d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 45388a0b0e6bSVictor Minden provided by the user. 45398a0b0e6bSVictor Minden 45408a0b0e6bSVictor Minden Collective on MPI_Comm 45418a0b0e6bSVictor Minden 45428a0b0e6bSVictor Minden Input Parameters: 45438a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 45448a0b0e6bSVictor Minden . m - number of rows 45458a0b0e6bSVictor Minden . n - number of columns 45468a0b0e6bSVictor Minden . i - row indices 45478a0b0e6bSVictor Minden . j - column indices 45481230e6d1SVictor Minden . a - matrix values 45491230e6d1SVictor Minden . nz - number of nonzeros 45501230e6d1SVictor Minden - idx - 0 or 1 based 45518a0b0e6bSVictor Minden 45528a0b0e6bSVictor Minden Output Parameter: 45538a0b0e6bSVictor Minden . mat - the matrix 45548a0b0e6bSVictor Minden 45558a0b0e6bSVictor Minden Level: intermediate 45568a0b0e6bSVictor Minden 45578a0b0e6bSVictor Minden Notes: 45588a0b0e6bSVictor Minden The i and j indices are 0 based 45598a0b0e6bSVictor Minden 45608a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 45618a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 45628a0b0e6bSVictor Minden as shown: 45638a0b0e6bSVictor Minden 45648a0b0e6bSVictor Minden 1 0 0 45658a0b0e6bSVictor Minden 2 0 3 45668a0b0e6bSVictor Minden 4 5 6 45678a0b0e6bSVictor Minden 45688a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 45698a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 45708a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 45718a0b0e6bSVictor Minden 45728a0b0e6bSVictor Minden 457369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 45748a0b0e6bSVictor Minden 45758a0b0e6bSVictor Minden @*/ 45761230e6d1SVictor Minden PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt *i,PetscInt *j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx) 45778a0b0e6bSVictor Minden { 45788a0b0e6bSVictor Minden PetscErrorCode ierr; 4579d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 45808a0b0e6bSVictor Minden 45818a0b0e6bSVictor Minden 45828a0b0e6bSVictor Minden PetscFunctionBegin; 45831795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 45841230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4585c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 45861230e6d1SVictor Minden } 45878a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 45888a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 45898a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 45901230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 45911230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 45921230e6d1SVictor Minden if (idx) { 45931230e6d1SVictor Minden row = i[ii] - 1; 45941230e6d1SVictor Minden col = j[ii] - 1; 45951230e6d1SVictor Minden } else { 45961230e6d1SVictor Minden row = i[ii]; 45971230e6d1SVictor Minden col = j[ii]; 45988a0b0e6bSVictor Minden } 45991230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 46008a0b0e6bSVictor Minden } 46018a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 46028a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4603d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 46048a0b0e6bSVictor Minden PetscFunctionReturn(0); 46058a0b0e6bSVictor Minden } 460636db0b34SBarry Smith 4607cc8ba8e1SBarry Smith #undef __FUNCT__ 4608ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4609dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4610cc8ba8e1SBarry Smith { 4611dfbe8321SBarry Smith PetscErrorCode ierr; 4612cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 461336db0b34SBarry Smith 4614cc8ba8e1SBarry Smith PetscFunctionBegin; 46158ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4616cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4617cc8ba8e1SBarry Smith a->coloring = coloring; 461812c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 461997f1f81fSBarry Smith PetscInt i,*larray; 462012c595b3SBarry Smith ISColoring ocoloring; 462108b6dcc0SBarry Smith ISColoringValue *colors; 462212c595b3SBarry Smith 462312c595b3SBarry Smith /* set coloring for diagonal portion */ 4624785e854fSJed Brown ierr = PetscMalloc1(A->cmap->n,&larray);CHKERRQ(ierr); 46252205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) larray[i] = i; 46260298fd71SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,NULL,larray);CHKERRQ(ierr); 4627785e854fSJed Brown ierr = PetscMalloc1(A->cmap->n,&colors);CHKERRQ(ierr); 46282205254eSKarl Rupp for (i=0; i<A->cmap->n; i++) colors[i] = coloring->colors[larray[i]]; 462912c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4630d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 463112c595b3SBarry Smith a->coloring = ocoloring; 463212c595b3SBarry Smith } 4633cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4634cc8ba8e1SBarry Smith } 4635cc8ba8e1SBarry Smith 4636ee4f033dSBarry Smith #undef __FUNCT__ 4637ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 463897f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4639ee4f033dSBarry Smith { 4640ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4641d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 464254f21887SBarry Smith MatScalar *v = a->a; 464354f21887SBarry Smith PetscScalar *values = (PetscScalar*)advalues; 464408b6dcc0SBarry Smith ISColoringValue *color; 4645ee4f033dSBarry Smith 4646ee4f033dSBarry Smith PetscFunctionBegin; 4647e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4648ee4f033dSBarry Smith color = a->coloring->colors; 4649ee4f033dSBarry Smith /* loop over rows */ 4650ee4f033dSBarry Smith for (i=0; i<m; i++) { 4651ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4652ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 46532205254eSKarl Rupp for (j=0; j<nz; j++) *v++ = values[color[*jj++]]; 4654ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4655cc8ba8e1SBarry Smith } 4656cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4657cc8ba8e1SBarry Smith } 465836db0b34SBarry Smith 4659acf2f550SJed Brown #undef __FUNCT__ 4660acf2f550SJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal" 4661acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4662acf2f550SJed Brown { 4663acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4664acf2f550SJed Brown PetscErrorCode ierr; 4665acf2f550SJed Brown 4666acf2f550SJed Brown PetscFunctionBegin; 4667acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4668acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 46692205254eSKarl Rupp 4670acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4671acf2f550SJed Brown PetscFunctionReturn(0); 4672acf2f550SJed Brown } 4673acf2f550SJed Brown 467481824310SBarry Smith /* 467581824310SBarry Smith Special version for direct calls from Fortran 467681824310SBarry Smith */ 4677b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h> 467881824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 467981824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 468081824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 468181824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 468281824310SBarry Smith #endif 468381824310SBarry Smith 468481824310SBarry Smith /* Change these macros so can be used in void function */ 468581824310SBarry Smith #undef CHKERRQ 4686ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 468781824310SBarry Smith #undef SETERRQ2 4688e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 46894994cf47SJed Brown #undef SETERRQ3 46904994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 469181824310SBarry Smith 469281824310SBarry Smith #undef __FUNCT__ 469381824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 46948cc058d9SJed 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) 469581824310SBarry Smith { 469681824310SBarry Smith Mat A = *AA; 469781824310SBarry Smith PetscInt m = *mm, n = *nn; 469881824310SBarry Smith InsertMode is = *isis; 469981824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 470081824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 470181824310SBarry Smith PetscInt *imax,*ai,*ailen; 470281824310SBarry Smith PetscErrorCode ierr; 470381824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 470454f21887SBarry Smith MatScalar *ap,value,*aa; 4705ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4706ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 470781824310SBarry Smith 470881824310SBarry Smith PetscFunctionBegin; 47094994cf47SJed Brown MatCheckPreallocated(A,1); 471081824310SBarry Smith imax = a->imax; 471181824310SBarry Smith ai = a->i; 471281824310SBarry Smith ailen = a->ilen; 471381824310SBarry Smith aj = a->j; 471481824310SBarry Smith aa = a->a; 471581824310SBarry Smith 471681824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 471781824310SBarry Smith row = im[k]; 471881824310SBarry Smith if (row < 0) continue; 471981824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4720ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 472181824310SBarry Smith #endif 472281824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 472381824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 472481824310SBarry Smith low = 0; 472581824310SBarry Smith high = nrow; 472681824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 472781824310SBarry Smith if (in[l] < 0) continue; 472881824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4729ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 473081824310SBarry Smith #endif 473181824310SBarry Smith col = in[l]; 47322205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 47332205254eSKarl Rupp else value = v[k + l*m]; 47342205254eSKarl Rupp 473581824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 473681824310SBarry Smith 47372205254eSKarl Rupp if (col <= lastcol) low = 0; 47382205254eSKarl Rupp else high = nrow; 473981824310SBarry Smith lastcol = col; 474081824310SBarry Smith while (high-low > 5) { 474181824310SBarry Smith t = (low+high)/2; 474281824310SBarry Smith if (rp[t] > col) high = t; 474381824310SBarry Smith else low = t; 474481824310SBarry Smith } 474581824310SBarry Smith for (i=low; i<high; i++) { 474681824310SBarry Smith if (rp[i] > col) break; 474781824310SBarry Smith if (rp[i] == col) { 474881824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 474981824310SBarry Smith else ap[i] = value; 475081824310SBarry Smith goto noinsert; 475181824310SBarry Smith } 475281824310SBarry Smith } 475381824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 475481824310SBarry Smith if (nonew == 1) goto noinsert; 4755ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4756fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 475781824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 475881824310SBarry Smith /* shift up all the later entries in this row */ 475981824310SBarry Smith for (ii=N; ii>=i; ii--) { 476081824310SBarry Smith rp[ii+1] = rp[ii]; 476181824310SBarry Smith ap[ii+1] = ap[ii]; 476281824310SBarry Smith } 476381824310SBarry Smith rp[i] = col; 476481824310SBarry Smith ap[i] = value; 476581824310SBarry Smith noinsert:; 476681824310SBarry Smith low = i + 1; 476781824310SBarry Smith } 476881824310SBarry Smith ailen[row] = nrow; 476981824310SBarry Smith } 477081824310SBarry Smith A->same_nonzero = PETSC_FALSE; 477181824310SBarry Smith PetscFunctionReturnVoid(); 477281824310SBarry Smith } 47739f7953f8SBarry Smith 477462298a1eSBarry Smith 4775