1d5d45c9bSBarry Smith /* 23369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 3d5d45c9bSBarry Smith matrix storage format. 4d5d45c9bSBarry Smith */ 53369ce9aSBarry Smith 6c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 7c6db04a5SJed Brown #include <petscblaslapack.h> 8c6db04a5SJed Brown #include <petscbt.h> 9af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 100716a85fSBarry Smith 114099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A) 124099cc6bSBarry Smith { 134099cc6bSBarry Smith PetscErrorCode ierr; 144099cc6bSBarry Smith PetscBool flg; 154099cc6bSBarry Smith char type[256]; 164099cc6bSBarry Smith 174099cc6bSBarry Smith PetscFunctionBegin; 181e1ea65dSPierre Jolivet ierr = PetscObjectOptionsBegin((PetscObject)A);CHKERRQ(ierr); 195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg)); 205f80ce2aSJacob Faibussowitsch if (flg) CHKERRQ(MatSeqAIJSetType(A,type)); 214099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 224099cc6bSBarry Smith PetscFunctionReturn(0); 234099cc6bSBarry Smith } 244099cc6bSBarry Smith 25857cbf51SRichard Tran Mills PetscErrorCode MatGetColumnReductions_SeqAIJ(Mat A,PetscInt type,PetscReal *reductions) 260716a85fSBarry Smith { 270716a85fSBarry Smith PetscInt i,m,n; 280716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 290716a85fSBarry Smith 300716a85fSBarry Smith PetscFunctionBegin; 315f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(A,&m,&n)); 325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(reductions,n)); 330716a85fSBarry Smith if (type == NORM_2) { 340716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 35a873a8cdSSam Reynolds reductions[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 360716a85fSBarry Smith } 370716a85fSBarry Smith } else if (type == NORM_1) { 380716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 39a873a8cdSSam Reynolds reductions[aij->j[i]] += PetscAbsScalar(aij->a[i]); 400716a85fSBarry Smith } 410716a85fSBarry Smith } else if (type == NORM_INFINITY) { 420716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 43a873a8cdSSam Reynolds reductions[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),reductions[aij->j[i]]); 440716a85fSBarry Smith } 45857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 46a873a8cdSSam Reynolds for (i=0; i<aij->i[m]; i++) { 47857cbf51SRichard Tran Mills reductions[aij->j[i]] += PetscRealPart(aij->a[i]); 48a873a8cdSSam Reynolds } 49857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 50857cbf51SRichard Tran Mills for (i=0; i<aij->i[m]; i++) { 51857cbf51SRichard Tran Mills reductions[aij->j[i]] += PetscImaginaryPart(aij->a[i]); 52857cbf51SRichard Tran Mills } 53857cbf51SRichard Tran Mills } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown reduction type"); 540716a85fSBarry Smith 550716a85fSBarry Smith if (type == NORM_2) { 56a873a8cdSSam Reynolds for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 57857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 58a873a8cdSSam Reynolds for (i=0; i<n; i++) reductions[i] /= m; 590716a85fSBarry Smith } 600716a85fSBarry Smith PetscFunctionReturn(0); 610716a85fSBarry Smith } 620716a85fSBarry Smith 633a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 643a062f41SBarry Smith { 653a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 663a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 673a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 683a062f41SBarry Smith PetscInt *rows; 693a062f41SBarry Smith 703a062f41SBarry Smith PetscFunctionBegin; 713a062f41SBarry Smith for (i=0; i<m; i++) { 723a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 733a062f41SBarry Smith cnt++; 743a062f41SBarry Smith } 753a062f41SBarry Smith } 765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(cnt,&rows)); 773a062f41SBarry Smith cnt = 0; 783a062f41SBarry Smith for (i=0; i<m; i++) { 793a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 803a062f41SBarry Smith rows[cnt] = i; 813a062f41SBarry Smith cnt++; 823a062f41SBarry Smith } 833a062f41SBarry Smith } 845f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is)); 853a062f41SBarry Smith PetscFunctionReturn(0); 863a062f41SBarry Smith } 873a062f41SBarry Smith 88f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 896ce1633cSBarry Smith { 906ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 91fff043a9SJunchao Zhang const MatScalar *aa; 926ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 93b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 946ce1633cSBarry Smith PetscInt *rows; 956ce1633cSBarry Smith 966ce1633cSBarry Smith PetscFunctionBegin; 975f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 985f80ce2aSJacob Faibussowitsch CHKERRQ(MatMarkDiagonal_SeqAIJ(A)); 996ce1633cSBarry Smith diag = a->diag; 1006ce1633cSBarry Smith for (i=0; i<m; i++) { 101b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1026ce1633cSBarry Smith cnt++; 1036ce1633cSBarry Smith } 1046ce1633cSBarry Smith } 1055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(cnt,&rows)); 1066ce1633cSBarry Smith cnt = 0; 1076ce1633cSBarry Smith for (i=0; i<m; i++) { 108b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1096ce1633cSBarry Smith rows[cnt++] = i; 1106ce1633cSBarry Smith } 1116ce1633cSBarry Smith } 112f1f41ecbSJed Brown *nrows = cnt; 113f1f41ecbSJed Brown *zrows = rows; 1145f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 115f1f41ecbSJed Brown PetscFunctionReturn(0); 116f1f41ecbSJed Brown } 117f1f41ecbSJed Brown 118f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 119f1f41ecbSJed Brown { 120f1f41ecbSJed Brown PetscInt nrows,*rows; 121f1f41ecbSJed Brown 122f1f41ecbSJed Brown PetscFunctionBegin; 1230298fd71SBarry Smith *zrows = NULL; 1245f80ce2aSJacob Faibussowitsch CHKERRQ(MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows)); 1255f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows)); 1266ce1633cSBarry Smith PetscFunctionReturn(0); 1276ce1633cSBarry Smith } 1286ce1633cSBarry Smith 129b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 130b3a44c85SBarry Smith { 131b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 132b3a44c85SBarry Smith const MatScalar *aa; 133b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 134b3a44c85SBarry Smith const PetscInt *ii; 135b3a44c85SBarry Smith PetscInt n,i,j,*rows; 136b3a44c85SBarry Smith 137b3a44c85SBarry Smith PetscFunctionBegin; 1385f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 139f4259b30SLisandro Dalcin *keptrows = NULL; 140b3a44c85SBarry Smith ii = a->i; 141b3a44c85SBarry Smith for (i=0; i<m; i++) { 142b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 143b3a44c85SBarry Smith if (!n) { 144b3a44c85SBarry Smith cnt++; 145b3a44c85SBarry Smith goto ok1; 146b3a44c85SBarry Smith } 1472e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 148b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 149b3a44c85SBarry Smith } 150b3a44c85SBarry Smith cnt++; 151b3a44c85SBarry Smith ok1:; 152b3a44c85SBarry Smith } 1532e5835c6SStefano Zampini if (!cnt) { 1545f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 1552e5835c6SStefano Zampini PetscFunctionReturn(0); 1562e5835c6SStefano Zampini } 1575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(A->rmap->n-cnt,&rows)); 158b3a44c85SBarry Smith cnt = 0; 159b3a44c85SBarry Smith for (i=0; i<m; i++) { 160b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 161b3a44c85SBarry Smith if (!n) continue; 1622e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 163b3a44c85SBarry Smith if (aa[j] != 0.0) { 164b3a44c85SBarry Smith rows[cnt++] = i; 165b3a44c85SBarry Smith break; 166b3a44c85SBarry Smith } 167b3a44c85SBarry Smith } 168b3a44c85SBarry Smith } 1695f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 1705f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows)); 171b3a44c85SBarry Smith PetscFunctionReturn(0); 172b3a44c85SBarry Smith } 173b3a44c85SBarry Smith 1747087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 17579299369SBarry Smith { 17679299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 17799e65526SBarry Smith PetscInt i,m = Y->rmap->n; 17899e65526SBarry Smith const PetscInt *diag; 1792e5835c6SStefano Zampini MatScalar *aa; 18099e65526SBarry Smith const PetscScalar *v; 181ace3abfcSBarry Smith PetscBool missing; 18279299369SBarry Smith 18379299369SBarry Smith PetscFunctionBegin; 18409f38230SBarry Smith if (Y->assembled) { 1855f80ce2aSJacob Faibussowitsch CHKERRQ(MatMissingDiagonal_SeqAIJ(Y,&missing,NULL)); 18609f38230SBarry Smith if (!missing) { 18779299369SBarry Smith diag = aij->diag; 1885f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(D,&v)); 1895f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(Y,&aa)); 19079299369SBarry Smith if (is == INSERT_VALUES) { 19179299369SBarry Smith for (i=0; i<m; i++) { 19279299369SBarry Smith aa[diag[i]] = v[i]; 19379299369SBarry Smith } 19479299369SBarry Smith } else { 19579299369SBarry Smith for (i=0; i<m; i++) { 19679299369SBarry Smith aa[diag[i]] += v[i]; 19779299369SBarry Smith } 19879299369SBarry Smith } 1995f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(Y,&aa)); 2005f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(D,&v)); 20179299369SBarry Smith PetscFunctionReturn(0); 20279299369SBarry Smith } 2035f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(Y)); 20409f38230SBarry Smith } 2055f80ce2aSJacob Faibussowitsch CHKERRQ(MatDiagonalSet_Default(Y,D,is)); 20609f38230SBarry Smith PetscFunctionReturn(0); 20709f38230SBarry Smith } 20879299369SBarry Smith 2091a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 21017ab2063SBarry Smith { 211416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21297f1f81fSBarry Smith PetscInt i,ishift; 21317ab2063SBarry Smith 2143a40ed3dSBarry Smith PetscFunctionBegin; 215d0f46423SBarry Smith *m = A->rmap->n; 2163a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 217bfeeae90SHong Zhang ishift = 0; 21853e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2195f80ce2aSJacob Faibussowitsch CHKERRQ(MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja)); 220bfeeae90SHong Zhang } else if (oshift == 1) { 2211a83f524SJed Brown PetscInt *tia; 222d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2233b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 2245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(A->rmap->n+1,&tia)); 2251a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2261a83f524SJed Brown *ia = tia; 227ecc77c7aSBarry Smith if (ja) { 2281a83f524SJed Brown PetscInt *tja; 2295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz+1,&tja)); 2301a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2311a83f524SJed Brown *ja = tja; 232ecc77c7aSBarry Smith } 2336945ee14SBarry Smith } else { 234ecc77c7aSBarry Smith *ia = a->i; 235ecc77c7aSBarry Smith if (ja) *ja = a->j; 236a2ce50c7SBarry Smith } 2373a40ed3dSBarry Smith PetscFunctionReturn(0); 238a2744918SBarry Smith } 239a2744918SBarry Smith 2401a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2416945ee14SBarry Smith { 2423a40ed3dSBarry Smith PetscFunctionBegin; 2433a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 244bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 2455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(*ia)); 2465f80ce2aSJacob Faibussowitsch if (ja) CHKERRQ(PetscFree(*ja)); 247bcd2baecSBarry Smith } 2483a40ed3dSBarry Smith PetscFunctionReturn(0); 24917ab2063SBarry Smith } 25017ab2063SBarry Smith 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; 254d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 25597f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2563b2fbd54SBarry Smith 2573a40ed3dSBarry Smith PetscFunctionBegin; 258899cda47SBarry Smith *nn = n; 2593a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2603b2fbd54SBarry Smith if (symmetric) { 2615f80ce2aSJacob Faibussowitsch CHKERRQ(MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja)); 2623b2fbd54SBarry Smith } else { 2635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(n,&collengths)); 2645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(n+1,&cia)); 2655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz,&cja)); 2663b2fbd54SBarry Smith jj = a->j; 2673b2fbd54SBarry Smith for (i=0; i<nz; i++) { 268bfeeae90SHong Zhang collengths[jj[i]]++; 2693b2fbd54SBarry Smith } 2703b2fbd54SBarry Smith cia[0] = oshift; 2713b2fbd54SBarry Smith for (i=0; i<n; i++) { 2723b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2733b2fbd54SBarry Smith } 2745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(collengths,n)); 2753b2fbd54SBarry Smith jj = a->j; 276a93ec695SBarry Smith for (row=0; row<m; row++) { 277a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 278a93ec695SBarry Smith for (i=0; i<mr; i++) { 279bfeeae90SHong Zhang col = *jj++; 2802205254eSKarl Rupp 2813b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2823b2fbd54SBarry Smith } 2833b2fbd54SBarry Smith } 2845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(collengths)); 2853b2fbd54SBarry Smith *ia = cia; *ja = cja; 2863b2fbd54SBarry Smith } 2873a40ed3dSBarry Smith PetscFunctionReturn(0); 2883b2fbd54SBarry Smith } 2893b2fbd54SBarry Smith 2901a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2913b2fbd54SBarry Smith { 2923a40ed3dSBarry Smith PetscFunctionBegin; 2933a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2943b2fbd54SBarry Smith 2955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(*ia)); 2965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(*ja)); 2973a40ed3dSBarry Smith PetscFunctionReturn(0); 2983b2fbd54SBarry Smith } 2993b2fbd54SBarry Smith 3007cee066cSHong Zhang /* 3017cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3027cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 303040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3047cee066cSHong Zhang */ 3057cee066cSHong 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) 3067cee066cSHong Zhang { 3077cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3087cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 309071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3107cee066cSHong Zhang PetscInt *cspidx; 311071fcb05SBarry Smith const PetscInt *jj; 3127cee066cSHong Zhang 3137cee066cSHong Zhang PetscFunctionBegin; 3147cee066cSHong Zhang *nn = n; 3157cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 316625f6d37SHong Zhang 3175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(n,&collengths)); 3185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(n+1,&cia)); 3195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz,&cja)); 3205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz,&cspidx)); 3217cee066cSHong Zhang jj = a->j; 3227cee066cSHong Zhang for (i=0; i<nz; i++) { 3237cee066cSHong Zhang collengths[jj[i]]++; 3247cee066cSHong Zhang } 3257cee066cSHong Zhang cia[0] = oshift; 3267cee066cSHong Zhang for (i=0; i<n; i++) { 3277cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3287cee066cSHong Zhang } 3295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(collengths,n)); 3307cee066cSHong Zhang jj = a->j; 3317cee066cSHong Zhang for (row=0; row<m; row++) { 3327cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3337cee066cSHong Zhang for (i=0; i<mr; i++) { 3347cee066cSHong Zhang col = *jj++; 335071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 336071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 337071fcb05SBarry Smith cja[tmp] = row + oshift; 3387cee066cSHong Zhang } 3397cee066cSHong Zhang } 3405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(collengths)); 341071fcb05SBarry Smith *ia = cia; 342071fcb05SBarry Smith *ja = cja; 3437cee066cSHong Zhang *spidx = cspidx; 3447cee066cSHong Zhang PetscFunctionReturn(0); 3457cee066cSHong Zhang } 3467cee066cSHong Zhang 3477cee066cSHong 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) 3487cee066cSHong Zhang { 3497cee066cSHong Zhang PetscFunctionBegin; 3505f80ce2aSJacob Faibussowitsch CHKERRQ(MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done)); 3515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(*spidx)); 3527cee066cSHong Zhang PetscFunctionReturn(0); 3537cee066cSHong Zhang } 3547cee066cSHong Zhang 35587d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 35687d4246cSBarry Smith { 35787d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 35887d4246cSBarry Smith PetscInt *ai = a->i; 359fff043a9SJunchao Zhang PetscScalar *aa; 36087d4246cSBarry Smith 36187d4246cSBarry Smith PetscFunctionBegin; 3625f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 3635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(aa+ai[row],v,ai[row+1]-ai[row])); 3645f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 36587d4246cSBarry Smith PetscFunctionReturn(0); 36687d4246cSBarry Smith } 36787d4246cSBarry Smith 368bd04181cSBarry Smith /* 369bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 370bd04181cSBarry Smith 371bd04181cSBarry Smith - a single row of values is set with each call 372bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 373bd04181cSBarry Smith - the values are always added to the matrix, not set 374bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 375bd04181cSBarry Smith 3761f763a69SBarry Smith This does NOT assume the global column indices are sorted 377bd04181cSBarry Smith 3781f763a69SBarry Smith */ 379bd04181cSBarry Smith 380af0996ceSBarry Smith #include <petsc/private/isimpl.h> 381189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 382189e4007SBarry Smith { 383189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3841f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 3851f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 3861f763a69SBarry Smith PetscInt lastcol = -1; 387fff043a9SJunchao Zhang MatScalar *ap,value,*aa; 388189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 389189e4007SBarry Smith 390fff043a9SJunchao Zhang PetscFunctionBegin; 3915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 392f38dd0b8SBarry Smith row = ridx[im[0]]; 3931f763a69SBarry Smith rp = aj + ai[row]; 3941f763a69SBarry Smith ap = aa + ai[row]; 3951f763a69SBarry Smith nrow = ailen[row]; 396189e4007SBarry Smith low = 0; 397189e4007SBarry Smith high = nrow; 398189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 399189e4007SBarry Smith col = cidx[in[l]]; 400f38dd0b8SBarry Smith value = v[l]; 401189e4007SBarry Smith 402189e4007SBarry Smith if (col <= lastcol) low = 0; 403189e4007SBarry Smith else high = nrow; 404189e4007SBarry Smith lastcol = col; 405189e4007SBarry Smith while (high-low > 5) { 406189e4007SBarry Smith t = (low+high)/2; 407189e4007SBarry Smith if (rp[t] > col) high = t; 408189e4007SBarry Smith else low = t; 409189e4007SBarry Smith } 410189e4007SBarry Smith for (i=low; i<high; i++) { 411189e4007SBarry Smith if (rp[i] == col) { 4121f763a69SBarry Smith ap[i] += value; 413189e4007SBarry Smith low = i + 1; 4141f763a69SBarry Smith break; 415189e4007SBarry Smith } 416189e4007SBarry Smith } 417189e4007SBarry Smith } 4185f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 419f38dd0b8SBarry Smith return 0; 420189e4007SBarry Smith } 421189e4007SBarry Smith 42297f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 42317ab2063SBarry Smith { 424416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 425e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 42697f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 427e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 428ce496241SStefano Zampini MatScalar *ap=NULL,value=0.0,*aa; 429ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 430ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 43117ab2063SBarry Smith 4323a40ed3dSBarry Smith PetscFunctionBegin; 4335f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 43417ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 435416022c9SBarry Smith row = im[k]; 4365ef9f2a5SBarry Smith if (row < 0) continue; 4376bdcaf15SBarry Smith PetscCheck(row < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,row,A->rmap->n-1); 438720833daSHong Zhang rp = aj + ai[row]; 439876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 44017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 441416022c9SBarry Smith low = 0; 442c71e6ed7SBarry Smith high = nrow; 44317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4445ef9f2a5SBarry Smith if (in[l] < 0) continue; 4456bdcaf15SBarry Smith PetscCheck(in[l] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,in[l],A->cmap->n-1); 446bfeeae90SHong Zhang col = in[l]; 447071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 448071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 44936db0b34SBarry Smith 4502205254eSKarl Rupp if (col <= lastcol) low = 0; 4512205254eSKarl Rupp else high = nrow; 452e2ee6c50SBarry Smith lastcol = col; 453416022c9SBarry Smith while (high-low > 5) { 454416022c9SBarry Smith t = (low+high)/2; 455416022c9SBarry Smith if (rp[t] > col) high = t; 456416022c9SBarry Smith else low = t; 45717ab2063SBarry Smith } 458416022c9SBarry Smith for (i=low; i<high; i++) { 45917ab2063SBarry Smith if (rp[i] > col) break; 46017ab2063SBarry Smith if (rp[i] == col) { 461876c6284SHong Zhang if (!A->structure_only) { 4620c0d7e18SFande Kong if (is == ADD_VALUES) { 4630c0d7e18SFande Kong ap[i] += value; 4640c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4650c0d7e18SFande Kong } 46617ab2063SBarry Smith else ap[i] = value; 467720833daSHong Zhang } 468e44c0bd4SBarry Smith low = i + 1; 46917ab2063SBarry Smith goto noinsert; 47017ab2063SBarry Smith } 47117ab2063SBarry Smith } 472dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 473c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 4742c71b3e2SJacob Faibussowitsch PetscCheckFalse(nonew == -1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%" PetscInt_FMT ",%" PetscInt_FMT ") in the matrix",row,col); 475720833daSHong Zhang if (A->structure_only) { 476876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 477720833daSHong Zhang } else { 478fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 479720833daSHong Zhang } 480c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 481416022c9SBarry Smith /* shift up all the later entries in this row */ 4825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraymove(rp+i+1,rp+i,N-i+1)); 48317ab2063SBarry Smith rp[i] = col; 484580bdb30SBarry Smith if (!A->structure_only) { 4855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraymove(ap+i+1,ap+i,N-i+1)); 486580bdb30SBarry Smith ap[i] = value; 487580bdb30SBarry Smith } 488416022c9SBarry Smith low = i + 1; 489e56f5c9eSBarry Smith A->nonzerostate++; 490e44c0bd4SBarry Smith noinsert:; 49117ab2063SBarry Smith } 49217ab2063SBarry Smith ailen[row] = nrow; 49317ab2063SBarry Smith } 4945f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 4953a40ed3dSBarry Smith PetscFunctionReturn(0); 49617ab2063SBarry Smith } 49717ab2063SBarry Smith 49819b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 49919b08ed1SBarry Smith { 50019b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 50119b08ed1SBarry Smith PetscInt *rp,k,row; 50219b08ed1SBarry Smith PetscInt *ai = a->i; 50319b08ed1SBarry Smith PetscInt *aj = a->j; 504fff043a9SJunchao Zhang MatScalar *aa,*ap; 50519b08ed1SBarry Smith 50619b08ed1SBarry Smith PetscFunctionBegin; 507*28b400f6SJacob Faibussowitsch PetscCheck(!A->was_assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 5082c71b3e2SJacob Faibussowitsch PetscCheckFalse(m*n+a->nz > a->maxnz,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of entries in matrix will be larger than maximum nonzeros allocated for %" PetscInt_FMT " in MatSeqAIJSetTotalPreallocation()",a->maxnz); 509fff043a9SJunchao Zhang 5105f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 51119b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 51219b08ed1SBarry Smith row = im[k]; 51319b08ed1SBarry Smith rp = aj + ai[row]; 51419b08ed1SBarry Smith ap = aa + ai[row]; 51519b08ed1SBarry Smith 5165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(rp,in,n*sizeof(PetscInt))); 51719b08ed1SBarry Smith if (!A->structure_only) { 51819b08ed1SBarry Smith if (v) { 5195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(ap,v,n*sizeof(PetscScalar))); 52019b08ed1SBarry Smith v += n; 52119b08ed1SBarry Smith } else { 5225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemzero(ap,n*sizeof(PetscScalar))); 52319b08ed1SBarry Smith } 52419b08ed1SBarry Smith } 52519b08ed1SBarry Smith a->ilen[row] = n; 52619b08ed1SBarry Smith a->imax[row] = n; 52719b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 52819b08ed1SBarry Smith a->nz += n; 52919b08ed1SBarry Smith } 5305f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 53119b08ed1SBarry Smith PetscFunctionReturn(0); 53219b08ed1SBarry Smith } 53319b08ed1SBarry Smith 53419b08ed1SBarry Smith /*@ 53519b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 53619b08ed1SBarry Smith 53719b08ed1SBarry Smith Input Parameters: 53819b08ed1SBarry Smith + A - the SeqAIJ matrix 53919b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 54019b08ed1SBarry Smith 54119b08ed1SBarry Smith Level: advanced 54219b08ed1SBarry Smith 54319b08ed1SBarry Smith Notes: 54419b08ed1SBarry Smith This can be called if you will be provided the matrix row by row (from row zero) with sorted column indices for each row. 54519b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 54619b08ed1SBarry Smith as always with multiple matrix assemblies. 54719b08ed1SBarry Smith 54819b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 54919b08ed1SBarry Smith @*/ 55019b08ed1SBarry Smith 55119b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 55219b08ed1SBarry Smith { 55319b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 55419b08ed1SBarry Smith 55519b08ed1SBarry Smith PetscFunctionBegin; 5565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(A->rmap)); 5575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(A->cmap)); 55819b08ed1SBarry Smith a->maxnz = nztotal; 55919b08ed1SBarry Smith if (!a->imax) { 5605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(A->rmap->n,&a->imax)); 5615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt))); 56219b08ed1SBarry Smith } 56319b08ed1SBarry Smith if (!a->ilen) { 5645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(A->rmap->n,&a->ilen)); 5655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt))); 56619b08ed1SBarry Smith } else { 5675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt))); 56819b08ed1SBarry Smith } 56919b08ed1SBarry Smith 57019b08ed1SBarry Smith /* allocate the matrix space */ 57119b08ed1SBarry Smith if (A->structure_only) { 5725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nztotal,&a->j)); 5735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(A->rmap->n+1,&a->i)); 5745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt))); 57519b08ed1SBarry Smith } else { 5765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i)); 5775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)))); 57819b08ed1SBarry Smith } 57919b08ed1SBarry Smith a->i[0] = 0; 58019b08ed1SBarry Smith if (A->structure_only) { 58119b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 58219b08ed1SBarry Smith a->free_a = PETSC_FALSE; 58319b08ed1SBarry Smith } else { 58419b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 58519b08ed1SBarry Smith a->free_a = PETSC_TRUE; 58619b08ed1SBarry Smith } 58719b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 58819b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 58919b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 59019b08ed1SBarry Smith PetscFunctionReturn(0); 59119b08ed1SBarry Smith } 59219b08ed1SBarry Smith 593071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 594071fcb05SBarry Smith { 595071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 596071fcb05SBarry Smith PetscInt *rp,k,row; 597071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 598071fcb05SBarry Smith PetscInt *aj = a->j; 599fff043a9SJunchao Zhang MatScalar *aa,*ap; 600071fcb05SBarry Smith 601071fcb05SBarry Smith PetscFunctionBegin; 6025f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 603071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 604071fcb05SBarry Smith row = im[k]; 6056bdcaf15SBarry Smith PetscCheck(n <= a->imax[row],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Preallocation for row %" PetscInt_FMT " does not match number of columns provided",n); 606071fcb05SBarry Smith rp = aj + ai[row]; 607071fcb05SBarry Smith ap = aa + ai[row]; 608071fcb05SBarry Smith if (!A->was_assembled) { 6095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(rp,in,n*sizeof(PetscInt))); 610071fcb05SBarry Smith } 611071fcb05SBarry Smith if (!A->structure_only) { 612071fcb05SBarry Smith if (v) { 6135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(ap,v,n*sizeof(PetscScalar))); 614071fcb05SBarry Smith v += n; 615071fcb05SBarry Smith } else { 6165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemzero(ap,n*sizeof(PetscScalar))); 617071fcb05SBarry Smith } 618071fcb05SBarry Smith } 619071fcb05SBarry Smith ailen[row] = n; 620071fcb05SBarry Smith a->nz += n; 621071fcb05SBarry Smith } 6225f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 623071fcb05SBarry Smith PetscFunctionReturn(0); 624071fcb05SBarry Smith } 625071fcb05SBarry Smith 626a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6277eb43aa7SLois Curfman McInnes { 6287eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 62997f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 63097f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 631fff043a9SJunchao Zhang MatScalar *ap,*aa; 6327eb43aa7SLois Curfman McInnes 6333a40ed3dSBarry Smith PetscFunctionBegin; 6345f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 6357eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6367eb43aa7SLois Curfman McInnes row = im[k]; 63754c59aa7SJacob Faibussowitsch if (row < 0) {v += n; continue;} /* negative row */ 63854c59aa7SJacob Faibussowitsch PetscCheck(row < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,row,A->rmap->n-1); 639bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6407eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6417eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 64254c59aa7SJacob Faibussowitsch if (in[l] < 0) {v++; continue;} /* negative column */ 64354c59aa7SJacob Faibussowitsch PetscCheck(in[l] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,in[l],A->cmap->n-1); 644bfeeae90SHong Zhang col = in[l]; 6457eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6467eb43aa7SLois Curfman McInnes while (high-low > 5) { 6477eb43aa7SLois Curfman McInnes t = (low+high)/2; 6487eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6497eb43aa7SLois Curfman McInnes else low = t; 6507eb43aa7SLois Curfman McInnes } 6517eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6527eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6537eb43aa7SLois Curfman McInnes if (rp[i] == col) { 654b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6557eb43aa7SLois Curfman McInnes goto finished; 6567eb43aa7SLois Curfman McInnes } 6577eb43aa7SLois Curfman McInnes } 65897e567efSBarry Smith *v++ = 0.0; 6597eb43aa7SLois Curfman McInnes finished:; 6607eb43aa7SLois Curfman McInnes } 6617eb43aa7SLois Curfman McInnes } 6625f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 6633a40ed3dSBarry Smith PetscFunctionReturn(0); 6647eb43aa7SLois Curfman McInnes } 6657eb43aa7SLois Curfman McInnes 6663ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 66717ab2063SBarry Smith { 6683ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 669c898d852SStefano Zampini const PetscScalar *av; 6703ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 6713ea6fe3dSLisandro Dalcin PetscInt *rowlens; 67217ab2063SBarry Smith 6733a40ed3dSBarry Smith PetscFunctionBegin; 6745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerSetUp(viewer)); 6752205254eSKarl Rupp 6763ea6fe3dSLisandro Dalcin M = mat->rmap->N; 6773ea6fe3dSLisandro Dalcin N = mat->cmap->N; 6783ea6fe3dSLisandro Dalcin m = mat->rmap->n; 6793ea6fe3dSLisandro Dalcin nz = A->nz; 680416022c9SBarry Smith 6813ea6fe3dSLisandro Dalcin /* write matrix header */ 6823ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 6833ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 6845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT)); 685416022c9SBarry Smith 6863ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 6875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m,&rowlens)); 6883ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 6895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT)); 6905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(rowlens)); 6913ea6fe3dSLisandro Dalcin /* store column indices */ 6925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT)); 693416022c9SBarry Smith /* store nonzero values */ 6945f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(mat,&av)); 6955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR)); 6965f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(mat,&av)); 697b37d52dbSMark F. Adams 6983ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 6995f80ce2aSJacob Faibussowitsch CHKERRQ(MatView_Binary_BlockSizes(mat,viewer)); 7003a40ed3dSBarry Smith PetscFunctionReturn(0); 70117ab2063SBarry Smith } 702416022c9SBarry Smith 7037dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7047dc0baabSHong Zhang { 7057dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7067dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7077dc0baabSHong Zhang 7087dc0baabSHong Zhang PetscFunctionBegin; 7095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 7107dc0baabSHong Zhang for (i=0; i<m; i++) { 7115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i)); 7127dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ") ",a->j[k])); 7147dc0baabSHong Zhang } 7155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 7167dc0baabSHong Zhang } 7175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 7187dc0baabSHong Zhang PetscFunctionReturn(0); 7197dc0baabSHong Zhang } 7207dc0baabSHong Zhang 72109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 722cd155464SBarry Smith 723dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 724416022c9SBarry Smith { 725416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 726c898d852SStefano Zampini const PetscScalar *av; 72760e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 728e060cb09SBarry Smith const char *name; 729f3ef73ceSBarry Smith PetscViewerFormat format; 73017ab2063SBarry Smith 7313a40ed3dSBarry Smith PetscFunctionBegin; 7327dc0baabSHong Zhang if (A->structure_only) { 7335f80ce2aSJacob Faibussowitsch CHKERRQ(MatView_SeqAIJ_ASCII_structonly(A,viewer)); 7347dc0baabSHong Zhang PetscFunctionReturn(0); 7357dc0baabSHong Zhang } 73643e49210SHong Zhang 7375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer,&format)); 7382e5835c6SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 7392e5835c6SStefano Zampini 740c898d852SStefano Zampini /* trigger copy to CPU if needed */ 7415f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&av)); 7425f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&av)); 74371c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 74497f1f81fSBarry Smith PetscInt nofinalvalue = 0; 74560e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 746c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 747d00d2cf4SBarry Smith nofinalvalue = 1; 748d00d2cf4SBarry Smith } 7495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 7505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",m,A->cmap->n)); 7515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %" PetscInt_FMT " \n",a->nz)); 752fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 7535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"zzz = zeros(%" PetscInt_FMT ",4);\n",a->nz+nofinalvalue)); 754fbfe6fa7SJed Brown #else 7555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"zzz = zeros(%" PetscInt_FMT ",3);\n",a->nz+nofinalvalue)); 756fbfe6fa7SJed Brown #endif 7575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"zzz = [\n")); 75817ab2063SBarry Smith 75917ab2063SBarry Smith for (i=0; i<m; i++) { 76060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 761aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 7625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 76317ab2063SBarry Smith #else 7645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %18.16e\n",i+1,a->j[j]+1,(double)a->a[j])); 76517ab2063SBarry Smith #endif 76617ab2063SBarry Smith } 76717ab2063SBarry Smith } 768d00d2cf4SBarry Smith if (nofinalvalue) { 769c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 7705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %18.16e %18.16e\n",m,A->cmap->n,0.,0.)); 771c337ccceSJed Brown #else 7725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %18.16e\n",m,A->cmap->n,0.0)); 773c337ccceSJed Brown #endif 774d00d2cf4SBarry Smith } 7755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetName((PetscObject)A,&name)); 7765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name)); 7775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 778fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 7795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 78044cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 7815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i)); 78260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 783aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 78436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 7855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 78636db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 7875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]))); 78836db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 7895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]))); 7906831982aSBarry Smith } 79144cd7ae7SLois Curfman McInnes #else 7925f80ce2aSJacob Faibussowitsch if (a->a[j] != 0.0) CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j])); 79344cd7ae7SLois Curfman McInnes #endif 79444cd7ae7SLois Curfman McInnes } 7955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 79644cd7ae7SLois Curfman McInnes } 7975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 798fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 79997f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 8005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 8015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m+1,&sptr)); 802496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 803496be53dSLois Curfman McInnes sptr[i] = nzd+1; 80460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 805496be53dSLois Curfman McInnes if (a->j[j] >= i) { 806aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 80736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 808496be53dSLois Curfman McInnes #else 809496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 810496be53dSLois Curfman McInnes #endif 811496be53dSLois Curfman McInnes } 812496be53dSLois Curfman McInnes } 813496be53dSLois Curfman McInnes } 8142e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 8155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT "\n\n",m,nzd)); 8162e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8172205254eSKarl Rupp if (i+4<m) { 8185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5])); 8192205254eSKarl Rupp } else if (i+3<m) { 8205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4])); 8212205254eSKarl Rupp } else if (i+2<m) { 8225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3])); 8232205254eSKarl Rupp } else if (i+1<m) { 8245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1],sptr[i+2])); 8252205254eSKarl Rupp } else if (i<m) { 8265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " %" PetscInt_FMT "\n",sptr[i],sptr[i+1])); 8272205254eSKarl Rupp } else { 8285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT "\n",sptr[i])); 8292205254eSKarl Rupp } 830496be53dSLois Curfman McInnes } 8315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 8325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(sptr)); 833496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 83460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 8355f80ce2aSJacob Faibussowitsch if (a->j[j] >= i) CHKERRQ(PetscViewerASCIIPrintf(viewer," %" PetscInt_FMT " ",a->j[j]+fshift)); 836496be53dSLois Curfman McInnes } 8375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 838496be53dSLois Curfman McInnes } 8395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 840496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 84160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 842496be53dSLois Curfman McInnes if (a->j[j] >= i) { 843aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 84436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 8455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 8466831982aSBarry Smith } 847496be53dSLois Curfman McInnes #else 8485f80ce2aSJacob Faibussowitsch if (a->a[j] != 0.0) CHKERRQ(PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j])); 849496be53dSLois Curfman McInnes #endif 850496be53dSLois Curfman McInnes } 851496be53dSLois Curfman McInnes } 8525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 853496be53dSLois Curfman McInnes } 8545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 855fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 85697f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 85787828ca2SBarry Smith PetscScalar value; 85868f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 85968f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 86068f1ed48SBarry Smith 86168f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 86268f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 86368f1ed48SBarry Smith realonly = PETSC_FALSE; 86468f1ed48SBarry Smith break; 86568f1ed48SBarry Smith } 86668f1ed48SBarry Smith } 86768f1ed48SBarry Smith #endif 86802594712SBarry Smith 8695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 87002594712SBarry Smith for (i=0; i<m; i++) { 87102594712SBarry Smith jcnt = 0; 872d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 873e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 87402594712SBarry Smith value = a->a[cnt++]; 875e24b481bSBarry Smith jcnt++; 87602594712SBarry Smith } else { 87702594712SBarry Smith value = 0.0; 87802594712SBarry Smith } 879aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 88068f1ed48SBarry Smith if (realonly) { 8815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value))); 88268f1ed48SBarry Smith } else { 8835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value))); 88468f1ed48SBarry Smith } 88502594712SBarry Smith #else 8865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value)); 88702594712SBarry Smith #endif 88802594712SBarry Smith } 8895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 89002594712SBarry Smith } 8915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 8923c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 893150b93efSMatthew G. Knepley PetscInt fshift=1; 8945f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 8953c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 8965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n")); 8973c215bfdSMatthew Knepley #else 8985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n")); 8993c215bfdSMatthew Knepley #endif 9005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %" PetscInt_FMT "\n", m, A->cmap->n, a->nz)); 9013c215bfdSMatthew Knepley for (i=0; i<m; i++) { 90260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9033c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 9045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 9053c215bfdSMatthew Knepley #else 9065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"%" PetscInt_FMT " %" PetscInt_FMT " %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j])); 9073c215bfdSMatthew Knepley #endif 9083c215bfdSMatthew Knepley } 9093c215bfdSMatthew Knepley } 9105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 9113a40ed3dSBarry Smith } else { 9125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 913d5f3da31SBarry Smith if (A->factortype) { 91416cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 9155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i)); 91616cd7e1dSShri Abhyankar /* L part */ 91760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 91816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 91916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 9205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 92116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])))); 92316cd7e1dSShri Abhyankar } else { 9245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]))); 92516cd7e1dSShri Abhyankar } 92616cd7e1dSShri Abhyankar #else 9275f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j])); 92816cd7e1dSShri Abhyankar #endif 92916cd7e1dSShri Abhyankar } 93016cd7e1dSShri Abhyankar /* diagonal */ 93116cd7e1dSShri Abhyankar j = a->diag[i]; 93216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 93316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 9345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]))); 93516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])))); 93716cd7e1dSShri Abhyankar } else { 9385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]))); 93916cd7e1dSShri Abhyankar } 94016cd7e1dSShri Abhyankar #else 9415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)(1.0/a->a[j]))); 94216cd7e1dSShri Abhyankar #endif 94316cd7e1dSShri Abhyankar 94416cd7e1dSShri Abhyankar /* U part */ 94560e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 94616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 94716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 9485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 94916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])))); 95116cd7e1dSShri Abhyankar } else { 9525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]))); 95316cd7e1dSShri Abhyankar } 95416cd7e1dSShri Abhyankar #else 9555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j])); 95616cd7e1dSShri Abhyankar #endif 95716cd7e1dSShri Abhyankar } 9585f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 95916cd7e1dSShri Abhyankar } 96016cd7e1dSShri Abhyankar } else { 96117ab2063SBarry Smith for (i=0; i<m; i++) { 9625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i)); 96360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 964aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 96536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 9665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]))); 96736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]))); 9693a40ed3dSBarry Smith } else { 9705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)PetscRealPart(a->a[j]))); 97117ab2063SBarry Smith } 97217ab2063SBarry Smith #else 9735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",a->j[j],(double)a->a[j])); 97417ab2063SBarry Smith #endif 97517ab2063SBarry Smith } 9765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer,"\n")); 97717ab2063SBarry Smith } 97816cd7e1dSShri Abhyankar } 9795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 98017ab2063SBarry Smith } 9815f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerFlush(viewer)); 9823a40ed3dSBarry Smith PetscFunctionReturn(0); 983416022c9SBarry Smith } 984416022c9SBarry Smith 9859804daf3SBarry Smith #include <petscdraw.h> 986dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 987416022c9SBarry Smith { 988480ef9eaSBarry Smith Mat A = (Mat) Aa; 989416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 990383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 991383922c3SLisandro Dalcin int color; 992b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 993b0a32e0cSBarry Smith PetscViewer viewer; 994f3ef73ceSBarry Smith PetscViewerFormat format; 995fff043a9SJunchao Zhang const PetscScalar *aa; 996cddf8d76SBarry Smith 9973a40ed3dSBarry Smith PetscFunctionBegin; 9985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer)); 9995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerGetFormat(viewer,&format)); 10005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr)); 1001383922c3SLisandro Dalcin 1002416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10035f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 1004fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 10055f80ce2aSJacob Faibussowitsch PetscErrorCode ierr; 1006383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10070513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1008b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1009416022c9SBarry Smith for (i=0; i<m; i++) { 1010cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1011bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1012bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1013fff043a9SJunchao Zhang if (PetscRealPart(aa[j]) >= 0.) continue; 10145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color)); 1015cddf8d76SBarry Smith } 1016cddf8d76SBarry Smith } 1017b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1018cddf8d76SBarry Smith for (i=0; i<m; i++) { 1019cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1020bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1021bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1022fff043a9SJunchao Zhang if (aa[j] != 0.) continue; 10235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color)); 1024cddf8d76SBarry Smith } 1025cddf8d76SBarry Smith } 1026b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1027cddf8d76SBarry Smith for (i=0; i<m; i++) { 1028cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1029bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1030bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1031fff043a9SJunchao Zhang if (PetscRealPart(aa[j]) <= 0.) continue; 10325f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color)); 1033416022c9SBarry Smith } 1034416022c9SBarry Smith } 1035383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10360513a670SBarry Smith } else { 10370513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10380513a670SBarry Smith /* first determine max of all nonzero values */ 1039b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1040383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1041b0a32e0cSBarry Smith PetscDraw popup; 10425f80ce2aSJacob Faibussowitsch PetscErrorCode ierr; 10430513a670SBarry Smith 10440513a670SBarry Smith for (i=0; i<nz; i++) { 1045fff043a9SJunchao Zhang if (PetscAbsScalar(aa[i]) > maxv) maxv = PetscAbsScalar(aa[i]); 10460513a670SBarry Smith } 1047383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 10485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawGetPopup(draw,&popup)); 10495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawScalePopup(popup,minv,maxv)); 1050383922c3SLisandro Dalcin 1051383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10520513a670SBarry Smith for (i=0; i<m; i++) { 1053383922c3SLisandro Dalcin y_l = m - i - 1.0; 1054383922c3SLisandro Dalcin y_r = y_l + 1.0; 1055bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1056383922c3SLisandro Dalcin x_l = a->j[j]; 1057383922c3SLisandro Dalcin x_r = x_l + 1.0; 1058fff043a9SJunchao Zhang color = PetscDrawRealToColor(PetscAbsScalar(aa[count]),minv,maxv); 10595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color)); 10600513a670SBarry Smith count++; 10610513a670SBarry Smith } 10620513a670SBarry Smith } 1063383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10640513a670SBarry Smith } 10655f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 1066480ef9eaSBarry Smith PetscFunctionReturn(0); 1067480ef9eaSBarry Smith } 1068cddf8d76SBarry Smith 10699804daf3SBarry Smith #include <petscdraw.h> 1070dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1071480ef9eaSBarry Smith { 1072b0a32e0cSBarry Smith PetscDraw draw; 107336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1074ace3abfcSBarry Smith PetscBool isnull; 1075480ef9eaSBarry Smith 1076480ef9eaSBarry Smith PetscFunctionBegin; 10775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDrawGetDraw(viewer,0,&draw)); 10785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawIsNull(draw,&isnull)); 1079480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1080480ef9eaSBarry Smith 1081d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1082480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 10835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawSetCoordinates(draw,xl,yl,xr,yr)); 10845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer)); 10855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A)); 10865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL)); 10875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscDrawSave(draw)); 10883a40ed3dSBarry Smith PetscFunctionReturn(0); 1089416022c9SBarry Smith } 1090416022c9SBarry Smith 1091dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1092416022c9SBarry Smith { 1093ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1094416022c9SBarry Smith 10953a40ed3dSBarry Smith PetscFunctionBegin; 10965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 10975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 10985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 1099c45a1595SBarry Smith if (iascii) { 11005f80ce2aSJacob Faibussowitsch CHKERRQ(MatView_SeqAIJ_ASCII(A,viewer)); 11010f5bd95cSBarry Smith } else if (isbinary) { 11025f80ce2aSJacob Faibussowitsch CHKERRQ(MatView_SeqAIJ_Binary(A,viewer)); 11030f5bd95cSBarry Smith } else if (isdraw) { 11045f80ce2aSJacob Faibussowitsch CHKERRQ(MatView_SeqAIJ_Draw(A,viewer)); 110511aeaf0aSBarry Smith } 11065f80ce2aSJacob Faibussowitsch CHKERRQ(MatView_SeqAIJ_Inode(A,viewer)); 11073a40ed3dSBarry Smith PetscFunctionReturn(0); 110817ab2063SBarry Smith } 110919bcc07fSBarry Smith 1110dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 111117ab2063SBarry Smith { 1112416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1113580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1114d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 111554f21887SBarry Smith MatScalar *aa = a->a,*ap; 11163447b6efSHong Zhang PetscReal ratio = 0.6; 111717ab2063SBarry Smith 11183a40ed3dSBarry Smith PetscFunctionBegin; 11193a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 11205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 1121b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1122b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 11235f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd_SeqAIJ_Inode(A,mode)); 1124b215bc84SStefano Zampini PetscFunctionReturn(0); 1125b215bc84SStefano Zampini } 112617ab2063SBarry Smith 112743ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 112817ab2063SBarry Smith for (i=1; i<m; i++) { 1129416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 113017ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 113194a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 113217ab2063SBarry Smith if (fshift) { 1133bfeeae90SHong Zhang ip = aj + ai[i]; 1134bfeeae90SHong Zhang ap = aa + ai[i]; 113517ab2063SBarry Smith N = ailen[i]; 11365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraymove(ip-fshift,ip,N)); 1137580bdb30SBarry Smith if (!A->structure_only) { 11385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraymove(ap-fshift,ap,N)); 113917ab2063SBarry Smith } 114017ab2063SBarry Smith } 114117ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 114217ab2063SBarry Smith } 114317ab2063SBarry Smith if (m) { 114417ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 114517ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 114617ab2063SBarry Smith } 11477b083b7cSBarry Smith 114817ab2063SBarry Smith /* reset ilen and imax for each row */ 11497b083b7cSBarry Smith a->nonzerorowcnt = 0; 1150396832f4SHong Zhang if (A->structure_only) { 11515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->imax)); 11525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->ilen)); 1153396832f4SHong Zhang } else { /* !A->structure_only */ 115417ab2063SBarry Smith for (i=0; i<m; i++) { 115517ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 11567b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 115717ab2063SBarry Smith } 1158396832f4SHong Zhang } 1159bfeeae90SHong Zhang a->nz = ai[m]; 11602c71b3e2SJacob Faibussowitsch PetscCheckFalse(fshift && a->nounused == -1,PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %" PetscInt_FMT " X %" PetscInt_FMT ", %" PetscInt_FMT " unneeded", m, A->cmap->n, fshift); 116117ab2063SBarry Smith 11625f80ce2aSJacob Faibussowitsch CHKERRQ(MatMarkDiagonal_SeqAIJ(A)); 11635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Matrix size: %" PetscInt_FMT " X %" PetscInt_FMT "; storage space: %" PetscInt_FMT " unneeded,%" PetscInt_FMT " used\n",m,A->cmap->n,fshift,a->nz)); 11645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Number of mallocs during MatSetValues() is %" PetscInt_FMT "\n",a->reallocs)); 11655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Maximum nonzeros in any row is %" PetscInt_FMT "\n",rmax)); 11662205254eSKarl Rupp 11678e58a170SBarry Smith A->info.mallocs += a->reallocs; 1168dd5f02e7SSatish Balay a->reallocs = 0; 11696712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 117036db0b34SBarry Smith a->rmax = rmax; 11714e220ebcSLois Curfman McInnes 1172396832f4SHong Zhang if (!A->structure_only) { 11735f80ce2aSJacob Faibussowitsch CHKERRQ(MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio)); 1174396832f4SHong Zhang } 11755f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd_SeqAIJ_Inode(A,mode)); 11763a40ed3dSBarry Smith PetscFunctionReturn(0); 117717ab2063SBarry Smith } 117817ab2063SBarry Smith 117999cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 118099cafbc1SBarry Smith { 118199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 118299cafbc1SBarry Smith PetscInt i,nz = a->nz; 11832e5835c6SStefano Zampini MatScalar *aa; 118499cafbc1SBarry Smith 118599cafbc1SBarry Smith PetscFunctionBegin; 11865f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 118799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 11885f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 11895f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 119099cafbc1SBarry Smith PetscFunctionReturn(0); 119199cafbc1SBarry Smith } 119299cafbc1SBarry Smith 119399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 119499cafbc1SBarry Smith { 119599cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 119699cafbc1SBarry Smith PetscInt i,nz = a->nz; 11972e5835c6SStefano Zampini MatScalar *aa; 119899cafbc1SBarry Smith 119999cafbc1SBarry Smith PetscFunctionBegin; 12005f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 120199cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 12025f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 12035f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 120499cafbc1SBarry Smith PetscFunctionReturn(0); 120599cafbc1SBarry Smith } 120699cafbc1SBarry Smith 1207dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 120817ab2063SBarry Smith { 1209fff043a9SJunchao Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1210fff043a9SJunchao Zhang MatScalar *aa; 12113a40ed3dSBarry Smith 12123a40ed3dSBarry Smith PetscFunctionBegin; 12135f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayWrite(A,&aa)); 12145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(aa,a->i[A->rmap->n])); 12155f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayWrite(A,&aa)); 12165f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 12173a40ed3dSBarry Smith PetscFunctionReturn(0); 121817ab2063SBarry Smith } 1219416022c9SBarry Smith 1220cbc6b225SStefano Zampini PETSC_INTERN PetscErrorCode MatResetPreallocationCOO_SeqAIJ(Mat A) 1221cbc6b225SStefano Zampini { 1222cbc6b225SStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1223cbc6b225SStefano Zampini 1224cbc6b225SStefano Zampini PetscFunctionBegin; 12255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->perm)); 12265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->jmap)); 1227cbc6b225SStefano Zampini PetscFunctionReturn(0); 1228cbc6b225SStefano Zampini } 1229cbc6b225SStefano Zampini 1230dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 123117ab2063SBarry Smith { 1232416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1233d5d45c9bSBarry Smith 12343a40ed3dSBarry Smith PetscFunctionBegin; 1235aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1236c0aa6a63SJacob Faibussowitsch PetscLogObjectState((PetscObject)A,"Rows=%" PetscInt_FMT ", Cols=%" PetscInt_FMT ", NZ=%" PetscInt_FMT,A->rmap->n,A->cmap->n,a->nz); 123717ab2063SBarry Smith #endif 12385f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i)); 12395f80ce2aSJacob Faibussowitsch CHKERRQ(MatResetPreallocationCOO_SeqAIJ(A)); 12405f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&a->row)); 12415f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&a->col)); 12425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->diag)); 12435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->ibdiag)); 12445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->imax)); 12455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->ilen)); 12465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->ipre)); 12475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree3(a->idiag,a->mdiag,a->ssor_work)); 12485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->solve_work)); 12495f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&a->icol)); 12505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(a->saved_values)); 12515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(a->compressedrow.i,a->compressedrow.rindex)); 12525f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy_SeqAIJ_Inode(A)); 12535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(A->data)); 1254901853e0SKris Buschelman 12556718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 12566718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 12576718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 12586718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 12596718818eSStefano Zampini due to different matrix sizes */ 12605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL)); 12616718818eSStefano Zampini 12625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectChangeTypeName((PetscObject)A,NULL)); 12635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL)); 12645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL)); 12655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL)); 12665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL)); 12675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL)); 12685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL)); 12694222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 12705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL)); 12715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL)); 12725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL)); 12734222ddf1SHong Zhang #endif 12743d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 12755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL)); 12763d0639e7SStefano Zampini #endif 12775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL)); 1278af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 12795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL)); 1280af8000cdSHong Zhang #endif 1281d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 12825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL)); 1283d24d4204SJose E. Roman #endif 128463c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 12855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL)); 12865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL)); 128763c07aadSStefano Zampini #endif 12885f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL)); 12895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL)); 12905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL)); 12915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL)); 12925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL)); 12935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL)); 12945f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL)); 12955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL)); 12965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL)); 12975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL)); 12985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL)); 12995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJKron_C",NULL)); 13005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatSetPreallocationCOO_C",NULL)); 13015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)A,"MatSetValuesCOO_C",NULL)); 13023a40ed3dSBarry Smith PetscFunctionReturn(0); 130317ab2063SBarry Smith } 130417ab2063SBarry Smith 1305ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 130617ab2063SBarry Smith { 1307416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13083a40ed3dSBarry Smith 13093a40ed3dSBarry Smith PetscFunctionBegin; 1310a65d3064SKris Buschelman switch (op) { 1311a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13124e0d8c25SBarry Smith a->roworiented = flg; 1313a65d3064SKris Buschelman break; 1314a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1315a9817697SBarry Smith a->keepnonzeropattern = flg; 1316a65d3064SKris Buschelman break; 1317512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1318512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1319a65d3064SKris Buschelman break; 1320a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13214e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1322a65d3064SKris Buschelman break; 1323a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13244e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1325a65d3064SKris Buschelman break; 132628b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 132728b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 132828b2fa4aSMatthew Knepley break; 1329a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13304e0d8c25SBarry Smith a->ignorezeroentries = flg; 13310df259c2SBarry Smith break; 13323d472b54SHong Zhang case MAT_SPD: 1333b1646e73SJed Brown case MAT_SYMMETRIC: 1334b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1335b1646e73SJed Brown case MAT_HERMITIAN: 1336b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1337957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13385021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13395021d80fSJed Brown break; 13408c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1341a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1342a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 13435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Option %s ignored\n",MatOptions[op])); 1344a65d3064SKris Buschelman break; 1345b87ac2d8SJed Brown case MAT_USE_INODES: 13465f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg)); 1347b87ac2d8SJed Brown break; 1348c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1349c10200c1SHong Zhang A->submat_singleis = flg; 1350c10200c1SHong Zhang break; 1351071fcb05SBarry Smith case MAT_SORTED_FULL: 1352071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1353071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1354071fcb05SBarry Smith break; 13551a2c6b5cSJunchao Zhang case MAT_FORM_EXPLICIT_TRANSPOSE: 13561a2c6b5cSJunchao Zhang A->form_explicit_transpose = flg; 13571a2c6b5cSJunchao Zhang break; 1358a65d3064SKris Buschelman default: 135998921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1360a65d3064SKris Buschelman } 13613a40ed3dSBarry Smith PetscFunctionReturn(0); 136217ab2063SBarry Smith } 136317ab2063SBarry Smith 1364dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 136517ab2063SBarry Smith { 1366416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1367fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1368c898d852SStefano Zampini PetscScalar *x; 1369c898d852SStefano Zampini const PetscScalar *aa; 137017ab2063SBarry Smith 13713a40ed3dSBarry Smith PetscFunctionBegin; 13725f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(v,&n)); 13732c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 13745f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 1375d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1376d3e70bfaSHong Zhang PetscInt *diag=a->diag; 13775f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(v,&x)); 13782c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 13795f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(v,&x)); 13805f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 138135e7444dSHong Zhang PetscFunctionReturn(0); 138235e7444dSHong Zhang } 138335e7444dSHong Zhang 13845f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(v,&x)); 138535e7444dSHong Zhang for (i=0; i<n; i++) { 1386fdc842d1SBarry Smith x[i] = 0.0; 138735e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 138835e7444dSHong Zhang if (aj[j] == i) { 138935e7444dSHong Zhang x[i] = aa[j]; 139017ab2063SBarry Smith break; 139117ab2063SBarry Smith } 139217ab2063SBarry Smith } 139317ab2063SBarry Smith } 13945f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(v,&x)); 13955f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 13963a40ed3dSBarry Smith PetscFunctionReturn(0); 139717ab2063SBarry Smith } 139817ab2063SBarry Smith 1399c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1400dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 140117ab2063SBarry Smith { 1402416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14035f22a7b3SSebastian Grimberg const MatScalar *aa; 1404d9ca1df4SBarry Smith PetscScalar *y; 1405d9ca1df4SBarry Smith const PetscScalar *x; 1406d0f46423SBarry Smith PetscInt m = A->rmap->n; 14075c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 14085f22a7b3SSebastian Grimberg const MatScalar *v; 1409a77337e4SBarry Smith PetscScalar alpha; 1410d9ca1df4SBarry Smith PetscInt n,i,j; 1411d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14123447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1413ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14145c897100SBarry Smith #endif 141517ab2063SBarry Smith 14163a40ed3dSBarry Smith PetscFunctionBegin; 14175f80ce2aSJacob Faibussowitsch if (zz != yy) CHKERRQ(VecCopy(zz,yy)); 14185f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(xx,&x)); 14195f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(yy,&y)); 14205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 14215c897100SBarry Smith 14225c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1423fff043a9SJunchao Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,aa,y); 14245c897100SBarry Smith #else 14253447b6efSHong Zhang if (usecprow) { 14263447b6efSHong Zhang m = cprow.nrows; 14273447b6efSHong Zhang ii = cprow.i; 14287b2bb3b9SHong Zhang ridx = cprow.rindex; 14293447b6efSHong Zhang } else { 14303447b6efSHong Zhang ii = a->i; 14313447b6efSHong Zhang } 143217ab2063SBarry Smith for (i=0; i<m; i++) { 14333447b6efSHong Zhang idx = a->j + ii[i]; 1434fff043a9SJunchao Zhang v = aa + ii[i]; 14353447b6efSHong Zhang n = ii[i+1] - ii[i]; 14363447b6efSHong Zhang if (usecprow) { 14377b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14383447b6efSHong Zhang } else { 143917ab2063SBarry Smith alpha = x[i]; 14403447b6efSHong Zhang } 144104fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 144217ab2063SBarry Smith } 14435c897100SBarry Smith #endif 14445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz)); 14455f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(xx,&x)); 14465f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(yy,&y)); 14475f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 14483a40ed3dSBarry Smith PetscFunctionReturn(0); 144917ab2063SBarry Smith } 145017ab2063SBarry Smith 1451dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14525c897100SBarry Smith { 14535c897100SBarry Smith PetscFunctionBegin; 14545f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(yy,0.0)); 14555f80ce2aSJacob Faibussowitsch CHKERRQ(MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy)); 14565c897100SBarry Smith PetscFunctionReturn(0); 14575c897100SBarry Smith } 14585c897100SBarry Smith 1459c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 146078b84d54SShri Abhyankar 1461dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 146217ab2063SBarry Smith { 1463416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1464d9fead3dSBarry Smith PetscScalar *y; 146554f21887SBarry Smith const PetscScalar *x; 1466fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1467003131ecSBarry Smith PetscInt m=A->rmap->n; 14680298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 14697b083b7cSBarry Smith PetscInt n,i; 1470362ced78SSatish Balay PetscScalar sum; 1471ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 147217ab2063SBarry Smith 1473b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 147497952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1475fee21e36SBarry Smith #endif 1476fee21e36SBarry Smith 14773a40ed3dSBarry Smith PetscFunctionBegin; 1478b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 14795f80ce2aSJacob Faibussowitsch CHKERRQ(MatMult_SeqAIJ_Inode(A,xx,yy)); 1480b215bc84SStefano Zampini PetscFunctionReturn(0); 1481b215bc84SStefano Zampini } 14825f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&a_a)); 14835f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(xx,&x)); 14845f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(yy,&y)); 1485416022c9SBarry Smith ii = a->i; 14864eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 14875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(y,m)); 148897952fefSHong Zhang m = a->compressedrow.nrows; 148997952fefSHong Zhang ii = a->compressedrow.i; 149097952fefSHong Zhang ridx = a->compressedrow.rindex; 149197952fefSHong Zhang for (i=0; i<m; i++) { 149297952fefSHong Zhang n = ii[i+1] - ii[i]; 149397952fefSHong Zhang aj = a->j + ii[i]; 1494fff043a9SJunchao Zhang aa = a_a + ii[i]; 149597952fefSHong Zhang sum = 0.0; 1496003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1497003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 149897952fefSHong Zhang y[*ridx++] = sum; 149997952fefSHong Zhang } 150097952fefSHong Zhang } else { /* do not use compressed row format */ 1501b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15023d3eaba7SBarry Smith aj = a->j; 1503fff043a9SJunchao Zhang aa = a_a; 1504b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1505b05257ddSBarry Smith #else 150617ab2063SBarry Smith for (i=0; i<m; i++) { 1507003131ecSBarry Smith n = ii[i+1] - ii[i]; 1508003131ecSBarry Smith aj = a->j + ii[i]; 1509fff043a9SJunchao Zhang aa = a_a + ii[i]; 151017ab2063SBarry Smith sum = 0.0; 1511003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 151217ab2063SBarry Smith y[i] = sum; 151317ab2063SBarry Smith } 15148d195f9aSBarry Smith #endif 1515b05257ddSBarry Smith } 15165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz - a->nonzerorowcnt)); 15175f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(xx,&x)); 15185f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(yy,&y)); 15195f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&a_a)); 15203a40ed3dSBarry Smith PetscFunctionReturn(0); 152117ab2063SBarry Smith } 152217ab2063SBarry Smith 1523b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1524b434eb95SMatthew G. Knepley { 1525b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1526b434eb95SMatthew G. Knepley PetscScalar *y; 1527b434eb95SMatthew G. Knepley const PetscScalar *x; 1528fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1529b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1530b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1531b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1532b434eb95SMatthew G. Knepley PetscScalar sum; 1533b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1534b434eb95SMatthew G. Knepley 1535b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1536b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1537b434eb95SMatthew G. Knepley #endif 1538b434eb95SMatthew G. Knepley 1539b434eb95SMatthew G. Knepley PetscFunctionBegin; 15405f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&a_a)); 15415f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(xx,&x)); 15425f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(yy,&y)); 1543b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1544b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1545b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1546b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1547b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1548b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1549b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1550fff043a9SJunchao Zhang aa = a_a + ii[i]; 1551b434eb95SMatthew G. Knepley sum = 0.0; 1552b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1553b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1554b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1555b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1556b434eb95SMatthew G. Knepley } 1557b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15583d3eaba7SBarry Smith ii = a->i; 1559b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1560b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1561b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1562fff043a9SJunchao Zhang aa = a_a + ii[i]; 1563b434eb95SMatthew G. Knepley sum = 0.0; 1564b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1565b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1566b434eb95SMatthew G. Knepley y[i] = sum; 1567b434eb95SMatthew G. Knepley } 1568b434eb95SMatthew G. Knepley } 15695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz - nonzerorow)); 15705f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(xx,&x)); 15715f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(yy,&y)); 15725f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&a_a)); 1573b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1574b434eb95SMatthew G. Knepley } 1575b434eb95SMatthew G. Knepley 1576b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1577b434eb95SMatthew G. Knepley { 1578b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1579b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1580b434eb95SMatthew G. Knepley const PetscScalar *x; 1581fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1582b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1583b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1584b434eb95SMatthew G. Knepley PetscScalar sum; 1585b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1586b434eb95SMatthew G. Knepley 1587b434eb95SMatthew G. Knepley PetscFunctionBegin; 15885f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&a_a)); 15895f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(xx,&x)); 15905f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayPair(yy,zz,&y,&z)); 1591b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1592b434eb95SMatthew G. Knepley if (zz != yy) { 15935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(z,y,m)); 1594b434eb95SMatthew G. Knepley } 1595b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1596b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1597b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1598b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1599b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1600b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1601fff043a9SJunchao Zhang aa = a_a + ii[i]; 1602b434eb95SMatthew G. Knepley sum = y[*ridx]; 1603b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1604b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1605b434eb95SMatthew G. Knepley } 1606b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16073d3eaba7SBarry Smith ii = a->i; 1608b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1609b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1610b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1611fff043a9SJunchao Zhang aa = a_a + ii[i]; 1612b434eb95SMatthew G. Knepley sum = y[i]; 1613b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1614b434eb95SMatthew G. Knepley z[i] = sum; 1615b434eb95SMatthew G. Knepley } 1616b434eb95SMatthew G. Knepley } 16175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz)); 16185f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(xx,&x)); 16195f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayPair(yy,zz,&y,&z)); 16205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&a_a)); 1621b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1622b434eb95SMatthew G. Knepley } 1623b434eb95SMatthew G. Knepley 1624c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1625dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 162617ab2063SBarry Smith { 1627416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1628f15663dcSBarry Smith PetscScalar *y,*z; 1629f15663dcSBarry Smith const PetscScalar *x; 1630fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1631d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1632d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1633362ced78SSatish Balay PetscScalar sum; 1634ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16359ea0dfa2SSatish Balay 16363a40ed3dSBarry Smith PetscFunctionBegin; 1637b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 16385f80ce2aSJacob Faibussowitsch CHKERRQ(MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz)); 1639b215bc84SStefano Zampini PetscFunctionReturn(0); 1640b215bc84SStefano Zampini } 16415f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&a_a)); 16425f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(xx,&x)); 16435f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayPair(yy,zz,&y,&z)); 16444eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16454eb6d288SHong Zhang if (zz != yy) { 16465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(z,y,m)); 16474eb6d288SHong Zhang } 164897952fefSHong Zhang m = a->compressedrow.nrows; 164997952fefSHong Zhang ii = a->compressedrow.i; 165097952fefSHong Zhang ridx = a->compressedrow.rindex; 165197952fefSHong Zhang for (i=0; i<m; i++) { 165297952fefSHong Zhang n = ii[i+1] - ii[i]; 165397952fefSHong Zhang aj = a->j + ii[i]; 1654fff043a9SJunchao Zhang aa = a_a + ii[i]; 165597952fefSHong Zhang sum = y[*ridx]; 1656f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 165797952fefSHong Zhang z[*ridx++] = sum; 165897952fefSHong Zhang } 165997952fefSHong Zhang } else { /* do not use compressed row format */ 16603d3eaba7SBarry Smith ii = a->i; 1661f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 16623d3eaba7SBarry Smith aj = a->j; 1663fff043a9SJunchao Zhang aa = a_a; 1664f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1665f15663dcSBarry Smith #else 166617ab2063SBarry Smith for (i=0; i<m; i++) { 1667f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1668f15663dcSBarry Smith aj = a->j + ii[i]; 1669fff043a9SJunchao Zhang aa = a_a + ii[i]; 167017ab2063SBarry Smith sum = y[i]; 1671f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 167217ab2063SBarry Smith z[i] = sum; 167317ab2063SBarry Smith } 167402ab625aSSatish Balay #endif 1675f15663dcSBarry Smith } 16765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz)); 16775f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(xx,&x)); 16785f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayPair(yy,zz,&y,&z)); 16795f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&a_a)); 16803a40ed3dSBarry Smith PetscFunctionReturn(0); 168117ab2063SBarry Smith } 168217ab2063SBarry Smith 168317ab2063SBarry Smith /* 168417ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 168517ab2063SBarry Smith */ 1686dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 168717ab2063SBarry Smith { 1688416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1689d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 169017ab2063SBarry Smith 16913a40ed3dSBarry Smith PetscFunctionBegin; 169209f38230SBarry Smith if (!a->diag) { 16935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m,&a->diag)); 16945f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt))); 169509f38230SBarry Smith } 1696d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 169709f38230SBarry Smith a->diag[i] = a->i[i+1]; 1698bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1699bfeeae90SHong Zhang if (a->j[j] == i) { 170009f38230SBarry Smith a->diag[i] = j; 170117ab2063SBarry Smith break; 170217ab2063SBarry Smith } 170317ab2063SBarry Smith } 170417ab2063SBarry Smith } 17053a40ed3dSBarry Smith PetscFunctionReturn(0); 170617ab2063SBarry Smith } 170717ab2063SBarry Smith 170861ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 170961ecd0c6SBarry Smith { 171061ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 171161ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 171261ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 171361ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 171461ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 171561ecd0c6SBarry Smith 171661ecd0c6SBarry Smith PetscFunctionBegin; 171761ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 17185f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(A,1,NULL)); 17195f80ce2aSJacob Faibussowitsch CHKERRQ(MatShift_Basic(A,v)); 172061ecd0c6SBarry Smith PetscFunctionReturn(0); 172161ecd0c6SBarry Smith } 172261ecd0c6SBarry Smith 172361ecd0c6SBarry Smith if (a->diagonaldense) { 172461ecd0c6SBarry Smith cnt = 0; 172561ecd0c6SBarry Smith } else { 17265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(A->rmap->n,&mdiag)); 172761ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 172861ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 172961ecd0c6SBarry Smith cnt++; 173061ecd0c6SBarry Smith mdiag[i] = 1; 173161ecd0c6SBarry Smith } 173261ecd0c6SBarry Smith } 173361ecd0c6SBarry Smith } 173461ecd0c6SBarry Smith if (!cnt) { 17355f80ce2aSJacob Faibussowitsch CHKERRQ(MatShift_Basic(A,v)); 173661ecd0c6SBarry Smith } else { 1737b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1738b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 173961ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 174061ecd0c6SBarry Smith 174161ecd0c6SBarry Smith a->a = NULL; 174261ecd0c6SBarry Smith a->j = NULL; 174361ecd0c6SBarry Smith a->i = NULL; 174461ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 174561ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 174661ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1747447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 174861ecd0c6SBarry Smith } 17495f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax)); 175061ecd0c6SBarry Smith 175161ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 175261ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 17535f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES)); 1754447d62f5SStefano Zampini if (i < A->cmap->n) { 17555f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValue(A,i,i,v,ADD_VALUES)); 175661ecd0c6SBarry Smith } 1757447d62f5SStefano Zampini } 17585f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 17595f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 176061ecd0c6SBarry Smith if (singlemalloc) { 17615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree3(olda,oldj,oldi)); 176261ecd0c6SBarry Smith } else { 17635f80ce2aSJacob Faibussowitsch if (free_a) CHKERRQ(PetscFree(olda)); 17645f80ce2aSJacob Faibussowitsch if (free_ij) CHKERRQ(PetscFree(oldj)); 17655f80ce2aSJacob Faibussowitsch if (free_ij) CHKERRQ(PetscFree(oldi)); 176661ecd0c6SBarry Smith } 176761ecd0c6SBarry Smith } 17685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(mdiag)); 176961ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 177061ecd0c6SBarry Smith PetscFunctionReturn(0); 177161ecd0c6SBarry Smith } 177261ecd0c6SBarry Smith 1773be5855fcSBarry Smith /* 1774be5855fcSBarry Smith Checks for missing diagonals 1775be5855fcSBarry Smith */ 1776ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1777be5855fcSBarry Smith { 1778be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17797734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1780be5855fcSBarry Smith 1781be5855fcSBarry Smith PetscFunctionBegin; 178209f38230SBarry Smith *missing = PETSC_FALSE; 17837734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 178409f38230SBarry Smith *missing = PETSC_TRUE; 178509f38230SBarry Smith if (d) *d = 0; 17865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n")); 178709f38230SBarry Smith } else { 178801445905SHong Zhang PetscInt n; 178901445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1790f1e2ffcdSBarry Smith diag = a->diag; 179101445905SHong Zhang for (i=0; i<n; i++) { 17927734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 179309f38230SBarry Smith *missing = PETSC_TRUE; 179409f38230SBarry Smith if (d) *d = i; 17955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Matrix is missing diagonal number %" PetscInt_FMT "\n",i)); 1796358d2f5dSShri Abhyankar break; 179709f38230SBarry Smith } 1798be5855fcSBarry Smith } 1799be5855fcSBarry Smith } 1800be5855fcSBarry Smith PetscFunctionReturn(0); 1801be5855fcSBarry Smith } 1802be5855fcSBarry Smith 18030da83c2eSBarry Smith #include <petscblaslapack.h> 18040da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18050da83c2eSBarry Smith 18060da83c2eSBarry Smith /* 18070da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18080da83c2eSBarry Smith */ 18090da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18100da83c2eSBarry Smith { 18110da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18120da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18130da83c2eSBarry Smith const PetscReal shift = 0.0; 18140da83c2eSBarry Smith PetscInt ipvt[5]; 18150da83c2eSBarry Smith PetscScalar work[25],*v_work; 18160da83c2eSBarry Smith 18170da83c2eSBarry Smith PetscFunctionBegin; 18180da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18190da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18202c71b3e2SJacob Faibussowitsch PetscCheckFalse(ncnt != n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %" PetscInt_FMT " doesn't match number matrix rows %" PetscInt_FMT,ncnt,n); 18210da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18220da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18230da83c2eSBarry Smith } 18245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(bsizemax,&indx)); 18250da83c2eSBarry Smith if (bsizemax > 7) { 18265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots)); 18270da83c2eSBarry Smith } 18280da83c2eSBarry Smith ncnt = 0; 18290da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18300da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18315f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag)); 18320da83c2eSBarry Smith switch (bsizes[i]) { 18330da83c2eSBarry Smith case 1: 18340da83c2eSBarry Smith *diag = 1.0/(*diag); 18350da83c2eSBarry Smith break; 18360da83c2eSBarry Smith case 2: 18375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected)); 18380da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_2(diag)); 18400da83c2eSBarry Smith break; 18410da83c2eSBarry Smith case 3: 18425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected)); 18430da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_3(diag)); 18450da83c2eSBarry Smith break; 18460da83c2eSBarry Smith case 4: 18475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected)); 18480da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_4(diag)); 18500da83c2eSBarry Smith break; 18510da83c2eSBarry Smith case 5: 18525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected)); 18530da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_5(diag)); 18550da83c2eSBarry Smith break; 18560da83c2eSBarry Smith case 6: 18575f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected)); 18580da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_6(diag)); 18600da83c2eSBarry Smith break; 18610da83c2eSBarry Smith case 7: 18625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected)); 18630da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_7(diag)); 18650da83c2eSBarry Smith break; 18660da83c2eSBarry Smith default: 18675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected)); 18680da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_N(diag,bsizes[i])); 18700da83c2eSBarry Smith } 18710da83c2eSBarry Smith ncnt += bsizes[i]; 18720da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 18730da83c2eSBarry Smith } 18740da83c2eSBarry Smith if (bsizemax > 7) { 18755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(v_work,v_pivots)); 18760da83c2eSBarry Smith } 18775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(indx)); 18780da83c2eSBarry Smith PetscFunctionReturn(0); 18790da83c2eSBarry Smith } 18800da83c2eSBarry Smith 1881422a814eSBarry Smith /* 1882422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1883422a814eSBarry Smith */ 18847087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 188571f1c65dSBarry Smith { 188671f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 1887d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 18882e5835c6SStefano Zampini const MatScalar *v; 188954f21887SBarry Smith PetscScalar *idiag,*mdiag; 189071f1c65dSBarry Smith 189171f1c65dSBarry Smith PetscFunctionBegin; 189271f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 18935f80ce2aSJacob Faibussowitsch CHKERRQ(MatMarkDiagonal_SeqAIJ(A)); 189471f1c65dSBarry Smith diag = a->diag; 189571f1c65dSBarry Smith if (!a->idiag) { 18965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work)); 18975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar))); 189871f1c65dSBarry Smith } 18992e5835c6SStefano Zampini 190071f1c65dSBarry Smith mdiag = a->mdiag; 190171f1c65dSBarry Smith idiag = a->idiag; 19025f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&v)); 1903422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 190471f1c65dSBarry Smith for (i=0; i<m; i++) { 190571f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1906899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1907899639b0SHong Zhang if (PetscRealPart(fshift)) { 19085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Zero diagonal on row %" PetscInt_FMT "\n",i)); 19097b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19107b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19117b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 191298921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %" PetscInt_FMT,i); 1913899639b0SHong Zhang } 191471f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 191571f1c65dSBarry Smith } 19165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(m)); 191771f1c65dSBarry Smith } else { 191871f1c65dSBarry Smith for (i=0; i<m; i++) { 191971f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 192071f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 192171f1c65dSBarry Smith } 19225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*m)); 192371f1c65dSBarry Smith } 192471f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 19255f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&v)); 192671f1c65dSBarry Smith PetscFunctionReturn(0); 192771f1c65dSBarry Smith } 192871f1c65dSBarry Smith 1929c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 193041f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 193117ab2063SBarry Smith { 1932416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1933e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 19342e5835c6SStefano Zampini const MatScalar *v,*idiag=NULL,*mdiag,*aa; 193554f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 19363d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 193797f1f81fSBarry Smith const PetscInt *idx,*diag; 193817ab2063SBarry Smith 19393a40ed3dSBarry Smith PetscFunctionBegin; 1940b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 19415f80ce2aSJacob Faibussowitsch CHKERRQ(MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx)); 1942b215bc84SStefano Zampini PetscFunctionReturn(0); 1943b215bc84SStefano Zampini } 1944b965ef7fSBarry Smith its = its*lits; 194591723122SBarry Smith 194671f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 19475f80ce2aSJacob Faibussowitsch if (!a->idiagvalid) CHKERRQ(MatInvertDiagonal_SeqAIJ(A,omega,fshift)); 194871f1c65dSBarry Smith a->fshift = fshift; 194971f1c65dSBarry Smith a->omega = omega; 1950ed480e8bSBarry Smith 195171f1c65dSBarry Smith diag = a->diag; 195271f1c65dSBarry Smith t = a->ssor_work; 1953ed480e8bSBarry Smith idiag = a->idiag; 195471f1c65dSBarry Smith mdiag = a->mdiag; 1955ed480e8bSBarry Smith 19565f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 19575f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(xx,&x)); 19585f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(bb,&b)); 1959ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 196017ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 196117ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1962ed480e8bSBarry Smith bs = b; 196317ab2063SBarry Smith for (i=0; i<m; i++) { 196471f1c65dSBarry Smith d = fshift + mdiag[i]; 1965416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1966ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 19672e5835c6SStefano Zampini v = aa + diag[i] + 1; 196817ab2063SBarry Smith sum = b[i]*d/omega; 1969003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 197017ab2063SBarry Smith x[i] = sum; 197117ab2063SBarry Smith } 19725f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(xx,&x)); 19735f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(bb,&b)); 19745f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 19755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(a->nz)); 19763a40ed3dSBarry Smith PetscFunctionReturn(0); 197717ab2063SBarry Smith } 1978c783ea89SBarry Smith 19792c71b3e2SJacob Faibussowitsch PetscCheckFalse(flag == SOR_APPLY_LOWER,PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 19802205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 19814c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 1982887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 198317ab2063SBarry Smith 198417ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 198517ab2063SBarry Smith 1986887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 198717ab2063SBarry Smith */ 198817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 198917ab2063SBarry Smith 199017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 199117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1992416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1993ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 19942e5835c6SStefano Zampini v = aa + diag[i] + 1; 199517ab2063SBarry Smith sum = b[i]; 1996e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1997ed480e8bSBarry Smith x[i] = sum*idiag[i]; 199817ab2063SBarry Smith } 199917ab2063SBarry Smith 200017ab2063SBarry Smith /* t = b - (2*E - D)x */ 20012e5835c6SStefano Zampini v = aa; 20022205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 200317ab2063SBarry Smith 200417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2005ed480e8bSBarry Smith ts = t; 2006416022c9SBarry Smith diag = a->diag; 200717ab2063SBarry Smith for (i=0; i<m; i++) { 2008416022c9SBarry Smith n = diag[i] - a->i[i]; 2009ed480e8bSBarry Smith idx = a->j + a->i[i]; 20102e5835c6SStefano Zampini v = aa + a->i[i]; 201117ab2063SBarry Smith sum = t[i]; 2012003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2013ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2014733d66baSBarry Smith /* x = x + t */ 2015733d66baSBarry Smith x[i] += t[i]; 201617ab2063SBarry Smith } 201717ab2063SBarry Smith 20185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(6.0*m-1 + 2.0*a->nz)); 20195f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(xx,&x)); 20205f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(bb,&b)); 20213a40ed3dSBarry Smith PetscFunctionReturn(0); 202217ab2063SBarry Smith } 202317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 202417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 202517ab2063SBarry Smith for (i=0; i<m; i++) { 2026416022c9SBarry Smith n = diag[i] - a->i[i]; 2027ed480e8bSBarry Smith idx = a->j + a->i[i]; 20282e5835c6SStefano Zampini v = aa + a->i[i]; 202917ab2063SBarry Smith sum = b[i]; 2030e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20315c99c7daSBarry Smith t[i] = sum; 2032ed480e8bSBarry Smith x[i] = sum*idiag[i]; 203317ab2063SBarry Smith } 20345c99c7daSBarry Smith xb = t; 20355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(a->nz)); 20363a40ed3dSBarry Smith } else xb = b; 203717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 203817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2039416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2040ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20412e5835c6SStefano Zampini v = aa + diag[i] + 1; 204217ab2063SBarry Smith sum = xb[i]; 2043e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20445c99c7daSBarry Smith if (xb == b) { 2045ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20465c99c7daSBarry Smith } else { 2047b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 204817ab2063SBarry Smith } 20495c99c7daSBarry Smith } 20505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(a->nz)); /* assumes 1/2 in upper */ 205117ab2063SBarry Smith } 205217ab2063SBarry Smith its--; 205317ab2063SBarry Smith } 205417ab2063SBarry Smith while (its--) { 205517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 205617ab2063SBarry Smith for (i=0; i<m; i++) { 2057b19a5dc2SMark Adams /* lower */ 2058b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2059ed480e8bSBarry Smith idx = a->j + a->i[i]; 20602e5835c6SStefano Zampini v = aa + a->i[i]; 206117ab2063SBarry Smith sum = b[i]; 2062e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2063b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2064b19a5dc2SMark Adams /* upper */ 2065b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2066b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 20672e5835c6SStefano Zampini v = aa + diag[i] + 1; 2068b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2069b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 207017ab2063SBarry Smith } 2071b19a5dc2SMark Adams xb = t; 20725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz)); 2073b19a5dc2SMark Adams } else xb = b; 207417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 207517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2076b19a5dc2SMark Adams sum = xb[i]; 2077b19a5dc2SMark Adams if (xb == b) { 2078b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2079416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2080ed480e8bSBarry Smith idx = a->j + a->i[i]; 20812e5835c6SStefano Zampini v = aa + a->i[i]; 2082e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2083ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2084b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2085b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2086b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 20872e5835c6SStefano Zampini v = aa + diag[i] + 1; 2088b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2089b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 209017ab2063SBarry Smith } 2091b19a5dc2SMark Adams } 2092b19a5dc2SMark Adams if (xb == b) { 20935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz)); 2094b19a5dc2SMark Adams } else { 20955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(a->nz)); /* assumes 1/2 in upper */ 2096b19a5dc2SMark Adams } 209717ab2063SBarry Smith } 209817ab2063SBarry Smith } 20995f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 21005f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(xx,&x)); 21015f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(bb,&b)); 2102365a8a9eSBarry Smith PetscFunctionReturn(0); 210317ab2063SBarry Smith } 210417ab2063SBarry Smith 2105dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 210617ab2063SBarry Smith { 2107416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21084e220ebcSLois Curfman McInnes 21093a40ed3dSBarry Smith PetscFunctionBegin; 21104e220ebcSLois Curfman McInnes info->block_size = 1.0; 21113966268fSBarry Smith info->nz_allocated = a->maxnz; 21123966268fSBarry Smith info->nz_used = a->nz; 21133966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21143966268fSBarry Smith info->assemblies = A->num_ass; 21153966268fSBarry Smith info->mallocs = A->info.mallocs; 21167adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2117d5f3da31SBarry Smith if (A->factortype) { 21184e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21194e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21204e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21214e220ebcSLois Curfman McInnes } else { 21224e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21234e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21244e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21254e220ebcSLois Curfman McInnes } 21263a40ed3dSBarry Smith PetscFunctionReturn(0); 212717ab2063SBarry Smith } 212817ab2063SBarry Smith 21292b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 213017ab2063SBarry Smith { 2131416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2132c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 213397b48c8fSBarry Smith const PetscScalar *xx; 21342e5835c6SStefano Zampini PetscScalar *bb,*aa; 2135c7da8527SEric Chamberland PetscInt d = 0; 213617ab2063SBarry Smith 21373a40ed3dSBarry Smith PetscFunctionBegin; 213897b48c8fSBarry Smith if (x && b) { 21395f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(x,&xx)); 21405f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(b,&bb)); 214197b48c8fSBarry Smith for (i=0; i<N; i++) { 21422c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]); 2143447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 214497b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 214597b48c8fSBarry Smith } 21465f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(x,&xx)); 21475f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(b,&bb)); 214897b48c8fSBarry Smith } 214997b48c8fSBarry Smith 21505f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 2151a9817697SBarry Smith if (a->keepnonzeropattern) { 2152f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 21532c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]); 21545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]])); 2155f1e2ffcdSBarry Smith } 2156f4df32b1SMatthew Knepley if (diag != 0.0) { 2157c7da8527SEric Chamberland for (i=0; i<N; i++) { 2158c7da8527SEric Chamberland d = rows[i]; 2159447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 21602c71b3e2SJacob Faibussowitsch PetscCheckFalse(a->diag[d] >= a->i[d+1],PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %" PetscInt_FMT,d); 2161c7da8527SEric Chamberland } 2162f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2163447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 21642e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 2165f1e2ffcdSBarry Smith } 2166f1e2ffcdSBarry Smith } 2167f1e2ffcdSBarry Smith } else { 2168f4df32b1SMatthew Knepley if (diag != 0.0) { 216917ab2063SBarry Smith for (i=0; i<N; i++) { 21702c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]); 21717ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2172447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2173447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2174447d62f5SStefano Zampini } else { 2175416022c9SBarry Smith a->ilen[rows[i]] = 1; 21762e5835c6SStefano Zampini aa[a->i[rows[i]]] = diag; 2177bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2178447d62f5SStefano Zampini } 2179447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 21805f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES)); 218117ab2063SBarry Smith } 218217ab2063SBarry Smith } 21833a40ed3dSBarry Smith } else { 218417ab2063SBarry Smith for (i=0; i<N; i++) { 21852c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]); 2186416022c9SBarry Smith a->ilen[rows[i]] = 0; 218717ab2063SBarry Smith } 218817ab2063SBarry Smith } 2189e56f5c9eSBarry Smith A->nonzerostate++; 2190f1e2ffcdSBarry Smith } 21915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 21925f80ce2aSJacob Faibussowitsch CHKERRQ((*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY)); 21933a40ed3dSBarry Smith PetscFunctionReturn(0); 219417ab2063SBarry Smith } 219517ab2063SBarry Smith 21966e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 21976e169961SBarry Smith { 21986e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21996e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22002b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22016e169961SBarry Smith const PetscScalar *xx; 22022e5835c6SStefano Zampini PetscScalar *bb,*aa; 22036e169961SBarry Smith 22046e169961SBarry Smith PetscFunctionBegin; 22052e5835c6SStefano Zampini if (!N) PetscFunctionReturn(0); 22065f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&aa)); 22076e169961SBarry Smith if (x && b) { 22085f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(x,&xx)); 22095f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArray(b,&bb)); 22102b40b63fSBarry Smith vecs = PETSC_TRUE; 22116e169961SBarry Smith } 22125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(A->rmap->n,&zeroed)); 22136e169961SBarry Smith for (i=0; i<N; i++) { 22142c71b3e2SJacob Faibussowitsch PetscCheckFalse(rows[i] < 0 || rows[i] > m,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %" PetscInt_FMT " out of range", rows[i]); 22155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]])); 22162205254eSKarl Rupp 22176e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22186e169961SBarry Smith } 22196e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22206e169961SBarry Smith if (!zeroed[i]) { 22216e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22224cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22232e5835c6SStefano Zampini if (vecs) bb[i] -= aa[j]*xx[a->j[j]]; 22242e5835c6SStefano Zampini aa[j] = 0.0; 22256e169961SBarry Smith } 22266e169961SBarry Smith } 22274cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22286e169961SBarry Smith } 22296e169961SBarry Smith if (x && b) { 22305f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(x,&xx)); 22315f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArray(b,&bb)); 22326e169961SBarry Smith } 22335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(zeroed)); 22346e169961SBarry Smith if (diag != 0.0) { 22355f80ce2aSJacob Faibussowitsch CHKERRQ(MatMissingDiagonal_SeqAIJ(A,&missing,&d)); 22361d5a398dSstefano_zampini if (missing) { 22371d5a398dSstefano_zampini for (i=0; i<N; i++) { 22384cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22392c71b3e2SJacob Faibussowitsch PetscCheckFalse(a->nonew && rows[i] >= d,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %" PetscInt_FMT " (%" PetscInt_FMT ")",d,rows[i]); 22405f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES)); 22411d5a398dSstefano_zampini } 22421d5a398dSstefano_zampini } else { 22436e169961SBarry Smith for (i=0; i<N; i++) { 22442e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 22456e169961SBarry Smith } 22466e169961SBarry Smith } 22471d5a398dSstefano_zampini } 22485f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&aa)); 22495f80ce2aSJacob Faibussowitsch CHKERRQ((*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY)); 22506e169961SBarry Smith PetscFunctionReturn(0); 22516e169961SBarry Smith } 22526e169961SBarry Smith 2253a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 225417ab2063SBarry Smith { 2255fff043a9SJunchao Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2256fff043a9SJunchao Zhang const PetscScalar *aa; 2257fff043a9SJunchao Zhang PetscInt *itmp; 225817ab2063SBarry Smith 22593a40ed3dSBarry Smith PetscFunctionBegin; 22605f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 2261416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 22622e5835c6SStefano Zampini if (v) *v = (PetscScalar*)(aa + a->i[row]); 226317ab2063SBarry Smith if (idx) { 2264bfeeae90SHong Zhang itmp = a->j + a->i[row]; 226526fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2266f4259b30SLisandro Dalcin else *idx = NULL; 226717ab2063SBarry Smith } 22685f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 22693a40ed3dSBarry Smith PetscFunctionReturn(0); 227017ab2063SBarry Smith } 227117ab2063SBarry Smith 2272a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 227317ab2063SBarry Smith { 22743a40ed3dSBarry Smith PetscFunctionBegin; 2275cb4a9cd9SHong Zhang if (nz) *nz = 0; 22762e5835c6SStefano Zampini if (idx) *idx = NULL; 22772e5835c6SStefano Zampini if (v) *v = NULL; 22783a40ed3dSBarry Smith PetscFunctionReturn(0); 227917ab2063SBarry Smith } 228017ab2063SBarry Smith 2281dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 228217ab2063SBarry Smith { 2283416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22842e5835c6SStefano Zampini const MatScalar *v; 228536db0b34SBarry Smith PetscReal sum = 0.0; 228697f1f81fSBarry Smith PetscInt i,j; 228717ab2063SBarry Smith 22883a40ed3dSBarry Smith PetscFunctionBegin; 22895f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&v)); 229017ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2291570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2292570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 229373cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2294570b7f6dSBarry Smith #else 2295416022c9SBarry Smith for (i=0; i<a->nz; i++) { 229636db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 229717ab2063SBarry Smith } 22988f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2299570b7f6dSBarry Smith #endif 23005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*a->nz)); 23013a40ed3dSBarry Smith } else if (type == NORM_1) { 230236db0b34SBarry Smith PetscReal *tmp; 230397f1f81fSBarry Smith PetscInt *jj = a->j; 23045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(A->cmap->n+1,&tmp)); 2305064f8208SBarry Smith *nrm = 0.0; 2306416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2307bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 230817ab2063SBarry Smith } 2309d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2310064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 231117ab2063SBarry Smith } 23125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(tmp)); 23135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(PetscMax(a->nz-1,0))); 23143a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2315064f8208SBarry Smith *nrm = 0.0; 2316d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 23172e5835c6SStefano Zampini const PetscScalar *v2 = v + a->i[j]; 231817ab2063SBarry Smith sum = 0.0; 2319416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 23202e5835c6SStefano Zampini sum += PetscAbsScalar(*v2); v2++; 232117ab2063SBarry Smith } 2322064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 232317ab2063SBarry Smith } 23245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(PetscMax(a->nz-1,0))); 2325f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23265f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&v)); 23273a40ed3dSBarry Smith PetscFunctionReturn(0); 232817ab2063SBarry Smith } 232917ab2063SBarry Smith 23304e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 23314e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 23324e938277SHong Zhang { 23334e938277SHong Zhang PetscInt i,j,anzj; 23344e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 23354e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 23364e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 23374e938277SHong Zhang 23384e938277SHong Zhang PetscFunctionBegin; 23394e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 23405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(an+1,&ati)); 23415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(ai[am],&atj)); 23425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(an,&atfill)); 23434e938277SHong Zhang 23444e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 23454e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 234626fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 23474e938277SHong Zhang /* Form ati for csr format of A^T. */ 234826fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 23494e938277SHong Zhang 23504e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 23515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(atfill,ati,an)); 23524e938277SHong Zhang 23534e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 23544e938277SHong Zhang for (i=0;i<am;i++) { 23554e938277SHong Zhang anzj = ai[i+1] - ai[i]; 23564e938277SHong Zhang for (j=0;j<anzj;j++) { 23574e938277SHong Zhang atj[atfill[*aj]] = i; 23584e938277SHong Zhang atfill[*aj++] += 1; 23594e938277SHong Zhang } 23604e938277SHong Zhang } 23614e938277SHong Zhang 23624e938277SHong Zhang /* Clean up temporary space and complete requests. */ 23635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(atfill)); 23645f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B)); 23655f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs))); 23665f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(*B,((PetscObject)A)->type_name)); 2367a2f3521dSMark F. Adams 23684e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 23694e938277SHong Zhang b->free_a = PETSC_FALSE; 23704e938277SHong Zhang b->free_ij = PETSC_TRUE; 23714e938277SHong Zhang b->nonew = 0; 23724e938277SHong Zhang PetscFunctionReturn(0); 23734e938277SHong Zhang } 23744e938277SHong Zhang 23757087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2376cd0d46ebSvictorle { 23773d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 237854f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 23792e5835c6SStefano Zampini const MatScalar *va,*vb; 238097f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2381cd0d46ebSvictorle 2382cd0d46ebSvictorle PetscFunctionBegin; 23835f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(A,&ma,&na)); 23845f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(B,&mb,&nb)); 23855485867bSBarry Smith if (ma!=nb || na!=mb) { 23865485867bSBarry Smith *f = PETSC_FALSE; 23875485867bSBarry Smith PetscFunctionReturn(0); 23885485867bSBarry Smith } 23895f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&va)); 23905f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(B,&vb)); 2391cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2392cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 23935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(ma,&aptr)); 23945f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(mb,&bptr)); 2395cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2396cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2397cd0d46ebSvictorle 2398cd0d46ebSvictorle *f = PETSC_TRUE; 2399cd0d46ebSvictorle for (i=0; i<ma; i++) { 2400cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 240197f1f81fSBarry Smith PetscInt idc,idr; 24025485867bSBarry Smith PetscScalar vc,vr; 2403cd0d46ebSvictorle /* column/row index/value */ 24045485867bSBarry Smith idc = adx[aptr[i]]; 24055485867bSBarry Smith idr = bdx[bptr[idc]]; 24065485867bSBarry Smith vc = va[aptr[i]]; 24075485867bSBarry Smith vr = vb[bptr[idc]]; 24085485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24095485867bSBarry Smith *f = PETSC_FALSE; 24105485867bSBarry Smith goto done; 2411cd0d46ebSvictorle } else { 24125485867bSBarry Smith aptr[i]++; 24135485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2414cd0d46ebSvictorle } 2415cd0d46ebSvictorle } 2416cd0d46ebSvictorle } 2417cd0d46ebSvictorle done: 24185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(aptr)); 24195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(bptr)); 24205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&va)); 24215f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(B,&vb)); 2422cd0d46ebSvictorle PetscFunctionReturn(0); 2423cd0d46ebSvictorle } 2424cd0d46ebSvictorle 24257087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24261cbb95d3SBarry Smith { 24273d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 242854f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 242954f21887SBarry Smith MatScalar *va,*vb; 24301cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 24311cbb95d3SBarry Smith 24321cbb95d3SBarry Smith PetscFunctionBegin; 24335f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(A,&ma,&na)); 24345f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(B,&mb,&nb)); 24351cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 24361cbb95d3SBarry Smith *f = PETSC_FALSE; 24371cbb95d3SBarry Smith PetscFunctionReturn(0); 24381cbb95d3SBarry Smith } 24391cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 24401cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 24411cbb95d3SBarry Smith va = aij->a; vb = bij->a; 24425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(ma,&aptr)); 24435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(mb,&bptr)); 24441cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 24451cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 24461cbb95d3SBarry Smith 24471cbb95d3SBarry Smith *f = PETSC_TRUE; 24481cbb95d3SBarry Smith for (i=0; i<ma; i++) { 24491cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 24501cbb95d3SBarry Smith PetscInt idc,idr; 24511cbb95d3SBarry Smith PetscScalar vc,vr; 24521cbb95d3SBarry Smith /* column/row index/value */ 24531cbb95d3SBarry Smith idc = adx[aptr[i]]; 24541cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 24551cbb95d3SBarry Smith vc = va[aptr[i]]; 24561cbb95d3SBarry Smith vr = vb[bptr[idc]]; 24571cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 24581cbb95d3SBarry Smith *f = PETSC_FALSE; 24591cbb95d3SBarry Smith goto done; 24601cbb95d3SBarry Smith } else { 24611cbb95d3SBarry Smith aptr[i]++; 24621cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 24631cbb95d3SBarry Smith } 24641cbb95d3SBarry Smith } 24651cbb95d3SBarry Smith } 24661cbb95d3SBarry Smith done: 24675f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(aptr)); 24685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(bptr)); 24691cbb95d3SBarry Smith PetscFunctionReturn(0); 24701cbb95d3SBarry Smith } 24711cbb95d3SBarry Smith 2472ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24739e29f15eSvictorle { 24749e29f15eSvictorle PetscFunctionBegin; 24755f80ce2aSJacob Faibussowitsch CHKERRQ(MatIsTranspose_SeqAIJ(A,A,tol,f)); 24769e29f15eSvictorle PetscFunctionReturn(0); 24779e29f15eSvictorle } 24789e29f15eSvictorle 2479ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24801cbb95d3SBarry Smith { 24811cbb95d3SBarry Smith PetscFunctionBegin; 24825f80ce2aSJacob Faibussowitsch CHKERRQ(MatIsHermitianTranspose_SeqAIJ(A,A,tol,f)); 24831cbb95d3SBarry Smith PetscFunctionReturn(0); 24841cbb95d3SBarry Smith } 24851cbb95d3SBarry Smith 2486dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 248717ab2063SBarry Smith { 2488416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2489fff8e43fSBarry Smith const PetscScalar *l,*r; 2490fff8e43fSBarry Smith PetscScalar x; 249154f21887SBarry Smith MatScalar *v; 2492fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2493fff8e43fSBarry Smith const PetscInt *jj; 249417ab2063SBarry Smith 24953a40ed3dSBarry Smith PetscFunctionBegin; 249617ab2063SBarry Smith if (ll) { 24973ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 24983ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 24995f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(ll,&m)); 25002c71b3e2SJacob Faibussowitsch PetscCheckFalse(m != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 25015f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(ll,&l)); 25025f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&v)); 250317ab2063SBarry Smith for (i=0; i<m; i++) { 250417ab2063SBarry Smith x = l[i]; 2505416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25062205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 250717ab2063SBarry Smith } 25085f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(ll,&l)); 25095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(nz)); 25105f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&v)); 251117ab2063SBarry Smith } 251217ab2063SBarry Smith if (rr) { 25135f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(rr,&n)); 25142c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 25155f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(rr,&r)); 25165f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&v)); 25172e5835c6SStefano Zampini jj = a->j; 25182205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 25195f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&v)); 25205f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(rr,&r)); 25215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(nz)); 252217ab2063SBarry Smith } 25235f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 25243a40ed3dSBarry Smith PetscFunctionReturn(0); 252517ab2063SBarry Smith } 252617ab2063SBarry Smith 25277dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 252817ab2063SBarry Smith { 2529db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 2530d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 253197f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 25325d0c19d7SBarry Smith const PetscInt *irow,*icol; 25332e5835c6SStefano Zampini const PetscScalar *aa; 25345d0c19d7SBarry Smith PetscInt nrows,ncols; 253597f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 253654f21887SBarry Smith MatScalar *a_new,*mat_a; 2537416022c9SBarry Smith Mat C; 2538cdc6f3adSToby Isaac PetscBool stride; 253917ab2063SBarry Smith 25403a40ed3dSBarry Smith PetscFunctionBegin; 25415f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(isrow,&irow)); 25425f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(isrow,&nrows)); 25435f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(iscol,&ncols)); 254417ab2063SBarry Smith 25455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride)); 2546ff718158SBarry Smith if (stride) { 25475f80ce2aSJacob Faibussowitsch CHKERRQ(ISStrideGetInfo(iscol,&first,&step)); 2548ff718158SBarry Smith } else { 2549ff718158SBarry Smith first = 0; 2550ff718158SBarry Smith step = 0; 2551ff718158SBarry Smith } 2552fee21e36SBarry Smith if (stride && step == 1) { 255302834360SBarry Smith /* special case of contiguous rows */ 25545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(nrows,&lens,nrows,&starts)); 255502834360SBarry Smith /* loop over new rows determining lens and starting points */ 255602834360SBarry Smith for (i=0; i<nrows; i++) { 2557bfeeae90SHong Zhang kstart = ai[irow[i]]; 2558a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2559a91a9bebSLisandro Dalcin starts[i] = kstart; 256002834360SBarry Smith for (k=kstart; k<kend; k++) { 2561bfeeae90SHong Zhang if (aj[k] >= first) { 256202834360SBarry Smith starts[i] = k; 256302834360SBarry Smith break; 256402834360SBarry Smith } 256502834360SBarry Smith } 2566a2744918SBarry Smith sum = 0; 256702834360SBarry Smith while (k < kend) { 2568bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2569a2744918SBarry Smith sum++; 257002834360SBarry Smith } 2571a2744918SBarry Smith lens[i] = sum; 257202834360SBarry Smith } 257302834360SBarry Smith /* create submatrix */ 2574cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 257597f1f81fSBarry Smith PetscInt n_cols,n_rows; 25765f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(*B,&n_rows,&n_cols)); 25772c71b3e2SJacob Faibussowitsch PetscCheckFalse(n_rows != nrows || n_cols != ncols,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 25785f80ce2aSJacob Faibussowitsch CHKERRQ(MatZeroEntries(*B)); 257908480c60SBarry Smith C = *B; 25803a40ed3dSBarry Smith } else { 25813bef6203SJed Brown PetscInt rbs,cbs; 25825f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),&C)); 25835f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE)); 25845f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetBlockSize(isrow,&rbs)); 25855f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetBlockSize(iscol,&cbs)); 25865f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizes(C,rbs,cbs)); 25875f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(C,((PetscObject)A)->type_name)); 25885f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens)); 258908480c60SBarry Smith } 2590db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2591db02288aSLois Curfman McInnes 259202834360SBarry Smith /* loop over rows inserting into submatrix */ 2593db02288aSLois Curfman McInnes a_new = c->a; 2594db02288aSLois Curfman McInnes j_new = c->j; 2595db02288aSLois Curfman McInnes i_new = c->i; 25965f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 259702834360SBarry Smith for (i=0; i<nrows; i++) { 2598a2744918SBarry Smith ii = starts[i]; 2599a2744918SBarry Smith lensi = lens[i]; 2600a2744918SBarry Smith for (k=0; k<lensi; k++) { 2601a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 260202834360SBarry Smith } 26035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(a_new,aa + starts[i],lensi)); 2604a2744918SBarry Smith a_new += lensi; 2605a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2606a2744918SBarry Smith c->ilen[i] = lensi; 260702834360SBarry Smith } 26085f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 26095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(lens,starts)); 26103a40ed3dSBarry Smith } else { 26115f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(iscol,&icol)); 26125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(oldcols,&smap)); 26135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(1+nrows,&lens)); 26144dcab191SBarry Smith for (i=0; i<ncols; i++) { 26156bdcaf15SBarry Smith PetscCheck(icol[i] < oldcols,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%" PetscInt_FMT "] %" PetscInt_FMT " >= A->cmap->n %" PetscInt_FMT,i,icol[i],oldcols); 26164dcab191SBarry Smith smap[icol[i]] = i+1; 26174dcab191SBarry Smith } 26184dcab191SBarry Smith 261902834360SBarry Smith /* determine lens of each row */ 262002834360SBarry Smith for (i=0; i<nrows; i++) { 2621bfeeae90SHong Zhang kstart = ai[irow[i]]; 262202834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 262302834360SBarry Smith lens[i] = 0; 262402834360SBarry Smith for (k=kstart; k<kend; k++) { 2625bfeeae90SHong Zhang if (smap[aj[k]]) { 262602834360SBarry Smith lens[i]++; 262702834360SBarry Smith } 262802834360SBarry Smith } 262902834360SBarry Smith } 263017ab2063SBarry Smith /* Create and fill new matrix */ 2631a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2632ace3abfcSBarry Smith PetscBool equal; 26330f5bd95cSBarry Smith 263499141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 26352c71b3e2SJacob Faibussowitsch PetscCheckFalse((*B)->rmap->n != nrows || (*B)->cmap->n != ncols,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 26365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal)); 2637*28b400f6SJacob Faibussowitsch PetscCheck(equal,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 26385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(c->ilen,(*B)->rmap->n)); 263908480c60SBarry Smith C = *B; 26403a40ed3dSBarry Smith } else { 26413bef6203SJed Brown PetscInt rbs,cbs; 26425f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),&C)); 26435f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE)); 26445f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetBlockSize(isrow,&rbs)); 26455f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetBlockSize(iscol,&cbs)); 26465f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizes(C,rbs,cbs)); 26475f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(C,((PetscObject)A)->type_name)); 26485f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens)); 264908480c60SBarry Smith } 26505f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 265199141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 265217ab2063SBarry Smith for (i=0; i<nrows; i++) { 265399141d43SSatish Balay row = irow[i]; 2654bfeeae90SHong Zhang kstart = ai[row]; 265599141d43SSatish Balay kend = kstart + a->ilen[row]; 2656bfeeae90SHong Zhang mat_i = c->i[i]; 265799141d43SSatish Balay mat_j = c->j + mat_i; 265899141d43SSatish Balay mat_a = c->a + mat_i; 265999141d43SSatish Balay mat_ilen = c->ilen + i; 266017ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2661bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2662ed480e8bSBarry Smith *mat_j++ = tcol - 1; 26632e5835c6SStefano Zampini *mat_a++ = aa[k]; 266499141d43SSatish Balay (*mat_ilen)++; 266599141d43SSatish Balay 266617ab2063SBarry Smith } 266717ab2063SBarry Smith } 266817ab2063SBarry Smith } 26695f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 267002834360SBarry Smith /* Free work space */ 26715f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(iscol,&icol)); 26725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(smap)); 26735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(lens)); 2674cdc6f3adSToby Isaac /* sort */ 2675cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2676cdc6f3adSToby Isaac PetscInt ilen; 2677cdc6f3adSToby Isaac 2678cdc6f3adSToby Isaac mat_i = c->i[i]; 2679cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2680cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2681cdc6f3adSToby Isaac ilen = c->ilen[i]; 26825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSortIntWithScalarArray(ilen,mat_j,mat_a)); 2683cdc6f3adSToby Isaac } 268402834360SBarry Smith } 26858c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 26865f80ce2aSJacob Faibussowitsch CHKERRQ(MatBindToCPU(C,A->boundtocpu)); 2687305c6ccfSStefano Zampini #endif 26885f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 26895f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 269017ab2063SBarry Smith 26915f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(isrow,&irow)); 2692416022c9SBarry Smith *B = C; 26933a40ed3dSBarry Smith PetscFunctionReturn(0); 269417ab2063SBarry Smith } 269517ab2063SBarry Smith 2696fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 269782d44351SHong Zhang { 269882d44351SHong Zhang Mat B; 269982d44351SHong Zhang 270082d44351SHong Zhang PetscFunctionBegin; 2701c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 27025f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(subComm,&B)); 27035f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n)); 27045f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizesFromMats(B,mat,mat)); 27055f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(B,MATSEQAIJ)); 27065f80ce2aSJacob Faibussowitsch CHKERRQ(MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE)); 270782d44351SHong Zhang *subMat = B; 2708c2d650bdSHong Zhang } else { 27095f80ce2aSJacob Faibussowitsch CHKERRQ(MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN)); 2710c2d650bdSHong Zhang } 271182d44351SHong Zhang PetscFunctionReturn(0); 271282d44351SHong Zhang } 271382d44351SHong Zhang 27149a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2715a871dcd8SBarry Smith { 271663b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 271763b91edcSBarry Smith Mat outA; 2718ace3abfcSBarry Smith PetscBool row_identity,col_identity; 271963b91edcSBarry Smith 27203a40ed3dSBarry Smith PetscFunctionBegin; 27212c71b3e2SJacob Faibussowitsch PetscCheckFalse(info->levels != 0,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 27221df811f5SHong Zhang 27235f80ce2aSJacob Faibussowitsch CHKERRQ(ISIdentity(row,&row_identity)); 27245f80ce2aSJacob Faibussowitsch CHKERRQ(ISIdentity(col,&col_identity)); 2725a871dcd8SBarry Smith 272663b91edcSBarry Smith outA = inA; 2727d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 27285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(inA->solvertype)); 27295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype)); 27302205254eSKarl Rupp 27315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)row)); 27325f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&a->row)); 27332205254eSKarl Rupp 2734c3122656SLisandro Dalcin a->row = row; 27352205254eSKarl Rupp 27365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)col)); 27375f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&a->col)); 27382205254eSKarl Rupp 2739c3122656SLisandro Dalcin a->col = col; 274063b91edcSBarry Smith 274136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 27425f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&a->icol)); 27435f80ce2aSJacob Faibussowitsch CHKERRQ(ISInvertPermutation(col,PETSC_DECIDE,&a->icol)); 27445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol)); 2745f0ec6fceSSatish Balay 274694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 27475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(inA->rmap->n+1,&a->solve_work)); 27485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar))); 274994a9d846SBarry Smith } 275063b91edcSBarry Smith 27515f80ce2aSJacob Faibussowitsch CHKERRQ(MatMarkDiagonal_SeqAIJ(inA)); 2752137fb511SHong Zhang if (row_identity && col_identity) { 27535f80ce2aSJacob Faibussowitsch CHKERRQ(MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info)); 2754137fb511SHong Zhang } else { 27555f80ce2aSJacob Faibussowitsch CHKERRQ(MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info)); 2756137fb511SHong Zhang } 27573a40ed3dSBarry Smith PetscFunctionReturn(0); 2758a871dcd8SBarry Smith } 2759a871dcd8SBarry Smith 2760f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2761f0b747eeSBarry Smith { 2762f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2763dfa0f9e5SStefano Zampini PetscScalar *v; 2764c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 27653a40ed3dSBarry Smith 27663a40ed3dSBarry Smith PetscFunctionBegin; 27675f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(inA,&v)); 27685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(a->nz,&bnz)); 2769dfa0f9e5SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one)); 27705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(a->nz)); 27715f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(inA,&v)); 27725f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(inA)); 27733a40ed3dSBarry Smith PetscFunctionReturn(0); 2774f0b747eeSBarry Smith } 2775f0b747eeSBarry Smith 2776f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 277716b64355SHong Zhang { 277816b64355SHong Zhang PetscInt i; 277916b64355SHong Zhang 278016b64355SHong Zhang PetscFunctionBegin; 278116b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 27825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr)); 278316b64355SHong Zhang 278416b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 27855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->sbuf2[i])); 278616b64355SHong Zhang } 27875f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1)); 278816b64355SHong Zhang 278916b64355SHong Zhang if (submatj->rbuf1) { 27905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->rbuf1[0])); 27915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->rbuf1)); 279216b64355SHong Zhang } 279316b64355SHong Zhang 279416b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 27955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->rbuf3[i])); 279616b64355SHong Zhang } 27975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3)); 27985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->pa)); 279916b64355SHong Zhang } 280016b64355SHong Zhang 280116b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 28025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableDestroy((PetscTable*)&submatj->rmap)); 28035f80ce2aSJacob Faibussowitsch if (submatj->cmap_loc) CHKERRQ(PetscFree(submatj->cmap_loc)); 28045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->rmap_loc)); 280516b64355SHong Zhang #else 28065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->rmap)); 280716b64355SHong Zhang #endif 280816b64355SHong Zhang 280916b64355SHong Zhang if (!submatj->allcolumns) { 281016b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 28115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableDestroy((PetscTable*)&submatj->cmap)); 281216b64355SHong Zhang #else 28135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->cmap)); 281416b64355SHong Zhang #endif 281516b64355SHong Zhang } 28165f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj->row2proc)); 281716b64355SHong Zhang 28185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(submatj)); 281916b64355SHong Zhang PetscFunctionReturn(0); 282016b64355SHong Zhang } 282116b64355SHong Zhang 28220fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 282316b64355SHong Zhang { 282416b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 28255c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 282616b64355SHong Zhang 282716b64355SHong Zhang PetscFunctionBegin; 28285f80ce2aSJacob Faibussowitsch CHKERRQ((*submatj->destroy)(C)); 28295f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroySubMatrix_Private(submatj)); 283016b64355SHong Zhang PetscFunctionReturn(0); 283116b64355SHong Zhang } 283216b64355SHong Zhang 28332d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 28342d033e1fSHong Zhang { 28352d033e1fSHong Zhang PetscInt i; 28360fb991dcSHong Zhang Mat C; 28370fb991dcSHong Zhang Mat_SeqAIJ *c; 28380fb991dcSHong Zhang Mat_SubSppt *submatj; 28392d033e1fSHong Zhang 28402d033e1fSHong Zhang PetscFunctionBegin; 28412d033e1fSHong Zhang for (i=0; i<n; i++) { 28420fb991dcSHong Zhang C = (*mat)[i]; 28430fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 28440fb991dcSHong Zhang submatj = c->submatis1; 28452d033e1fSHong Zhang if (submatj) { 2846682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 28475f80ce2aSJacob Faibussowitsch CHKERRQ((*submatj->destroy)(C)); 28485f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroySubMatrix_Private(submatj)); 28495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(C->defaultvectype)); 28505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutDestroy(&C->rmap)); 28515f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutDestroy(&C->cmap)); 28525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscHeaderDestroy(&C)); 2853682e4c99SStefano Zampini } 28542d033e1fSHong Zhang } else { 28555f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&C)); 28562d033e1fSHong Zhang } 28572d033e1fSHong Zhang } 285886e85357SHong Zhang 285963a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 28605f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroySubMatrices_Dummy(n,mat)); 286163a75b2aSHong Zhang 28625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(*mat)); 28632d033e1fSHong Zhang PetscFunctionReturn(0); 28642d033e1fSHong Zhang } 28652d033e1fSHong Zhang 28667dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2867cddf8d76SBarry Smith { 286897f1f81fSBarry Smith PetscInt i; 2869cddf8d76SBarry Smith 28703a40ed3dSBarry Smith PetscFunctionBegin; 2871cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 28725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(n+1,B)); 2873cddf8d76SBarry Smith } 2874cddf8d76SBarry Smith 2875cddf8d76SBarry Smith for (i=0; i<n; i++) { 28765f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i])); 2877cddf8d76SBarry Smith } 28783a40ed3dSBarry Smith PetscFunctionReturn(0); 2879cddf8d76SBarry Smith } 2880cddf8d76SBarry Smith 288197f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 28824dcbc457SBarry Smith { 2883e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 28845d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 28855d0c19d7SBarry Smith const PetscInt *idx; 288697f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2887f1af5d2fSBarry Smith PetscBT table; 2888bbd702dbSSatish Balay 28893a40ed3dSBarry Smith PetscFunctionBegin; 2890d0f46423SBarry Smith m = A->rmap->n; 2891e4d965acSSatish Balay ai = a->i; 2892bfeeae90SHong Zhang aj = a->j; 28938a047759SSatish Balay 28942c71b3e2SJacob Faibussowitsch PetscCheckFalse(ov < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 289506763907SSatish Balay 28965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m+1,&nidx)); 28975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBTCreate(m,&table)); 289806763907SSatish Balay 2899e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2900b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2901e4d965acSSatish Balay isz = 0; 29025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBTMemzero(m,table)); 2903e4d965acSSatish Balay 2904e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29055f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(is[i],&idx)); 29065f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(is[i],&n)); 2907e4d965acSSatish Balay 2908dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2909e4d965acSSatish Balay for (j=0; j<n; ++j) { 29102205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 29114dcbc457SBarry Smith } 29125f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(is[i],&idx)); 29135f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&is[i])); 2914e4d965acSSatish Balay 291504a348a9SBarry Smith k = 0; 291604a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 291704a348a9SBarry Smith n = isz; 291806763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2919e4d965acSSatish Balay row = nidx[k]; 2920e4d965acSSatish Balay start = ai[row]; 2921e4d965acSSatish Balay end = ai[row+1]; 292204a348a9SBarry Smith for (l = start; l<end; l++) { 2923efb16452SHong Zhang val = aj[l]; 29242205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2925e4d965acSSatish Balay } 2926e4d965acSSatish Balay } 2927e4d965acSSatish Balay } 29285f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i))); 2929e4d965acSSatish Balay } 29305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBTDestroy(&table)); 29315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(nidx)); 29323a40ed3dSBarry Smith PetscFunctionReturn(0); 29334dcbc457SBarry Smith } 293417ab2063SBarry Smith 29350513a670SBarry Smith /* -------------------------------------------------------------- */ 2936dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 29370513a670SBarry Smith { 29380513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29393b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 29405d0c19d7SBarry Smith const PetscInt *row,*col; 29415d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 294256cd22aeSBarry Smith IS icolp,irowp; 29430298fd71SBarry Smith PetscInt *cwork = NULL; 29440298fd71SBarry Smith PetscScalar *vwork = NULL; 29450513a670SBarry Smith 29463a40ed3dSBarry Smith PetscFunctionBegin; 29475f80ce2aSJacob Faibussowitsch CHKERRQ(ISInvertPermutation(rowp,PETSC_DECIDE,&irowp)); 29485f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(irowp,&row)); 29495f80ce2aSJacob Faibussowitsch CHKERRQ(ISInvertPermutation(colp,PETSC_DECIDE,&icolp)); 29505f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(icolp,&col)); 29510513a670SBarry Smith 29520513a670SBarry Smith /* determine lengths of permuted rows */ 29535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m+1,&lens)); 29542205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 29555f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),B)); 29565f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(*B,m,n,m,n)); 29575f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizesFromMats(*B,A,A)); 29585f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(*B,((PetscObject)A)->type_name)); 29595f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens)); 29605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(lens)); 29610513a670SBarry Smith 29625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(n,&cnew)); 29630513a670SBarry Smith for (i=0; i<m; i++) { 29645f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork)); 29652205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 29665f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES)); 29675f80ce2aSJacob Faibussowitsch CHKERRQ(MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork)); 29680513a670SBarry Smith } 29695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(cnew)); 29702205254eSKarl Rupp 29713c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 29722205254eSKarl Rupp 29738c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 29745f80ce2aSJacob Faibussowitsch CHKERRQ(MatBindToCPU(*B,A->boundtocpu)); 29759fe5e383SStefano Zampini #endif 29765f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY)); 29775f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY)); 29785f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(irowp,&row)); 29795f80ce2aSJacob Faibussowitsch CHKERRQ(ISRestoreIndices(icolp,&col)); 29805f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&irowp)); 29815f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&icolp)); 29826768869dSprj- if (rowp == colp) { 29835f80ce2aSJacob Faibussowitsch CHKERRQ(MatPropagateSymmetryOptions(A,*B)); 29846768869dSprj- } 29853a40ed3dSBarry Smith PetscFunctionReturn(0); 29860513a670SBarry Smith } 29870513a670SBarry Smith 2988dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2989cb5b572fSBarry Smith { 2990cb5b572fSBarry Smith PetscFunctionBegin; 299133f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 299233f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2993be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2994be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 29952e5835c6SStefano Zampini const PetscScalar *aa; 2996be6bf707SBarry Smith 29975f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 29982c71b3e2SJacob Faibussowitsch PetscCheckFalse(a->i[A->rmap->n] != b->i[B->rmap->n],PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different %" PetscInt_FMT " != %" PetscInt_FMT,a->i[A->rmap->n],b->i[B->rmap->n]); 29995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(b->a,aa,a->i[A->rmap->n])); 30005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectStateIncrease((PetscObject)B)); 30015f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 3002cb5b572fSBarry Smith } else { 30035f80ce2aSJacob Faibussowitsch CHKERRQ(MatCopy_Basic(A,B,str)); 3004cb5b572fSBarry Smith } 3005cb5b572fSBarry Smith PetscFunctionReturn(0); 3006cb5b572fSBarry Smith } 3007cb5b572fSBarry Smith 30084994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3009273d9f13SBarry Smith { 3010273d9f13SBarry Smith PetscFunctionBegin; 30115f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL)); 3012273d9f13SBarry Smith PetscFunctionReturn(0); 3013273d9f13SBarry Smith } 3014273d9f13SBarry Smith 3015f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 30166c0721eeSBarry Smith { 30176c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30186e111a19SKarl Rupp 30196c0721eeSBarry Smith PetscFunctionBegin; 30206c0721eeSBarry Smith *array = a->a; 30216c0721eeSBarry Smith PetscFunctionReturn(0); 30226c0721eeSBarry Smith } 30236c0721eeSBarry Smith 3024f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 30256c0721eeSBarry Smith { 30266c0721eeSBarry Smith PetscFunctionBegin; 3027f38c1e66SStefano Zampini *array = NULL; 30286c0721eeSBarry Smith PetscFunctionReturn(0); 30296c0721eeSBarry Smith } 3030273d9f13SBarry Smith 30318229c054SShri Abhyankar /* 30328229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 30338229c054SShri Abhyankar have different nonzero structure. 30348229c054SShri Abhyankar */ 3035b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3036ec7775f6SShri Abhyankar { 3037b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3038ec7775f6SShri Abhyankar 3039ec7775f6SShri Abhyankar PetscFunctionBegin; 3040ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3041ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3042b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3043b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3044b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 30458af7cee1SJed Brown nnz[i] = 0; 30468af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3047b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3048b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 30498af7cee1SJed Brown nnz[i]++; 30508af7cee1SJed Brown } 30518af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3052ec7775f6SShri Abhyankar } 3053ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3054ec7775f6SShri Abhyankar } 3055ec7775f6SShri Abhyankar 3056b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3057b264fe52SHong Zhang { 3058b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3059b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3060b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3061b264fe52SHong Zhang 3062b264fe52SHong Zhang PetscFunctionBegin; 3063b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 30645f80ce2aSJacob Faibussowitsch CHKERRQ(MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz)); 3065b264fe52SHong Zhang PetscFunctionReturn(0); 3066b264fe52SHong Zhang } 3067b264fe52SHong Zhang 3068f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3069ac90fabeSBarry Smith { 3070ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3071ac90fabeSBarry Smith 3072ac90fabeSBarry Smith PetscFunctionBegin; 3073134adf20SPierre Jolivet if (str == UNKNOWN_NONZERO_PATTERN || (PetscDefined(USE_DEBUG) && str == SAME_NONZERO_PATTERN)) { 3074134adf20SPierre Jolivet PetscBool e = x->nz == y->nz ? PETSC_TRUE : PETSC_FALSE; 3075134adf20SPierre Jolivet if (e) { 30765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e)); 307781fa06acSBarry Smith if (e) { 30785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycmp(x->j,y->j,y->nz,&e)); 3079134adf20SPierre Jolivet if (e) str = SAME_NONZERO_PATTERN; 308081fa06acSBarry Smith } 308181fa06acSBarry Smith } 308254c59aa7SJacob Faibussowitsch if (!e) PetscCheck(str != SAME_NONZERO_PATTERN,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MatStructure is not SAME_NONZERO_PATTERN"); 308381fa06acSBarry Smith } 3084ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 30852e5835c6SStefano Zampini const PetscScalar *xa; 30862e5835c6SStefano Zampini PetscScalar *ya,alpha = a; 308781fa06acSBarry Smith PetscBLASInt one = 1,bnz; 308881fa06acSBarry Smith 30895f80ce2aSJacob Faibussowitsch CHKERRQ(PetscBLASIntCast(x->nz,&bnz)); 30905f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(Y,&ya)); 30915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(X,&xa)); 30922e5835c6SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one)); 30935f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(X,&xa)); 30945f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(Y,&ya)); 30955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogFlops(2.0*bnz)); 30965f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(Y)); 30975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectStateIncrease((PetscObject)Y)); 3098ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 30995f80ce2aSJacob Faibussowitsch CHKERRQ(MatAXPY_Basic(Y,a,X,str)); 3100ac90fabeSBarry Smith } else { 31018229c054SShri Abhyankar Mat B; 31028229c054SShri Abhyankar PetscInt *nnz; 31035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(Y->rmap->N,&nnz)); 31045f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PetscObjectComm((PetscObject)Y),&B)); 31055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name)); 31065f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetLayouts(B,Y->rmap,Y->cmap)); 31075f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(B,((PetscObject)Y)->type_name)); 31085f80ce2aSJacob Faibussowitsch CHKERRQ(MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz)); 31095f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(B,0,nnz)); 31105f80ce2aSJacob Faibussowitsch CHKERRQ(MatAXPY_BasicWithPreallocation(B,Y,a,X,str)); 31115f80ce2aSJacob Faibussowitsch CHKERRQ(MatHeaderMerge(Y,&B)); 31125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(nnz)); 3113ac90fabeSBarry Smith } 3114ac90fabeSBarry Smith PetscFunctionReturn(0); 3115ac90fabeSBarry Smith } 3116ac90fabeSBarry Smith 31172726fb6dSPierre Jolivet PETSC_INTERN PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3118354c94deSBarry Smith { 3119354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3120354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3121354c94deSBarry Smith PetscInt i,nz; 3122354c94deSBarry Smith PetscScalar *a; 3123354c94deSBarry Smith 3124354c94deSBarry Smith PetscFunctionBegin; 3125354c94deSBarry Smith nz = aij->nz; 31265f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(mat,&a)); 31272205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 31285f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(mat,&a)); 3129354c94deSBarry Smith #else 3130354c94deSBarry Smith PetscFunctionBegin; 3131354c94deSBarry Smith #endif 3132354c94deSBarry Smith PetscFunctionReturn(0); 3133354c94deSBarry Smith } 3134354c94deSBarry Smith 3135985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3136e34fafa9SBarry Smith { 3137e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3138d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3139e34fafa9SBarry Smith PetscReal atmp; 3140985db425SBarry Smith PetscScalar *x; 3141ce496241SStefano Zampini const MatScalar *aa,*av; 3142e34fafa9SBarry Smith 3143e34fafa9SBarry Smith PetscFunctionBegin; 3144*28b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 31455f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&av)); 3146ce496241SStefano Zampini aa = av; 3147e34fafa9SBarry Smith ai = a->i; 3148e34fafa9SBarry Smith aj = a->j; 3149e34fafa9SBarry Smith 31505f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(v,0.0)); 31515f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(v,&x)); 31525f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(v,&n)); 31532c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3154e34fafa9SBarry Smith for (i=0; i<m; i++) { 3155e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3156e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3157985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3158985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3159985db425SBarry Smith aa++; aj++; 3160985db425SBarry Smith } 3161985db425SBarry Smith } 31625f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(v,&x)); 31635f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&av)); 3164985db425SBarry Smith PetscFunctionReturn(0); 3165985db425SBarry Smith } 3166985db425SBarry Smith 3167985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3168985db425SBarry Smith { 3169985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3170d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3171985db425SBarry Smith PetscScalar *x; 3172ce496241SStefano Zampini const MatScalar *aa,*av; 3173985db425SBarry Smith 3174985db425SBarry Smith PetscFunctionBegin; 3175*28b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 31765f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&av)); 3177ce496241SStefano Zampini aa = av; 3178985db425SBarry Smith ai = a->i; 3179985db425SBarry Smith aj = a->j; 3180985db425SBarry Smith 31815f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(v,0.0)); 31825f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(v,&x)); 31835f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(v,&n)); 31842c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3185985db425SBarry Smith for (i=0; i<m; i++) { 3186985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3187d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3188985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3189985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3190985db425SBarry Smith x[i] = 0.0; 3191985db425SBarry Smith if (idx) { 3192985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3193985db425SBarry Smith if (aj[j] > j) { 3194985db425SBarry Smith idx[i] = j; 3195985db425SBarry Smith break; 3196985db425SBarry Smith } 3197985db425SBarry Smith } 31981a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 31991a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3200985db425SBarry Smith } 3201985db425SBarry Smith } 3202985db425SBarry Smith for (j=0; j<ncols; j++) { 3203985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3204985db425SBarry Smith aa++; aj++; 3205985db425SBarry Smith } 3206985db425SBarry Smith } 32075f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(v,&x)); 32085f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&av)); 3209985db425SBarry Smith PetscFunctionReturn(0); 3210985db425SBarry Smith } 3211985db425SBarry Smith 3212c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3213c87e5d42SMatthew Knepley { 3214c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3215c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3216ce496241SStefano Zampini PetscScalar *x; 3217ce496241SStefano Zampini const MatScalar *aa,*av; 3218c87e5d42SMatthew Knepley 3219c87e5d42SMatthew Knepley PetscFunctionBegin; 32205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&av)); 3221ce496241SStefano Zampini aa = av; 3222c87e5d42SMatthew Knepley ai = a->i; 3223c87e5d42SMatthew Knepley aj = a->j; 3224c87e5d42SMatthew Knepley 32255f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(v,0.0)); 32265f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(v,&x)); 32275f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(v,&n)); 32282c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != m,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %" PetscInt_FMT " vs. %" PetscInt_FMT " rows", m, n); 3229c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3230c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3231f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3232f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3233f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3234f07e67edSHong Zhang x[i] = 0.0; 3235f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3236289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3237f07e67edSHong Zhang if (aj[j] > j) { 3238f07e67edSHong Zhang idx[i] = j; 32392205254eSKarl Rupp break; 32402205254eSKarl Rupp } 3241289a08f5SMatthew Knepley } 3242f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3243f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3244f07e67edSHong Zhang } 3245289a08f5SMatthew Knepley } 3246c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3247f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3248c87e5d42SMatthew Knepley aa++; aj++; 3249c87e5d42SMatthew Knepley } 3250c87e5d42SMatthew Knepley } 32515f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(v,&x)); 32525f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&av)); 3253c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3254c87e5d42SMatthew Knepley } 3255c87e5d42SMatthew Knepley 3256985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3257985db425SBarry Smith { 3258985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3259d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3260d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3261985db425SBarry Smith PetscScalar *x; 3262ce496241SStefano Zampini const MatScalar *aa,*av; 3263985db425SBarry Smith 3264985db425SBarry Smith PetscFunctionBegin; 3265*28b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32665f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&av)); 3267ce496241SStefano Zampini aa = av; 3268985db425SBarry Smith ai = a->i; 3269985db425SBarry Smith aj = a->j; 3270985db425SBarry Smith 32715f80ce2aSJacob Faibussowitsch CHKERRQ(VecSet(v,0.0)); 32725f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(v,&x)); 32735f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(v,&n)); 32742c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != m,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3275985db425SBarry Smith for (i=0; i<m; i++) { 3276985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3277d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3278985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3279985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3280985db425SBarry Smith x[i] = 0.0; 3281985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3282985db425SBarry Smith for (j=0; j<ncols; j++) { 3283985db425SBarry Smith if (aj[j] > j) { 3284985db425SBarry Smith idx[i] = j; 3285985db425SBarry Smith break; 3286985db425SBarry Smith } 3287985db425SBarry Smith } 3288fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3289fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3290985db425SBarry Smith } 3291985db425SBarry Smith } 3292985db425SBarry Smith for (j=0; j<ncols; j++) { 3293985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3294985db425SBarry Smith aa++; aj++; 3295e34fafa9SBarry Smith } 3296e34fafa9SBarry Smith } 32975f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(v,&x)); 32985f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&av)); 3299e34fafa9SBarry Smith PetscFunctionReturn(0); 3300e34fafa9SBarry Smith } 3301bbead8a2SBarry Smith 3302713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3303bbead8a2SBarry Smith { 3304bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 330533d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3306bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 33070da83c2eSBarry Smith const PetscReal shift = 0.0; 33081a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3309bbead8a2SBarry Smith 3310bbead8a2SBarry Smith PetscFunctionBegin; 3311a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 33124a0d0026SBarry Smith if (a->ibdiagvalid) { 33134a0d0026SBarry Smith if (values) *values = a->ibdiag; 33144a0d0026SBarry Smith PetscFunctionReturn(0); 33154a0d0026SBarry Smith } 33165f80ce2aSJacob Faibussowitsch CHKERRQ(MatMarkDiagonal_SeqAIJ(A)); 3317bbead8a2SBarry Smith if (!a->ibdiag) { 33185f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(bs2*mbs,&a->ibdiag)); 33195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar))); 3320bbead8a2SBarry Smith } 3321bbead8a2SBarry Smith diag = a->ibdiag; 3322bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3323bbead8a2SBarry Smith /* factor and invert each block */ 3324bbead8a2SBarry Smith switch (bs) { 3325bbead8a2SBarry Smith case 1: 3326bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 33275f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,1,&i,1,&i,diag+i)); 3328ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3329ec1892c8SHong Zhang if (allowzeropivot) { 33307b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33317b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 33327b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 33335f80ce2aSJacob Faibussowitsch CHKERRQ(PetscInfo(A,"Zero pivot, row %" PetscInt_FMT " pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON)); 333498921bdaSJacob Faibussowitsch } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot, row %" PetscInt_FMT " pivot %g tolerance %g",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON); 3335ec1892c8SHong Zhang } 3336bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3337bbead8a2SBarry Smith } 3338bbead8a2SBarry Smith break; 3339bbead8a2SBarry Smith case 2: 3340bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3341bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 33425f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,2,ij,2,ij,diag)); 33435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected)); 33447b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_2(diag)); 3346bbead8a2SBarry Smith diag += 4; 3347bbead8a2SBarry Smith } 3348bbead8a2SBarry Smith break; 3349bbead8a2SBarry Smith case 3: 3350bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3351bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 33525f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,3,ij,3,ij,diag)); 33535f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected)); 33547b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_3(diag)); 3356bbead8a2SBarry Smith diag += 9; 3357bbead8a2SBarry Smith } 3358bbead8a2SBarry Smith break; 3359bbead8a2SBarry Smith case 4: 3360bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3361bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 33625f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,4,ij,4,ij,diag)); 33635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected)); 33647b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_4(diag)); 3366bbead8a2SBarry Smith diag += 16; 3367bbead8a2SBarry Smith } 3368bbead8a2SBarry Smith break; 3369bbead8a2SBarry Smith case 5: 3370bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3371bbead8a2SBarry 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; 33725f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,5,ij,5,ij,diag)); 33735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected)); 33747b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_5(diag)); 3376bbead8a2SBarry Smith diag += 25; 3377bbead8a2SBarry Smith } 3378bbead8a2SBarry Smith break; 3379bbead8a2SBarry Smith case 6: 3380bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3381bbead8a2SBarry 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; 33825f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,6,ij,6,ij,diag)); 33835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected)); 33847b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_6(diag)); 3386bbead8a2SBarry Smith diag += 36; 3387bbead8a2SBarry Smith } 3388bbead8a2SBarry Smith break; 3389bbead8a2SBarry Smith case 7: 3390bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3391bbead8a2SBarry 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; 33925f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,7,ij,7,ij,diag)); 33935f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected)); 33947b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_7(diag)); 3396bbead8a2SBarry Smith diag += 49; 3397bbead8a2SBarry Smith } 3398bbead8a2SBarry Smith break; 3399bbead8a2SBarry Smith default: 34005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ)); 3401bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3402bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3403bbead8a2SBarry Smith IJ[j] = bs*i + j; 3404bbead8a2SBarry Smith } 34055f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetValues(A,bs,IJ,bs,IJ,diag)); 34065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected)); 34077b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 34085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscKernel_A_gets_transpose_A_N(diag,bs)); 3409bbead8a2SBarry Smith diag += bs2; 3410bbead8a2SBarry Smith } 34115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree3(v_work,v_pivots,IJ)); 3412bbead8a2SBarry Smith } 3413bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3414bbead8a2SBarry Smith PetscFunctionReturn(0); 3415bbead8a2SBarry Smith } 3416bbead8a2SBarry Smith 341773a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 341873a71a0fSBarry Smith { 341973a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3420fff043a9SJunchao Zhang PetscScalar a,*aa; 342173a71a0fSBarry Smith PetscInt m,n,i,j,col; 342273a71a0fSBarry Smith 342373a71a0fSBarry Smith PetscFunctionBegin; 342473a71a0fSBarry Smith if (!x->assembled) { 34255f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(x,&m,&n)); 342673a71a0fSBarry Smith for (i=0; i<m; i++) { 342773a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 34285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomGetValue(rctx,&a)); 342973a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 34305f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES)); 343173a71a0fSBarry Smith } 343273a71a0fSBarry Smith } 3433e2ce353bSJunchao Zhang } else { 34345f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayWrite(x,&aa)); 34355f80ce2aSJacob Faibussowitsch for (i=0; i<aij->nz; i++) CHKERRQ(PetscRandomGetValue(rctx,aa+i)); 34365f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayWrite(x,&aa)); 3437e2ce353bSJunchao Zhang } 34385f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 34395f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 344073a71a0fSBarry Smith PetscFunctionReturn(0); 344173a71a0fSBarry Smith } 344273a71a0fSBarry Smith 3443679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3444679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3445679944adSJunchao Zhang { 3446679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3447679944adSJunchao Zhang PetscScalar a; 3448679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3449679944adSJunchao Zhang 3450679944adSJunchao Zhang PetscFunctionBegin; 3451679944adSJunchao Zhang nskip = high - low; 34525f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(x,&m,&n)); 3453679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3454679944adSJunchao Zhang for (i=0; i<m; i++) { 3455679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 34565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscRandomGetValue(rctx,&a)); 3457679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3458679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 34595f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES)); 3460679944adSJunchao Zhang } 3461e2ce353bSJunchao Zhang } 34625f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY)); 34635f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY)); 3464679944adSJunchao Zhang PetscFunctionReturn(0); 3465679944adSJunchao Zhang } 3466679944adSJunchao Zhang 3467682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 34680a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3469cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3470cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3471cb5b572fSBarry Smith MatMult_SeqAIJ, 347297304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 34737c922b88SBarry Smith MatMultTranspose_SeqAIJ, 34747c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3475f4259b30SLisandro Dalcin NULL, 3476f4259b30SLisandro Dalcin NULL, 3477f4259b30SLisandro Dalcin NULL, 3478f4259b30SLisandro Dalcin /* 10*/ NULL, 3479cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3480f4259b30SLisandro Dalcin NULL, 348141f059aeSBarry Smith MatSOR_SeqAIJ, 348291e9d3e2SHong Zhang MatTranspose_SeqAIJ, 348397304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3484cb5b572fSBarry Smith MatEqual_SeqAIJ, 3485cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3486cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3487cb5b572fSBarry Smith MatNorm_SeqAIJ, 3488f4259b30SLisandro Dalcin /* 20*/ NULL, 3489cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3490cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3491cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3492d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3493f4259b30SLisandro Dalcin NULL, 3494f4259b30SLisandro Dalcin NULL, 3495f4259b30SLisandro Dalcin NULL, 3496f4259b30SLisandro Dalcin NULL, 34974994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3498f4259b30SLisandro Dalcin NULL, 3499f4259b30SLisandro Dalcin NULL, 3500f4259b30SLisandro Dalcin NULL, 3501f4259b30SLisandro Dalcin NULL, 3502d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3503f4259b30SLisandro Dalcin NULL, 3504f4259b30SLisandro Dalcin NULL, 3505cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3506f4259b30SLisandro Dalcin NULL, 3507d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 35087dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3509cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3510cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3511cb5b572fSBarry Smith MatCopy_SeqAIJ, 3512d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3513cb5b572fSBarry Smith MatScale_SeqAIJ, 35147d68702bSBarry Smith MatShift_SeqAIJ, 351579299369SBarry Smith MatDiagonalSet_SeqAIJ, 35166e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 351773a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 35183b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 35193b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 35203b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3521a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 352293dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3523f4259b30SLisandro Dalcin NULL, 3524f4259b30SLisandro Dalcin NULL, 3525cda55fadSBarry Smith MatPermute_SeqAIJ, 3526f4259b30SLisandro Dalcin NULL, 3527f4259b30SLisandro Dalcin /* 59*/ NULL, 3528b9b97703SBarry Smith MatDestroy_SeqAIJ, 3529b9b97703SBarry Smith MatView_SeqAIJ, 3530f4259b30SLisandro Dalcin NULL, 3531f4259b30SLisandro Dalcin NULL, 3532f4259b30SLisandro Dalcin /* 64*/ NULL, 3533321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3534f4259b30SLisandro Dalcin NULL, 3535f4259b30SLisandro Dalcin NULL, 3536f4259b30SLisandro Dalcin NULL, 3537d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3538c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3539f4259b30SLisandro Dalcin NULL, 3540f4259b30SLisandro Dalcin NULL, 3541f4259b30SLisandro Dalcin NULL, 3542f4259b30SLisandro Dalcin /* 74*/ NULL, 35433acb8795SBarry Smith MatFDColoringApply_AIJ, 3544f4259b30SLisandro Dalcin NULL, 3545f4259b30SLisandro Dalcin NULL, 3546f4259b30SLisandro Dalcin NULL, 35476ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3548f4259b30SLisandro Dalcin NULL, 3549f4259b30SLisandro Dalcin NULL, 3550f4259b30SLisandro Dalcin NULL, 3551bc011b1eSHong Zhang MatLoad_SeqAIJ, 3552d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 35531cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3554f4259b30SLisandro Dalcin NULL, 3555f4259b30SLisandro Dalcin NULL, 3556f4259b30SLisandro Dalcin NULL, 3557f4259b30SLisandro Dalcin /* 89*/ NULL, 3558f4259b30SLisandro Dalcin NULL, 355926be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3560f4259b30SLisandro Dalcin NULL, 3561f4259b30SLisandro Dalcin NULL, 35628fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3563f4259b30SLisandro Dalcin NULL, 3564f4259b30SLisandro Dalcin NULL, 35656fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3566f4259b30SLisandro Dalcin NULL, 35674222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3568f4259b30SLisandro Dalcin NULL, 3569f4259b30SLisandro Dalcin NULL, 357087d4246cSBarry Smith MatConjugate_SeqAIJ, 3571f4259b30SLisandro Dalcin NULL, 3572d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 357399cafbc1SBarry Smith MatRealPart_SeqAIJ, 3574f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3575f4259b30SLisandro Dalcin NULL, 3576f4259b30SLisandro Dalcin NULL, 3577cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3578f4259b30SLisandro Dalcin NULL, 35792af78befSBarry Smith MatGetRowMin_SeqAIJ, 3580f4259b30SLisandro Dalcin NULL, 3581599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3582f4259b30SLisandro Dalcin /*114*/ NULL, 3583f4259b30SLisandro Dalcin NULL, 3584f4259b30SLisandro Dalcin NULL, 3585f4259b30SLisandro Dalcin NULL, 3586f4259b30SLisandro Dalcin NULL, 3587f4259b30SLisandro Dalcin /*119*/ NULL, 3588f4259b30SLisandro Dalcin NULL, 3589f4259b30SLisandro Dalcin NULL, 3590f4259b30SLisandro Dalcin NULL, 3591b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 35920716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3593a873a8cdSSam Reynolds MatGetColumnReductions_SeqAIJ, 359437868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 35950da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3596f4259b30SLisandro Dalcin NULL, 3597f4259b30SLisandro Dalcin /*129*/ NULL, 3598f4259b30SLisandro Dalcin NULL, 3599f4259b30SLisandro Dalcin NULL, 360075648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3601b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3602b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 36032b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3604f4259b30SLisandro Dalcin NULL, 3605f4259b30SLisandro Dalcin NULL, 36063964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3607f4259b30SLisandro Dalcin /*139*/NULL, 3608f4259b30SLisandro Dalcin NULL, 3609f4259b30SLisandro Dalcin NULL, 36103a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 36119c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 36124222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 36134222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3614f4259b30SLisandro Dalcin NULL, 3615f4259b30SLisandro Dalcin NULL 36169e29f15eSvictorle }; 361717ab2063SBarry Smith 36187087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3619bef8e0ddSBarry Smith { 3620bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 362197f1f81fSBarry Smith PetscInt i,nz,n; 3622bef8e0ddSBarry Smith 3623bef8e0ddSBarry Smith PetscFunctionBegin; 3624bef8e0ddSBarry Smith nz = aij->maxnz; 3625d0f46423SBarry Smith n = mat->rmap->n; 3626bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3627bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3628bef8e0ddSBarry Smith } 3629bef8e0ddSBarry Smith aij->nz = nz; 3630bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3631bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3632bef8e0ddSBarry Smith } 3633bef8e0ddSBarry Smith PetscFunctionReturn(0); 3634bef8e0ddSBarry Smith } 3635bef8e0ddSBarry Smith 3636a3bb6f32SFande Kong /* 3637ddea5d60SJunchao Zhang * Given a sparse matrix with global column indices, compact it by using a local column space. 3638ddea5d60SJunchao Zhang * The result matrix helps saving memory in other algorithms, such as MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3639ddea5d60SJunchao Zhang */ 3640a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3641a3bb6f32SFande Kong { 3642a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3643a3bb6f32SFande Kong PetscTable gid1_lid1; 3644a3bb6f32SFande Kong PetscTablePosition tpos; 364525b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 364625b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3647a3bb6f32SFande Kong 3648a3bb6f32SFande Kong PetscFunctionBegin; 3649a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3650a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3651a3bb6f32SFande Kong /* use a table */ 36525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1)); 3653a3bb6f32SFande Kong ec = 0; 365425b670f0SStefano Zampini for (i=0; i<nz; i++) { 365525b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 36565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableFind(gid1_lid1,gid1,&data)); 3657a3bb6f32SFande Kong if (!data) { 3658a3bb6f32SFande Kong /* one based table */ 36595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES)); 3660a3bb6f32SFande Kong } 3661a3bb6f32SFande Kong } 3662a3bb6f32SFande Kong /* form array of columns we need */ 36635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(ec,&garray)); 36645f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableGetHeadPosition(gid1_lid1,&tpos)); 3665a3bb6f32SFande Kong while (tpos) { 36665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid)); 3667a3bb6f32SFande Kong gid--; 3668a3bb6f32SFande Kong lid--; 3669a3bb6f32SFande Kong garray[lid] = gid; 3670a3bb6f32SFande Kong } 36715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSortInt(ec,garray)); /* sort, and rebuild */ 36725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableRemoveAll(gid1_lid1)); 3673a3bb6f32SFande Kong for (i=0; i<ec; i++) { 36745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES)); 3675a3bb6f32SFande Kong } 3676a3bb6f32SFande Kong /* compact out the extra columns in B */ 367725b670f0SStefano Zampini for (i=0; i<nz; i++) { 367825b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 36795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableFind(gid1_lid1,gid1,&lid)); 3680a3bb6f32SFande Kong lid--; 368125b670f0SStefano Zampini jj[i] = lid; 3682a3bb6f32SFande Kong } 36835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutDestroy(&mat->cmap)); 36845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTableDestroy(&gid1_lid1)); 36855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap)); 36865f80ce2aSJacob Faibussowitsch CHKERRQ(ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping)); 36875f80ce2aSJacob Faibussowitsch CHKERRQ(ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH)); 3688a3bb6f32SFande Kong PetscFunctionReturn(0); 3689a3bb6f32SFande Kong } 3690a3bb6f32SFande Kong 3691bef8e0ddSBarry Smith /*@ 3692bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3693bef8e0ddSBarry Smith in the matrix. 3694bef8e0ddSBarry Smith 3695bef8e0ddSBarry Smith Input Parameters: 3696bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3697bef8e0ddSBarry Smith - indices - the column indices 3698bef8e0ddSBarry Smith 369915091d37SBarry Smith Level: advanced 370015091d37SBarry Smith 3701bef8e0ddSBarry Smith Notes: 3702bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3703bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3704bef8e0ddSBarry Smith of the MatSetValues() operation. 3705bef8e0ddSBarry Smith 3706bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3707d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3708bef8e0ddSBarry Smith 3709bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3710bef8e0ddSBarry Smith 3711b9617806SBarry Smith The indices should start with zero, not one. 3712b9617806SBarry Smith 3713bef8e0ddSBarry Smith @*/ 37147087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3715bef8e0ddSBarry Smith { 3716bef8e0ddSBarry Smith PetscFunctionBegin; 37170700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 37184482741eSBarry Smith PetscValidPointer(indices,2); 37195f80ce2aSJacob Faibussowitsch CHKERRQ(PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices))); 3720bef8e0ddSBarry Smith PetscFunctionReturn(0); 3721bef8e0ddSBarry Smith } 3722bef8e0ddSBarry Smith 3723be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3724be6bf707SBarry Smith 37257087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3726be6bf707SBarry Smith { 3727be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3728d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3729be6bf707SBarry Smith 3730be6bf707SBarry Smith PetscFunctionBegin; 3731*28b400f6SJacob Faibussowitsch PetscCheck(aij->nonew,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3732be6bf707SBarry Smith 3733be6bf707SBarry Smith /* allocate space for values if not already there */ 3734be6bf707SBarry Smith if (!aij->saved_values) { 37355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz+1,&aij->saved_values)); 37365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar))); 3737be6bf707SBarry Smith } 3738be6bf707SBarry Smith 3739be6bf707SBarry Smith /* copy values over */ 37405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(aij->saved_values,aij->a,nz)); 3741be6bf707SBarry Smith PetscFunctionReturn(0); 3742be6bf707SBarry Smith } 3743be6bf707SBarry Smith 3744be6bf707SBarry Smith /*@ 3745be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3746be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3747be6bf707SBarry Smith nonlinear portion. 3748be6bf707SBarry Smith 3749be6bf707SBarry Smith Collect on Mat 3750be6bf707SBarry Smith 3751be6bf707SBarry Smith Input Parameters: 37520e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3753be6bf707SBarry Smith 375415091d37SBarry Smith Level: advanced 375515091d37SBarry Smith 3756be6bf707SBarry Smith Common Usage, with SNESSolve(): 3757be6bf707SBarry Smith $ Create Jacobian matrix 3758be6bf707SBarry Smith $ Set linear terms into matrix 3759be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3760be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3761be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3762512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3763be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3764be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3765be6bf707SBarry Smith $ In your Jacobian routine 3766be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3767be6bf707SBarry Smith $ Set nonlinear terms in matrix 3768be6bf707SBarry Smith 3769be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3770be6bf707SBarry Smith $ // build linear portion of Jacobian 3771512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3772be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3773be6bf707SBarry Smith $ loop over nonlinear iterations 3774be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3775be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3776be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3777be6bf707SBarry Smith $ Solve linear system with Jacobian 3778be6bf707SBarry Smith $ endloop 3779be6bf707SBarry Smith 3780be6bf707SBarry Smith Notes: 3781be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3782512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3783be6bf707SBarry Smith calling this routine. 3784be6bf707SBarry Smith 37850c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 37860c468ba9SBarry Smith and does not allocated additional space. 37870c468ba9SBarry Smith 3788be6bf707SBarry Smith .seealso: MatRetrieveValues() 3789be6bf707SBarry Smith 3790be6bf707SBarry Smith @*/ 37917087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3792be6bf707SBarry Smith { 3793be6bf707SBarry Smith PetscFunctionBegin; 37940700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3795*28b400f6SJacob Faibussowitsch PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3796*28b400f6SJacob Faibussowitsch PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 37975f80ce2aSJacob Faibussowitsch CHKERRQ(PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat))); 3798be6bf707SBarry Smith PetscFunctionReturn(0); 3799be6bf707SBarry Smith } 3800be6bf707SBarry Smith 38017087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3802be6bf707SBarry Smith { 3803be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3804d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3805be6bf707SBarry Smith 3806be6bf707SBarry Smith PetscFunctionBegin; 3807*28b400f6SJacob Faibussowitsch PetscCheck(aij->nonew,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3808*28b400f6SJacob Faibussowitsch PetscCheck(aij->saved_values,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3809be6bf707SBarry Smith /* copy values over */ 38105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(aij->a,aij->saved_values,nz)); 3811be6bf707SBarry Smith PetscFunctionReturn(0); 3812be6bf707SBarry Smith } 3813be6bf707SBarry Smith 3814be6bf707SBarry Smith /*@ 3815be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3816be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3817be6bf707SBarry Smith nonlinear portion. 3818be6bf707SBarry Smith 3819be6bf707SBarry Smith Collect on Mat 3820be6bf707SBarry Smith 3821be6bf707SBarry Smith Input Parameters: 3822386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3823be6bf707SBarry Smith 382415091d37SBarry Smith Level: advanced 382515091d37SBarry Smith 3826be6bf707SBarry Smith .seealso: MatStoreValues() 3827be6bf707SBarry Smith 3828be6bf707SBarry Smith @*/ 38297087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3830be6bf707SBarry Smith { 3831be6bf707SBarry Smith PetscFunctionBegin; 38320700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3833*28b400f6SJacob Faibussowitsch PetscCheck(mat->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3834*28b400f6SJacob Faibussowitsch PetscCheck(!mat->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38355f80ce2aSJacob Faibussowitsch CHKERRQ(PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat))); 3836be6bf707SBarry Smith PetscFunctionReturn(0); 3837be6bf707SBarry Smith } 3838be6bf707SBarry Smith 3839be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 384017ab2063SBarry Smith /*@C 3841682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 38420d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 38436e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 384451c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 38452bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 384617ab2063SBarry Smith 3847d083f849SBarry Smith Collective 3848db81eaa0SLois Curfman McInnes 384917ab2063SBarry Smith Input Parameters: 3850db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 385117ab2063SBarry Smith . m - number of rows 385217ab2063SBarry Smith . n - number of columns 385317ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 385451c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 38550298fd71SBarry Smith (possibly different for each row) or NULL 385617ab2063SBarry Smith 385717ab2063SBarry Smith Output Parameter: 3858416022c9SBarry Smith . A - the matrix 385917ab2063SBarry Smith 3860175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3861f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3862175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3863175b88e8SBarry Smith 3864b259b22eSLois Curfman McInnes Notes: 386549a6f317SBarry Smith If nnz is given then nz is ignored 386649a6f317SBarry Smith 386717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 386817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 38690002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 387044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 387117ab2063SBarry Smith 387217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 38730298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 38743d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 38756da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 387617ab2063SBarry Smith 3877682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 38784fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3879682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 38806c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 38816c7ebb05SLois Curfman McInnes 38826c7ebb05SLois Curfman McInnes Options Database Keys: 3883698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 38849db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 388517ab2063SBarry Smith 3886027ccd11SLois Curfman McInnes Level: intermediate 3887027ccd11SLois Curfman McInnes 388869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 388936db0b34SBarry Smith 389017ab2063SBarry Smith @*/ 38917087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 389217ab2063SBarry Smith { 38933a40ed3dSBarry Smith PetscFunctionBegin; 38945f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(comm,A)); 38955f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(*A,m,n,m,n)); 38965f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(*A,MATSEQAIJ)); 38975f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz)); 3898273d9f13SBarry Smith PetscFunctionReturn(0); 3899273d9f13SBarry Smith } 3900273d9f13SBarry Smith 3901273d9f13SBarry Smith /*@C 3902273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3903273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3904273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3905273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3906273d9f13SBarry Smith 3907d083f849SBarry Smith Collective 3908273d9f13SBarry Smith 3909273d9f13SBarry Smith Input Parameters: 39101c4f3114SJed Brown + B - The matrix 3911273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3912273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39130298fd71SBarry Smith (possibly different for each row) or NULL 3914273d9f13SBarry Smith 3915273d9f13SBarry Smith Notes: 391649a6f317SBarry Smith If nnz is given then nz is ignored 391749a6f317SBarry Smith 3918273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3919273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3920273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3921273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3922273d9f13SBarry Smith 3923273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39240298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3925273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3926273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3927273d9f13SBarry Smith 3928aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3929aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3930aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3931aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3932aa95bbe8SBarry Smith 3933a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3934a96a251dSBarry Smith entries or columns indices 3935a96a251dSBarry Smith 3936273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3937273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3938273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3939273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3940273d9f13SBarry Smith 3941273d9f13SBarry Smith Options Database Keys: 3942698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 394347b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3944273d9f13SBarry Smith 3945273d9f13SBarry Smith Level: intermediate 3946273d9f13SBarry Smith 394719b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 394819b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 3949273d9f13SBarry Smith 3950273d9f13SBarry Smith @*/ 39517087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3952273d9f13SBarry Smith { 3953a23d5eceSKris Buschelman PetscFunctionBegin; 39546ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 39556ba663aaSJed Brown PetscValidType(B,1); 39565f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz))); 3957a23d5eceSKris Buschelman PetscFunctionReturn(0); 3958a23d5eceSKris Buschelman } 3959a23d5eceSKris Buschelman 39607087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3961a23d5eceSKris Buschelman { 3962273d9f13SBarry Smith Mat_SeqAIJ *b; 39632576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 396497f1f81fSBarry Smith PetscInt i; 3965273d9f13SBarry Smith 3966273d9f13SBarry Smith PetscFunctionBegin; 39672576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3968a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3969c461c341SBarry Smith skipallocation = PETSC_TRUE; 3970c461c341SBarry Smith nz = 0; 3971c461c341SBarry Smith } 39725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(B->rmap)); 39735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(B->cmap)); 3974899cda47SBarry Smith 3975435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 39762c71b3e2SJacob Faibussowitsch PetscCheckFalse(nz < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %" PetscInt_FMT,nz); 3977cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 3978d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 39792c71b3e2SJacob Faibussowitsch PetscCheckFalse(nnz[i] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %" PetscInt_FMT " value %" PetscInt_FMT,i,nnz[i]); 39802c71b3e2SJacob Faibussowitsch PetscCheckFalse(nnz[i] > B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %" PetscInt_FMT " value %" PetscInt_FMT " rowlength %" PetscInt_FMT,i,nnz[i],B->cmap->n); 3981b73539f3SBarry Smith } 3982b73539f3SBarry Smith } 3983b73539f3SBarry Smith 3984273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 39852205254eSKarl Rupp 3986273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3987273d9f13SBarry Smith 3988ab93d7beSBarry Smith if (!skipallocation) { 39892ee49352SLisandro Dalcin if (!b->imax) { 39905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(B->rmap->n,&b->imax)); 39915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt))); 3992071fcb05SBarry Smith } 3993071fcb05SBarry Smith if (!b->ilen) { 3994071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 39955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(B->rmap->n,&b->ilen)); 39965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt))); 3997071fcb05SBarry Smith } else { 39985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt))); 39992ee49352SLisandro Dalcin } 4000846b4da1SFande Kong if (!b->ipre) { 40015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(B->rmap->n,&b->ipre)); 40025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt))); 4003846b4da1SFande Kong } 4004273d9f13SBarry Smith if (!nnz) { 4005435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4006c62bd62aSJed Brown else if (nz < 0) nz = 1; 40075d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4008d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4009d0f46423SBarry Smith nz = nz*B->rmap->n; 4010273d9f13SBarry Smith } else { 4011c73702f5SBarry Smith PetscInt64 nz64 = 0; 4012c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 40135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscIntCast(nz64,&nz)); 4014273d9f13SBarry Smith } 4015ab93d7beSBarry Smith 4016273d9f13SBarry Smith /* allocate the matrix space */ 401753dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 40185f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i)); 4019396832f4SHong Zhang if (B->structure_only) { 40205f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nz,&b->j)); 40215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(B->rmap->n+1,&b->i)); 40225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt))); 4023396832f4SHong Zhang } else { 40245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i)); 40255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)))); 4026396832f4SHong Zhang } 4027bfeeae90SHong Zhang b->i[0] = 0; 4028d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 40295da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 40305da197adSKris Buschelman } 4031396832f4SHong Zhang if (B->structure_only) { 4032396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4033396832f4SHong Zhang b->free_a = PETSC_FALSE; 4034396832f4SHong Zhang } else { 4035273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4036e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4037396832f4SHong Zhang } 4038e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4039c461c341SBarry Smith } else { 4040e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4041e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4042c461c341SBarry Smith } 4043273d9f13SBarry Smith 4044846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4045846b4da1SFande Kong /* reserve user-requested sparsity */ 40465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(b->ipre,b->imax,B->rmap->n)); 4047846b4da1SFande Kong } 4048846b4da1SFande Kong 4049273d9f13SBarry Smith b->nz = 0; 4050273d9f13SBarry Smith b->maxnz = nz; 4051273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 40522205254eSKarl Rupp if (realalloc) { 40535f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE)); 40542205254eSKarl Rupp } 4055cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4056cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4057273d9f13SBarry Smith PetscFunctionReturn(0); 4058273d9f13SBarry Smith } 4059273d9f13SBarry Smith 4060846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4061846b4da1SFande Kong { 4062846b4da1SFande Kong Mat_SeqAIJ *a; 4063a5bbaf83SFande Kong PetscInt i; 4064846b4da1SFande Kong 4065846b4da1SFande Kong PetscFunctionBegin; 4066846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 406714d0e64fSAlex Lindsay 406814d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 406914d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 407014d0e64fSAlex Lindsay 4071846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 40722c814fdeSFande Kong /* if no saved info, we error out */ 4073*28b400f6SJacob Faibussowitsch PetscCheck(a->ipre,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info "); 40742c814fdeSFande Kong 40752c71b3e2SJacob Faibussowitsch PetscCheckFalse(!a->i || !a->j || !a->a || !a->imax || !a->ilen,PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Memory info is incomplete, and can not reset preallocation "); 40762c814fdeSFande Kong 40775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(a->imax,a->ipre,A->rmap->n)); 40785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(a->ilen,A->rmap->n)); 4079846b4da1SFande Kong a->i[0] = 0; 4080846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4081846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4082846b4da1SFande Kong } 4083846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4084846b4da1SFande Kong a->nz = 0; 4085846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4086846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4087846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4088846b4da1SFande Kong A->assembled = PETSC_FALSE; 4089846b4da1SFande Kong PetscFunctionReturn(0); 4090846b4da1SFande Kong } 4091846b4da1SFande Kong 409258d36128SBarry Smith /*@ 4093a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4094a1661176SMatthew Knepley 4095a1661176SMatthew Knepley Input Parameters: 4096a1661176SMatthew Knepley + B - the matrix 4097a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4098a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4099a1661176SMatthew Knepley - v - optional values in the matrix 4100a1661176SMatthew Knepley 4101a1661176SMatthew Knepley Level: developer 4102a1661176SMatthew Knepley 41036a9b8d82SBarry Smith Notes: 410458d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 410558d36128SBarry Smith 41066a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 41076a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 41086a9b8d82SBarry Smith 41096a9b8d82SBarry Smith Developer Notes: 41106a9b8d82SBarry Smith An optimization could be added to the implementation where it checks if the i, and j are identical to the current i and j and 41116a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 41126a9b8d82SBarry Smith 41136a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 41146a9b8d82SBarry Smith 41156a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4116a1661176SMatthew Knepley @*/ 4117a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4118a1661176SMatthew Knepley { 4119a1661176SMatthew Knepley PetscFunctionBegin; 41200700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 41216ba663aaSJed Brown PetscValidType(B,1); 41225f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v))); 4123a1661176SMatthew Knepley PetscFunctionReturn(0); 4124a1661176SMatthew Knepley } 4125a1661176SMatthew Knepley 41267087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4127a1661176SMatthew Knepley { 4128a1661176SMatthew Knepley PetscInt i; 4129a1661176SMatthew Knepley PetscInt m,n; 4130a1661176SMatthew Knepley PetscInt nz; 41316a9b8d82SBarry Smith PetscInt *nnz; 4132a1661176SMatthew Knepley 4133a1661176SMatthew Knepley PetscFunctionBegin; 41342c71b3e2SJacob Faibussowitsch PetscCheckFalse(Ii[0],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %" PetscInt_FMT, Ii[0]); 4135779a8d59SSatish Balay 41365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(B->rmap)); 41375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(B->cmap)); 4138779a8d59SSatish Balay 41395f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(B, &m, &n)); 41405f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m+1, &nnz)); 4141a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4142b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 41432c71b3e2SJacob Faibussowitsch PetscCheckFalse(nz < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %" PetscInt_FMT " has a negative number of columns %" PetscInt_FMT, i, nz); 4144a1661176SMatthew Knepley nnz[i] = nz; 4145a1661176SMatthew Knepley } 41465f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(B, 0, nnz)); 41475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(nnz)); 4148a1661176SMatthew Knepley 4149a1661176SMatthew Knepley for (i = 0; i < m; i++) { 41505f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES)); 4151a1661176SMatthew Knepley } 4152a1661176SMatthew Knepley 41535f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 41545f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 4155a1661176SMatthew Knepley 41565f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE)); 4157a1661176SMatthew Knepley PetscFunctionReturn(0); 4158a1661176SMatthew Knepley } 4159a1661176SMatthew Knepley 4160ad7e164aSPierre Jolivet /*@ 4161ad7e164aSPierre Jolivet MatSeqAIJKron - Computes C, the Kronecker product of A and B. 4162ad7e164aSPierre Jolivet 4163ad7e164aSPierre Jolivet Input Parameters: 4164ad7e164aSPierre Jolivet + A - left-hand side matrix 4165ad7e164aSPierre Jolivet . B - right-hand side matrix 4166ad7e164aSPierre Jolivet - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 4167ad7e164aSPierre Jolivet 4168ad7e164aSPierre Jolivet Output Parameter: 4169ad7e164aSPierre Jolivet . C - Kronecker product of A and B 4170ad7e164aSPierre Jolivet 4171ad7e164aSPierre Jolivet Level: intermediate 4172ad7e164aSPierre Jolivet 4173ad7e164aSPierre Jolivet Notes: 4174ad7e164aSPierre Jolivet MAT_REUSE_MATRIX can only be used when the nonzero structure of the product matrix has not changed from that last call to MatSeqAIJKron(). 4175ad7e164aSPierre Jolivet 4176ad7e164aSPierre Jolivet .seealso: MatCreateSeqAIJ(), MATSEQAIJ, MATKAIJ, MatReuse 4177ad7e164aSPierre Jolivet @*/ 4178ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron(Mat A,Mat B,MatReuse reuse,Mat *C) 4179ad7e164aSPierre Jolivet { 4180ad7e164aSPierre Jolivet PetscFunctionBegin; 4181ad7e164aSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4182ad7e164aSPierre Jolivet PetscValidType(A,1); 4183ad7e164aSPierre Jolivet PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4184ad7e164aSPierre Jolivet PetscValidType(B,2); 4185ad7e164aSPierre Jolivet PetscValidPointer(C,4); 4186ad7e164aSPierre Jolivet if (reuse == MAT_REUSE_MATRIX) { 4187ad7e164aSPierre Jolivet PetscValidHeaderSpecific(*C,MAT_CLASSID,4); 4188ad7e164aSPierre Jolivet PetscValidType(*C,4); 4189ad7e164aSPierre Jolivet } 41905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(A,"MatSeqAIJKron_C",(Mat,Mat,MatReuse,Mat*),(A,B,reuse,C))); 4191ad7e164aSPierre Jolivet PetscFunctionReturn(0); 4192ad7e164aSPierre Jolivet } 4193ad7e164aSPierre Jolivet 4194ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron_SeqAIJ(Mat A,Mat B,MatReuse reuse,Mat *C) 4195ad7e164aSPierre Jolivet { 4196ad7e164aSPierre Jolivet Mat newmat; 4197ad7e164aSPierre Jolivet Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4198ad7e164aSPierre Jolivet Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 4199ad7e164aSPierre Jolivet PetscScalar *v; 4200fff043a9SJunchao Zhang const PetscScalar *aa,*ba; 4201ad7e164aSPierre Jolivet PetscInt *i,*j,m,n,p,q,nnz = 0,am = A->rmap->n,bm = B->rmap->n,an = A->cmap->n, bn = B->cmap->n; 4202ad7e164aSPierre Jolivet PetscBool flg; 4203ad7e164aSPierre Jolivet 4204ad7e164aSPierre Jolivet PetscFunctionBegin; 4205*28b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4206*28b400f6SJacob Faibussowitsch PetscCheck(A->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4207*28b400f6SJacob Faibussowitsch PetscCheck(!B->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4208*28b400f6SJacob Faibussowitsch PetscCheck(B->assembled,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 42095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&flg)); 4210*28b400f6SJacob Faibussowitsch PetscCheck(flg,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatType %s",((PetscObject)B)->type_name); 42112c71b3e2SJacob Faibussowitsch PetscCheckFalse(reuse != MAT_INITIAL_MATRIX && reuse != MAT_REUSE_MATRIX,PETSC_COMM_SELF,PETSC_ERR_SUP,"MatReuse %d",(int)reuse); 4212ad7e164aSPierre Jolivet if (reuse == MAT_INITIAL_MATRIX) { 42135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(am*bm+1,&i,a->i[am]*b->i[bm],&j)); 42145f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_SELF,&newmat)); 42155f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(newmat,am*bm,an*bn,am*bm,an*bn)); 42165f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(newmat,MATAIJ)); 4217ad7e164aSPierre Jolivet i[0] = 0; 4218ad7e164aSPierre Jolivet for (m = 0; m < am; ++m) { 4219ad7e164aSPierre Jolivet for (p = 0; p < bm; ++p) { 4220ad7e164aSPierre Jolivet i[m*bm + p + 1] = i[m*bm + p] + (a->i[m+1] - a->i[m]) * (b->i[p+1] - b->i[p]); 4221ad7e164aSPierre Jolivet for (n = a->i[m]; n < a->i[m+1]; ++n) { 4222ad7e164aSPierre Jolivet for (q = b->i[p]; q < b->i[p+1]; ++q) { 4223ad7e164aSPierre Jolivet j[nnz++] = a->j[n]*bn + b->j[q]; 4224ad7e164aSPierre Jolivet } 4225ad7e164aSPierre Jolivet } 4226ad7e164aSPierre Jolivet } 4227ad7e164aSPierre Jolivet } 42285f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocationCSR(newmat,i,j,NULL)); 4229ad7e164aSPierre Jolivet *C = newmat; 42305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(i,j)); 4231ad7e164aSPierre Jolivet nnz = 0; 4232ad7e164aSPierre Jolivet } 42335f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(*C,&v)); 42345f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 42355f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(B,&ba)); 4236ad7e164aSPierre Jolivet for (m = 0; m < am; ++m) { 4237ad7e164aSPierre Jolivet for (p = 0; p < bm; ++p) { 4238ad7e164aSPierre Jolivet for (n = a->i[m]; n < a->i[m+1]; ++n) { 4239ad7e164aSPierre Jolivet for (q = b->i[p]; q < b->i[p+1]; ++q) { 4240fff043a9SJunchao Zhang v[nnz++] = aa[n] * ba[q]; 4241ad7e164aSPierre Jolivet } 4242ad7e164aSPierre Jolivet } 4243ad7e164aSPierre Jolivet } 4244ad7e164aSPierre Jolivet } 42455f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(*C,&v)); 42465f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 42475f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(B,&ba)); 4248ad7e164aSPierre Jolivet PetscFunctionReturn(0); 4249ad7e164aSPierre Jolivet } 4250ad7e164aSPierre Jolivet 4251c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4252af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4253170fe5c8SBarry Smith 4254170fe5c8SBarry Smith /* 4255170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4256170fe5c8SBarry Smith 4257170fe5c8SBarry Smith n p p 42582da392ccSBarry Smith [ ] [ ] [ ] 42592da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 42602da392ccSBarry Smith [ ] [ ] [ ] 4261170fe5c8SBarry Smith 4262170fe5c8SBarry Smith */ 4263170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4264170fe5c8SBarry Smith { 4265170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4266170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4267170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 426886214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4269170fe5c8SBarry Smith const PetscInt *ii,*idx; 4270170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4271170fe5c8SBarry Smith PetscScalar *c,*c_q; 427286214ceeSStefano Zampini PetscInt clda = sub_c->lda; 427386214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4274170fe5c8SBarry Smith 4275170fe5c8SBarry Smith PetscFunctionBegin; 4276d0f46423SBarry Smith m = A->rmap->n; 4277d0f46423SBarry Smith n = A->cmap->n; 4278d0f46423SBarry Smith p = B->cmap->n; 4279170fe5c8SBarry Smith a = sub_a->v; 4280170fe5c8SBarry Smith b = sub_b->a; 4281170fe5c8SBarry Smith c = sub_c->v; 428286214ceeSStefano Zampini if (clda == m) { 42835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(c,m*p)); 428486214ceeSStefano Zampini } else { 428586214ceeSStefano Zampini for (j=0;j<p;j++) 428686214ceeSStefano Zampini for (i=0;i<m;i++) 428786214ceeSStefano Zampini c[j*clda + i] = 0.0; 428886214ceeSStefano Zampini } 4289170fe5c8SBarry Smith ii = sub_b->i; 4290170fe5c8SBarry Smith idx = sub_b->j; 4291170fe5c8SBarry Smith for (i=0; i<n; i++) { 4292170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4293170fe5c8SBarry Smith while (q-->0) { 429486214ceeSStefano Zampini c_q = c + clda*(*idx); 429586214ceeSStefano Zampini a_q = a + alda*i; 4296854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4297170fe5c8SBarry Smith idx++; 4298170fe5c8SBarry Smith b++; 4299170fe5c8SBarry Smith } 4300170fe5c8SBarry Smith } 4301170fe5c8SBarry Smith PetscFunctionReturn(0); 4302170fe5c8SBarry Smith } 4303170fe5c8SBarry Smith 43044222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4305170fe5c8SBarry Smith { 4306d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 430786214ceeSStefano Zampini PetscBool cisdense; 4308170fe5c8SBarry Smith 4309170fe5c8SBarry Smith PetscFunctionBegin; 43102c71b3e2SJacob Faibussowitsch PetscCheckFalse(A->cmap->n != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %" PetscInt_FMT " != B->rmap->n %" PetscInt_FMT,A->cmap->n,B->rmap->n); 43115f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(C,m,n,m,n)); 43125f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizesFromMats(C,A,B)); 43135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"")); 431486214ceeSStefano Zampini if (!cisdense) { 43155f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(C,MATDENSE)); 431686214ceeSStefano Zampini } 43175f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetUp(C)); 4318d73949e8SHong Zhang 43194222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4320170fe5c8SBarry Smith PetscFunctionReturn(0); 4321170fe5c8SBarry Smith } 4322170fe5c8SBarry Smith 4323170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 43240bad9183SKris Buschelman /*MC 4325fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 43260bad9183SKris Buschelman based on compressed sparse row format. 43270bad9183SKris Buschelman 43280bad9183SKris Buschelman Options Database Keys: 43290bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 43300bad9183SKris Buschelman 43310bad9183SKris Buschelman Level: beginner 43320bad9183SKris Buschelman 43330cd7f59aSBarry Smith Notes: 43340cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 43350cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 43360cd7f59aSBarry Smith in the matrix 43370cd7f59aSBarry Smith 43380cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 43390cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 43400cd7f59aSBarry Smith 43410cd7f59aSBarry Smith Developer Notes: 43420cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 43430cd7f59aSBarry Smith 4344ed73aabaSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType, MATSELL, MATSEQSELL, MATMPISELL 43450bad9183SKris Buschelman M*/ 43460bad9183SKris Buschelman 4347ccd284c7SBarry Smith /*MC 4348ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4349ccd284c7SBarry Smith 4350ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4351ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 4352ed73aabaSBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4353ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4354ccd284c7SBarry Smith the above preallocation routines for simplicity. 4355ccd284c7SBarry Smith 4356ccd284c7SBarry Smith Options Database Keys: 4357ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4358ccd284c7SBarry Smith 435995452b02SPatrick Sanan Developer Notes: 4360ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4361ccd284c7SBarry Smith enough exist. 4362ccd284c7SBarry Smith 4363ccd284c7SBarry Smith Level: beginner 4364ccd284c7SBarry Smith 4365ed73aabaSBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ, MATMPIAIJ, MATSELL, MATSEQSELL, MATMPISELL 4366ccd284c7SBarry Smith M*/ 4367ccd284c7SBarry Smith 4368ccd284c7SBarry Smith /*MC 4369ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4370ccd284c7SBarry Smith 4371ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4372ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4373ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4374ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4375ccd284c7SBarry Smith the above preallocation routines for simplicity. 4376ccd284c7SBarry Smith 4377ccd284c7SBarry Smith Options Database Keys: 4378ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4379ccd284c7SBarry Smith 4380ccd284c7SBarry Smith Level: beginner 4381ccd284c7SBarry Smith 4382ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4383ccd284c7SBarry Smith M*/ 4384ccd284c7SBarry Smith 43857906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 43867906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 43877906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 43887906f579SHong Zhang #endif 4389d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4390d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4391d24d4204SJose E. Roman #endif 43927906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 43937906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 43947906f579SHong Zhang #endif 43957906f579SHong Zhang 4396d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4397c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 43984222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 43997906f579SHong Zhang 44008c778c55SBarry Smith /*@C 44018f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 44028c778c55SBarry Smith 44038c778c55SBarry Smith Not Collective 44048c778c55SBarry Smith 44058c778c55SBarry Smith Input Parameter: 4406579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 44078c778c55SBarry Smith 44088c778c55SBarry Smith Output Parameter: 44098c778c55SBarry Smith . array - pointer to the data 44108c778c55SBarry Smith 44118c778c55SBarry Smith Level: intermediate 44128c778c55SBarry Smith 4413774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 44148c778c55SBarry Smith @*/ 44158c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 44168c778c55SBarry Smith { 4417d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 44188c778c55SBarry Smith 44198c778c55SBarry Smith PetscFunctionBegin; 4420d67d9f35SJunchao Zhang if (aij->ops->getarray) { 44215f80ce2aSJacob Faibussowitsch CHKERRQ((*aij->ops->getarray)(A,array)); 4422d67d9f35SJunchao Zhang } else { 4423d67d9f35SJunchao Zhang *array = aij->a; 4424d67d9f35SJunchao Zhang } 4425d67d9f35SJunchao Zhang PetscFunctionReturn(0); 4426d67d9f35SJunchao Zhang } 4427d67d9f35SJunchao Zhang 4428d67d9f35SJunchao Zhang /*@C 4429d67d9f35SJunchao Zhang MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 4430d67d9f35SJunchao Zhang 4431d67d9f35SJunchao Zhang Not Collective 4432d67d9f35SJunchao Zhang 4433d67d9f35SJunchao Zhang Input Parameters: 4434d67d9f35SJunchao Zhang + mat - a MATSEQAIJ matrix 4435d67d9f35SJunchao Zhang - array - pointer to the data 4436d67d9f35SJunchao Zhang 4437d67d9f35SJunchao Zhang Level: intermediate 4438d67d9f35SJunchao Zhang 4439d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 4440d67d9f35SJunchao Zhang @*/ 4441d67d9f35SJunchao Zhang PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 4442d67d9f35SJunchao Zhang { 4443d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 4444d67d9f35SJunchao Zhang 4445d67d9f35SJunchao Zhang PetscFunctionBegin; 4446d67d9f35SJunchao Zhang if (aij->ops->restorearray) { 44475f80ce2aSJacob Faibussowitsch CHKERRQ((*aij->ops->restorearray)(A,array)); 4448d67d9f35SJunchao Zhang } else { 4449d67d9f35SJunchao Zhang *array = NULL; 4450d67d9f35SJunchao Zhang } 44515f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 44525f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectStateIncrease((PetscObject)A)); 44538c778c55SBarry Smith PetscFunctionReturn(0); 44548c778c55SBarry Smith } 44558c778c55SBarry Smith 445621e72a00SBarry Smith /*@C 44578f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 44588f1ea47aSStefano Zampini 44598f1ea47aSStefano Zampini Not Collective 44608f1ea47aSStefano Zampini 44618f1ea47aSStefano Zampini Input Parameter: 44628f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44638f1ea47aSStefano Zampini 44648f1ea47aSStefano Zampini Output Parameter: 44658f1ea47aSStefano Zampini . array - pointer to the data 44668f1ea47aSStefano Zampini 44678f1ea47aSStefano Zampini Level: intermediate 44688f1ea47aSStefano Zampini 44698f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 44708f1ea47aSStefano Zampini @*/ 44718f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 44728f1ea47aSStefano Zampini { 4473d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 44748f1ea47aSStefano Zampini 44758f1ea47aSStefano Zampini PetscFunctionBegin; 4476d67d9f35SJunchao Zhang if (aij->ops->getarrayread) { 44775f80ce2aSJacob Faibussowitsch CHKERRQ((*aij->ops->getarrayread)(A,array)); 4478d67d9f35SJunchao Zhang } else { 4479d67d9f35SJunchao Zhang *array = aij->a; 4480d67d9f35SJunchao Zhang } 44818f1ea47aSStefano Zampini PetscFunctionReturn(0); 44828f1ea47aSStefano Zampini } 44838f1ea47aSStefano Zampini 44848f1ea47aSStefano Zampini /*@C 44858f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 44868f1ea47aSStefano Zampini 44878f1ea47aSStefano Zampini Not Collective 44888f1ea47aSStefano Zampini 44898f1ea47aSStefano Zampini Input Parameter: 44908f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44918f1ea47aSStefano Zampini 44928f1ea47aSStefano Zampini Output Parameter: 44938f1ea47aSStefano Zampini . array - pointer to the data 44948f1ea47aSStefano Zampini 44958f1ea47aSStefano Zampini Level: intermediate 44968f1ea47aSStefano Zampini 44978f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 44988f1ea47aSStefano Zampini @*/ 44998f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 45008f1ea47aSStefano Zampini { 4501d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 45028f1ea47aSStefano Zampini 45038f1ea47aSStefano Zampini PetscFunctionBegin; 4504d67d9f35SJunchao Zhang if (aij->ops->restorearrayread) { 45055f80ce2aSJacob Faibussowitsch CHKERRQ((*aij->ops->restorearrayread)(A,array)); 4506d67d9f35SJunchao Zhang } else { 4507d67d9f35SJunchao Zhang *array = NULL; 4508d67d9f35SJunchao Zhang } 4509d67d9f35SJunchao Zhang PetscFunctionReturn(0); 4510d67d9f35SJunchao Zhang } 4511d67d9f35SJunchao Zhang 4512d67d9f35SJunchao Zhang /*@C 4513d67d9f35SJunchao Zhang MatSeqAIJGetArrayWrite - gives write-only access to the array where the data for a MATSEQAIJ matrix is stored 4514d67d9f35SJunchao Zhang 4515d67d9f35SJunchao Zhang Not Collective 4516d67d9f35SJunchao Zhang 4517d67d9f35SJunchao Zhang Input Parameter: 4518d67d9f35SJunchao Zhang . mat - a MATSEQAIJ matrix 4519d67d9f35SJunchao Zhang 4520d67d9f35SJunchao Zhang Output Parameter: 4521d67d9f35SJunchao Zhang . array - pointer to the data 4522d67d9f35SJunchao Zhang 4523d67d9f35SJunchao Zhang Level: intermediate 4524d67d9f35SJunchao Zhang 4525d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 4526d67d9f35SJunchao Zhang @*/ 4527d67d9f35SJunchao Zhang PetscErrorCode MatSeqAIJGetArrayWrite(Mat A,PetscScalar **array) 4528d67d9f35SJunchao Zhang { 4529d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 4530d67d9f35SJunchao Zhang 4531d67d9f35SJunchao Zhang PetscFunctionBegin; 4532d67d9f35SJunchao Zhang if (aij->ops->getarraywrite) { 45335f80ce2aSJacob Faibussowitsch CHKERRQ((*aij->ops->getarraywrite)(A,array)); 4534d67d9f35SJunchao Zhang } else { 4535d67d9f35SJunchao Zhang *array = aij->a; 4536d67d9f35SJunchao Zhang } 45375f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal(A)); 45385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectStateIncrease((PetscObject)A)); 4539d67d9f35SJunchao Zhang PetscFunctionReturn(0); 4540d67d9f35SJunchao Zhang } 4541d67d9f35SJunchao Zhang 4542d67d9f35SJunchao Zhang /*@C 4543d67d9f35SJunchao Zhang MatSeqAIJRestoreArrayWrite - restore the read-only access array obtained from MatSeqAIJGetArrayRead 4544d67d9f35SJunchao Zhang 4545d67d9f35SJunchao Zhang Not Collective 4546d67d9f35SJunchao Zhang 4547d67d9f35SJunchao Zhang Input Parameter: 4548d67d9f35SJunchao Zhang . mat - a MATSEQAIJ matrix 4549d67d9f35SJunchao Zhang 4550d67d9f35SJunchao Zhang Output Parameter: 4551d67d9f35SJunchao Zhang . array - pointer to the data 4552d67d9f35SJunchao Zhang 4553d67d9f35SJunchao Zhang Level: intermediate 4554d67d9f35SJunchao Zhang 4555d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 4556d67d9f35SJunchao Zhang @*/ 4557d67d9f35SJunchao Zhang PetscErrorCode MatSeqAIJRestoreArrayWrite(Mat A,PetscScalar **array) 4558d67d9f35SJunchao Zhang { 4559d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 4560d67d9f35SJunchao Zhang 4561d67d9f35SJunchao Zhang PetscFunctionBegin; 4562d67d9f35SJunchao Zhang if (aij->ops->restorearraywrite) { 45635f80ce2aSJacob Faibussowitsch CHKERRQ((*aij->ops->restorearraywrite)(A,array)); 4564d67d9f35SJunchao Zhang } else { 4565d67d9f35SJunchao Zhang *array = NULL; 4566d67d9f35SJunchao Zhang } 45678f1ea47aSStefano Zampini PetscFunctionReturn(0); 45688f1ea47aSStefano Zampini } 45698f1ea47aSStefano Zampini 45708f1ea47aSStefano Zampini /*@C 457121e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 457221e72a00SBarry Smith 457321e72a00SBarry Smith Not Collective 457421e72a00SBarry Smith 457521e72a00SBarry Smith Input Parameter: 4576579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 457721e72a00SBarry Smith 457821e72a00SBarry Smith Output Parameter: 457921e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 458021e72a00SBarry Smith 458121e72a00SBarry Smith Level: intermediate 458221e72a00SBarry Smith 458321e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 458421e72a00SBarry Smith @*/ 458521e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 458621e72a00SBarry Smith { 458721e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 458821e72a00SBarry Smith 458921e72a00SBarry Smith PetscFunctionBegin; 459021e72a00SBarry Smith *nz = aij->rmax; 459121e72a00SBarry Smith PetscFunctionReturn(0); 459221e72a00SBarry Smith } 459321e72a00SBarry Smith 4594394ed5ebSJunchao Zhang PetscErrorCode MatSetPreallocationCOO_SeqAIJ(Mat mat, PetscCount coo_n, const PetscInt coo_i[], const PetscInt coo_j[]) 4595394ed5ebSJunchao Zhang { 4596394ed5ebSJunchao Zhang MPI_Comm comm; 4597394ed5ebSJunchao Zhang PetscInt *i,*j; 4598394ed5ebSJunchao Zhang PetscInt M,N,row; 4599394ed5ebSJunchao Zhang PetscCount k,p,q,nneg,nnz,start,end; /* Index the coo array, so use PetscCount as their type */ 4600394ed5ebSJunchao Zhang PetscInt *Ai; /* Change to PetscCount once we use it for row pointers */ 4601394ed5ebSJunchao Zhang PetscInt *Aj; 4602394ed5ebSJunchao Zhang PetscScalar *Aa; 4603cbc6b225SStefano Zampini Mat_SeqAIJ *seqaij = (Mat_SeqAIJ*)(mat->data); 4604cbc6b225SStefano Zampini MatType rtype; 4605394ed5ebSJunchao Zhang PetscCount *perm,*jmap; 4606394ed5ebSJunchao Zhang 4607394ed5ebSJunchao Zhang PetscFunctionBegin; 46085f80ce2aSJacob Faibussowitsch CHKERRQ(MatResetPreallocationCOO_SeqAIJ(mat)); 46095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectGetComm((PetscObject)mat,&comm)); 46105f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(mat,&M,&N)); 46115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(coo_n,&i,coo_n,&j)); 46125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(i,coo_i,coo_n)); /* Make a copy since we'll modify it */ 46135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(j,coo_j,coo_n)); 46145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(coo_n,&perm)); 4615394ed5ebSJunchao Zhang for (k=0; k<coo_n; k++) { /* Ignore entries with negative row or col indices */ 4616394ed5ebSJunchao Zhang if (j[k] < 0) i[k] = -1; 4617394ed5ebSJunchao Zhang perm[k] = k; 4618394ed5ebSJunchao Zhang } 4619394ed5ebSJunchao Zhang 4620394ed5ebSJunchao Zhang /* Sort by row */ 46215f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSortIntWithIntCountArrayPair(coo_n,i,j,perm)); 4622394ed5ebSJunchao Zhang for (k=0; k<coo_n; k++) {if (i[k] >= 0) break;} /* Advance k to the first row with a non-negative index */ 4623394ed5ebSJunchao Zhang nneg = k; 46245f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(coo_n-nneg+1,&jmap)); /* +1 to make a CSR-like data structure. jmap[i] originally is the number of repeats for i-th nonzero */ 4625394ed5ebSJunchao Zhang nnz = 0; /* Total number of unique nonzeros to be counted */ 4626394ed5ebSJunchao Zhang jmap++; /* Inc jmap by 1 for convinience */ 4627394ed5ebSJunchao Zhang 46285f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(M+1,&Ai)); /* CSR of A */ 46295f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(coo_n-nneg,&Aj)); /* We have at most coo_n-nneg unique nonzeros */ 4630394ed5ebSJunchao Zhang 4631394ed5ebSJunchao Zhang /* In each row, sort by column, then unique column indices to get row length */ 4632394ed5ebSJunchao Zhang Ai++; /* Inc by 1 for convinience */ 4633394ed5ebSJunchao Zhang q = 0; /* q-th unique nonzero, with q starting from 0 */ 4634394ed5ebSJunchao Zhang while (k<coo_n) { 4635394ed5ebSJunchao Zhang row = i[k]; 4636394ed5ebSJunchao Zhang start = k; /* [start,end) indices for this row */ 4637394ed5ebSJunchao Zhang while (k<coo_n && i[k] == row) k++; 4638394ed5ebSJunchao Zhang end = k; 46395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscSortIntWithCountArray(end-start,j+start,perm+start)); 4640394ed5ebSJunchao Zhang /* Find number of unique col entries in this row */ 4641394ed5ebSJunchao Zhang Aj[q] = j[start]; /* Log the first nonzero in this row */ 4642394ed5ebSJunchao Zhang jmap[q] = 1; /* Number of repeats of this nozero entry */ 4643394ed5ebSJunchao Zhang Ai[row] = 1; 4644394ed5ebSJunchao Zhang nnz++; 4645394ed5ebSJunchao Zhang 4646394ed5ebSJunchao Zhang for (p=start+1; p<end; p++) { /* Scan remaining nonzero in this row */ 4647394ed5ebSJunchao Zhang if (j[p] != j[p-1]) { /* Meet a new nonzero */ 4648394ed5ebSJunchao Zhang q++; 4649394ed5ebSJunchao Zhang jmap[q] = 1; 4650394ed5ebSJunchao Zhang Aj[q] = j[p]; 4651394ed5ebSJunchao Zhang Ai[row]++; 4652394ed5ebSJunchao Zhang nnz++; 4653394ed5ebSJunchao Zhang } else { 4654394ed5ebSJunchao Zhang jmap[q]++; 4655394ed5ebSJunchao Zhang } 4656394ed5ebSJunchao Zhang } 4657394ed5ebSJunchao Zhang q++; /* Move to next row and thus next unique nonzero */ 4658394ed5ebSJunchao Zhang } 46595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree2(i,j)); 4660394ed5ebSJunchao Zhang 4661394ed5ebSJunchao Zhang Ai--; /* Back to the beginning of Ai[] */ 4662394ed5ebSJunchao Zhang for (k=0; k<M; k++) Ai[k+1] += Ai[k]; 4663394ed5ebSJunchao Zhang jmap--; /* Back to the beginning of jmap[] */ 4664394ed5ebSJunchao Zhang jmap[0] = 0; 4665394ed5ebSJunchao Zhang for (k=0; k<nnz; k++) jmap[k+1] += jmap[k]; 4666394ed5ebSJunchao Zhang if (nnz < coo_n-nneg) { /* Realloc with actual number of unique nonzeros */ 4667394ed5ebSJunchao Zhang PetscCount *jmap_new; 4668394ed5ebSJunchao Zhang PetscInt *Aj_new; 4669394ed5ebSJunchao Zhang 46705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nnz+1,&jmap_new)); 46715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(jmap_new,jmap,nnz+1)); 46725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(jmap)); 4673394ed5ebSJunchao Zhang jmap = jmap_new; 4674394ed5ebSJunchao Zhang 46755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(nnz,&Aj_new)); 46765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(Aj_new,Aj,nnz)); 46775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(Aj)); 4678394ed5ebSJunchao Zhang Aj = Aj_new; 4679394ed5ebSJunchao Zhang } 4680394ed5ebSJunchao Zhang 4681394ed5ebSJunchao Zhang if (nneg) { /* Discard heading entries with negative indices in perm[], as we'll access it from index 0 in MatSetValuesCOO */ 4682394ed5ebSJunchao Zhang PetscCount *perm_new; 4683cbc6b225SStefano Zampini 46845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(coo_n-nneg,&perm_new)); 46855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(perm_new,perm+nneg,coo_n-nneg)); 46865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(perm)); 4687394ed5ebSJunchao Zhang perm = perm_new; 4688394ed5ebSJunchao Zhang } 4689394ed5ebSJunchao Zhang 46905f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetRootType_Private(mat,&rtype)); 46915f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(nnz,&Aa)); /* Zero the matrix */ 46925f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSeqAIJWithArrays_private(PETSC_COMM_SELF,M,N,Ai,Aj,Aa,rtype,mat)); 4693394ed5ebSJunchao Zhang 4694394ed5ebSJunchao Zhang seqaij->singlemalloc = PETSC_FALSE; /* Ai, Aj and Aa are not allocated in one big malloc */ 4695394ed5ebSJunchao Zhang seqaij->free_a = seqaij->free_ij = PETSC_TRUE; /* Let newmat own Ai, Aj and Aa */ 4696394ed5ebSJunchao Zhang /* Record COO fields */ 4697394ed5ebSJunchao Zhang seqaij->coo_n = coo_n; 4698394ed5ebSJunchao Zhang seqaij->Atot = coo_n-nneg; /* Annz is seqaij->nz, so no need to record that again */ 4699394ed5ebSJunchao Zhang seqaij->jmap = jmap; /* of length nnz+1 */ 4700394ed5ebSJunchao Zhang seqaij->perm = perm; 4701394ed5ebSJunchao Zhang PetscFunctionReturn(0); 4702394ed5ebSJunchao Zhang } 4703394ed5ebSJunchao Zhang 4704394ed5ebSJunchao Zhang static PetscErrorCode MatSetValuesCOO_SeqAIJ(Mat A,const PetscScalar v[],InsertMode imode) 4705394ed5ebSJunchao Zhang { 4706394ed5ebSJunchao Zhang Mat_SeqAIJ *aseq = (Mat_SeqAIJ*)A->data; 4707394ed5ebSJunchao Zhang PetscCount i,j,Annz = aseq->nz; 4708394ed5ebSJunchao Zhang PetscCount *perm = aseq->perm,*jmap = aseq->jmap; 4709394ed5ebSJunchao Zhang PetscScalar *Aa; 4710394ed5ebSJunchao Zhang 4711394ed5ebSJunchao Zhang PetscFunctionBegin; 47125f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArray(A,&Aa)); 4713394ed5ebSJunchao Zhang for (i=0; i<Annz; i++) { 4714b6c38306SJunchao Zhang PetscScalar sum = 0.0; 4715b6c38306SJunchao Zhang for (j=jmap[i]; j<jmap[i+1]; j++) sum += v[perm[j]]; 4716b6c38306SJunchao Zhang Aa[i] = (imode == INSERT_VALUES? 0.0 : Aa[i]) + sum; 4717394ed5ebSJunchao Zhang } 47185f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArray(A,&Aa)); 4719394ed5ebSJunchao Zhang PetscFunctionReturn(0); 4720394ed5ebSJunchao Zhang } 4721394ed5ebSJunchao Zhang 472234b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 47235063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat,MatType,MatReuse,Mat*); 472402fe1965SBarry Smith #endif 47253d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 47265063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat,MatType,MatReuse,Mat*); 47273d0639e7SStefano Zampini #endif 472802fe1965SBarry Smith 47298cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4730273d9f13SBarry Smith { 4731273d9f13SBarry Smith Mat_SeqAIJ *b; 473238baddfdSBarry Smith PetscMPIInt size; 4733273d9f13SBarry Smith 4734273d9f13SBarry Smith PetscFunctionBegin; 47355f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size)); 47362c71b3e2SJacob Faibussowitsch PetscCheckFalse(size > 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4737273d9f13SBarry Smith 47385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(B,&b)); 47392205254eSKarl Rupp 4740b0a32e0cSBarry Smith B->data = (void*)b; 47412205254eSKarl Rupp 47425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps))); 4743071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 47442205254eSKarl Rupp 4745f4259b30SLisandro Dalcin b->row = NULL; 4746f4259b30SLisandro Dalcin b->col = NULL; 4747f4259b30SLisandro Dalcin b->icol = NULL; 4748b810aeb4SBarry Smith b->reallocs = 0; 474936db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4750f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4751416022c9SBarry Smith b->nonew = 0; 4752f4259b30SLisandro Dalcin b->diag = NULL; 4753f4259b30SLisandro Dalcin b->solve_work = NULL; 4754f4259b30SLisandro Dalcin B->spptr = NULL; 4755f4259b30SLisandro Dalcin b->saved_values = NULL; 4756f4259b30SLisandro Dalcin b->idiag = NULL; 4757f4259b30SLisandro Dalcin b->mdiag = NULL; 4758f4259b30SLisandro Dalcin b->ssor_work = NULL; 475971f1c65dSBarry Smith b->omega = 1.0; 476071f1c65dSBarry Smith b->fshift = 0.0; 476171f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4762bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4763a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 476417ab2063SBarry Smith 47655f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ)); 47668c778c55SBarry Smith 4767b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 47685f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ)); 47695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ)); 4770b3866ffcSBarry Smith #endif 477117f1a0eaSHong Zhang 47725f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ)); 47735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ)); 47745f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ)); 47755f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ)); 47765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ)); 47775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM)); 47785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL)); 47799779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 47805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL)); 4781191b95cbSRichard Tran Mills #endif 478234b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 47835f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE)); 47845f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ)); 47855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ)); 478602fe1965SBarry Smith #endif 47873d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 47885f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos)); 47893d0639e7SStefano Zampini #endif 47905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL)); 4791af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 47925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental)); 4793af8000cdSHong Zhang #endif 4794d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 47955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK)); 4796d24d4204SJose E. Roman #endif 479763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 47985f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE)); 47995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ)); 480063c07aadSStefano Zampini #endif 48015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense)); 48025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL)); 48035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS)); 48045f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ)); 48055f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ)); 48065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ)); 48075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ)); 48085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ)); 48095f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ)); 48105f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ)); 48115f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ)); 48125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ)); 48135f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJKron_C",MatSeqAIJKron_SeqAIJ)); 48145f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatSetPreallocationCOO_C",MatSetPreallocationCOO_SeqAIJ)); 48155f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)B,"MatSetValuesCOO_C",MatSetValuesCOO_SeqAIJ)); 48165f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate_SeqAIJ_Inode(B)); 48175f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ)); 48185f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetTypeFromOptions(B)); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 48193a40ed3dSBarry Smith PetscFunctionReturn(0); 482017ab2063SBarry Smith } 482117ab2063SBarry Smith 4822b24902e0SBarry Smith /* 4823b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4824b24902e0SBarry Smith */ 4825ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 482617ab2063SBarry Smith { 48272a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 4828071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 482917ab2063SBarry Smith 48303a40ed3dSBarry Smith PetscFunctionBegin; 48312c71b3e2SJacob Faibussowitsch PetscCheckFalse(!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4832273d9f13SBarry Smith 4833d5f3da31SBarry Smith C->factortype = A->factortype; 4834f4259b30SLisandro Dalcin c->row = NULL; 4835f4259b30SLisandro Dalcin c->col = NULL; 4836f4259b30SLisandro Dalcin c->icol = NULL; 48376ad4291fSHong Zhang c->reallocs = 0; 483817ab2063SBarry Smith 483969272f91SPierre Jolivet C->assembled = A->assembled; 484069272f91SPierre Jolivet C->preallocated = A->preallocated; 484117ab2063SBarry Smith 484269272f91SPierre Jolivet if (A->preallocated) { 48435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutReference(A->rmap,&C->rmap)); 48445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutReference(A->cmap,&C->cmap)); 4845eec197d1SBarry Smith 48465f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m,&c->imax)); 48475f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt))); 48485f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m,&c->ilen)); 48495f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt))); 48505f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt))); 485117ab2063SBarry Smith 485217ab2063SBarry Smith /* allocate the matrix space */ 4853f77e22a1SHong Zhang if (mallocmatspace) { 48545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i)); 48555f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt))); 48562205254eSKarl Rupp 4857f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 48582205254eSKarl Rupp 48595f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(c->i,a->i,m+1)); 486017ab2063SBarry Smith if (m > 0) { 48615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(c->j,a->j,a->i[m])); 4862be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 48632e5835c6SStefano Zampini const PetscScalar *aa; 48642e5835c6SStefano Zampini 48655f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 48665f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(c->a,aa,a->i[m])); 48675f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 4868be6bf707SBarry Smith } else { 48695f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArrayzero(c->a,a->i[m])); 487017ab2063SBarry Smith } 487108480c60SBarry Smith } 4872f77e22a1SHong Zhang } 487317ab2063SBarry Smith 48746ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4875416022c9SBarry Smith c->roworiented = a->roworiented; 4876416022c9SBarry Smith c->nonew = a->nonew; 4877416022c9SBarry Smith if (a->diag) { 48785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m+1,&c->diag)); 48795f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt))); 48805f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt))); 4881071fcb05SBarry Smith } else c->diag = NULL; 48822205254eSKarl Rupp 4883f4259b30SLisandro Dalcin c->solve_work = NULL; 4884f4259b30SLisandro Dalcin c->saved_values = NULL; 4885f4259b30SLisandro Dalcin c->idiag = NULL; 4886f4259b30SLisandro Dalcin c->ssor_work = NULL; 4887a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4888e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4889e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 48906ad4291fSHong Zhang 4891893ad86cSHong Zhang c->rmax = a->rmax; 4892416022c9SBarry Smith c->nz = a->nz; 48938ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4894754ec7b1SSatish Balay 48956ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 48966ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4897cd6b891eSBarry Smith if (a->compressedrow.use) { 48986ad4291fSHong Zhang i = a->compressedrow.nrows; 48995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex)); 49005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1)); 49015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i)); 490227ea64f8SHong Zhang } else { 490327ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 49040298fd71SBarry Smith c->compressedrow.i = NULL; 49050298fd71SBarry Smith c->compressedrow.rindex = NULL; 49066ad4291fSHong Zhang } 4907ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4908e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 49094846f1f5SKris Buschelman 49105f80ce2aSJacob Faibussowitsch CHKERRQ(MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C)); 491169272f91SPierre Jolivet } 49125f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist)); 49133a40ed3dSBarry Smith PetscFunctionReturn(0); 491417ab2063SBarry Smith } 491517ab2063SBarry Smith 4916b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4917b24902e0SBarry Smith { 4918b24902e0SBarry Smith PetscFunctionBegin; 49195f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PetscObjectComm((PetscObject)A),B)); 49205f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n)); 4921cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 49225f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetBlockSizesFromMats(*B,A,A)); 4923cfd3f464SBarry Smith } 49245f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(*B,((PetscObject)A)->type_name)); 49255f80ce2aSJacob Faibussowitsch CHKERRQ(MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE)); 4926b24902e0SBarry Smith PetscFunctionReturn(0); 4927b24902e0SBarry Smith } 4928b24902e0SBarry Smith 4929112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4930fbdbba38SShri Abhyankar { 493152f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 493252f91c60SVaclav Hapla 493352f91c60SVaclav Hapla PetscFunctionBegin; 493452f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 493552f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4936c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 49375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerSetUp(viewer)); 49385f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 49395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5)); 494052f91c60SVaclav Hapla if (isbinary) { 49415f80ce2aSJacob Faibussowitsch CHKERRQ(MatLoad_SeqAIJ_Binary(newMat,viewer)); 494252f91c60SVaclav Hapla } else if (ishdf5) { 494352f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 49445f80ce2aSJacob Faibussowitsch CHKERRQ(MatLoad_AIJ_HDF5(newMat,viewer)); 494552f91c60SVaclav Hapla #else 494652f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 494752f91c60SVaclav Hapla #endif 494852f91c60SVaclav Hapla } else { 494998921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name); 495052f91c60SVaclav Hapla } 495152f91c60SVaclav Hapla PetscFunctionReturn(0); 495252f91c60SVaclav Hapla } 495352f91c60SVaclav Hapla 49543ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 495552f91c60SVaclav Hapla { 49563ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 49573ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4958fbdbba38SShri Abhyankar 4959fbdbba38SShri Abhyankar PetscFunctionBegin; 49605f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerSetUp(viewer)); 4961bbead8a2SBarry Smith 49623ea6fe3dSLisandro Dalcin /* read in matrix header */ 49635f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT)); 49642c71b3e2SJacob Faibussowitsch PetscCheckFalse(header[0] != MAT_FILE_CLASSID,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4965fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 49662c71b3e2SJacob Faibussowitsch PetscCheckFalse(M < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M); 49672c71b3e2SJacob Faibussowitsch PetscCheckFalse(N < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N); 49682c71b3e2SJacob Faibussowitsch PetscCheckFalse(nz < 0,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4969fbdbba38SShri Abhyankar 49703ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 49715f80ce2aSJacob Faibussowitsch CHKERRQ(MatLoad_Binary_BlockSizes(mat,viewer)); 49723ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 49733ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 49743ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 49753ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 49763ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 49775f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(mat->rmap)); 49785f80ce2aSJacob Faibussowitsch CHKERRQ(PetscLayoutSetUp(mat->cmap)); 49793ea6fe3dSLisandro Dalcin 49803ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 49815f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(mat,&rows,&cols)); 49822c71b3e2SJacob Faibussowitsch PetscCheckFalse(M != rows || N != cols,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols); 49833ea6fe3dSLisandro Dalcin 4984fbdbba38SShri Abhyankar /* read in row lengths */ 49855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(M,&rowlens)); 49865f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT)); 49873ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 49883ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 49892c71b3e2SJacob Faibussowitsch PetscCheckFalse(sum != nz,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Inconsistent matrix data in file: nonzeros = %" PetscInt_FMT ", sum-row-lengths = %" PetscInt_FMT,nz,sum); 49903ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 49915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens)); 49925f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetSize(mat,&rows,&cols)); 49932c71b3e2SJacob Faibussowitsch PetscCheckFalse(M != rows || N != cols,PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols); 49943ea6fe3dSLisandro Dalcin /* store row lengths */ 49955f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycpy(a->ilen,rowlens,M)); 49965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(rowlens)); 4997fbdbba38SShri Abhyankar 49983ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 49993ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 50003ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 50015f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT)); 50023ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 50035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR)); 5004fbdbba38SShri Abhyankar 50055f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY)); 50065f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY)); 5007fbdbba38SShri Abhyankar PetscFunctionReturn(0); 5008fbdbba38SShri Abhyankar } 5009fbdbba38SShri Abhyankar 5010ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 50117264ac53SSatish Balay { 50127264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 5013fff043a9SJunchao Zhang const PetscScalar *aa,*ba; 5014eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 5015eeffb40dSHong Zhang PetscInt k; 5016eeffb40dSHong Zhang #endif 50177264ac53SSatish Balay 50183a40ed3dSBarry Smith PetscFunctionBegin; 5019bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 5020d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 5021ca44d042SBarry Smith *flg = PETSC_FALSE; 5022ca44d042SBarry Smith PetscFunctionReturn(0); 5023bcd2baecSBarry Smith } 50247264ac53SSatish Balay 50257264ac53SSatish Balay /* if the a->i are the same */ 50265f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycmp(a->i,b->i,A->rmap->n+1,flg)); 5027abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 50287264ac53SSatish Balay 50297264ac53SSatish Balay /* if a->j are the same */ 50305f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycmp(a->j,b->j,a->nz,flg)); 5031abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 5032bcd2baecSBarry Smith 50335f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(A,&aa)); 50345f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJGetArrayRead(B,&ba)); 5035bcd2baecSBarry Smith /* if a->a are the same */ 5036eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 5037eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 5038fff043a9SJunchao Zhang if (PetscRealPart(aa[k]) != PetscRealPart(ba[k]) || PetscImaginaryPart(aa[k]) != PetscImaginaryPart(ba[k])) { 5039eeffb40dSHong Zhang *flg = PETSC_FALSE; 50403a40ed3dSBarry Smith PetscFunctionReturn(0); 5041eeffb40dSHong Zhang } 5042eeffb40dSHong Zhang } 5043eeffb40dSHong Zhang #else 50445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscArraycmp(aa,ba,a->nz,flg)); 5045eeffb40dSHong Zhang #endif 50465f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(A,&aa)); 50475f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRestoreArrayRead(B,&ba)); 5048eeffb40dSHong Zhang PetscFunctionReturn(0); 50497264ac53SSatish Balay } 505036db0b34SBarry Smith 505105869f15SSatish Balay /*@ 505236db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 505336db0b34SBarry Smith provided by the user. 505436db0b34SBarry Smith 5055d083f849SBarry Smith Collective 505636db0b34SBarry Smith 505736db0b34SBarry Smith Input Parameters: 505836db0b34SBarry Smith + comm - must be an MPI communicator of size 1 505936db0b34SBarry Smith . m - number of rows 506036db0b34SBarry Smith . n - number of columns 5061483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 506236db0b34SBarry Smith . j - column indices 506336db0b34SBarry Smith - a - matrix values 506436db0b34SBarry Smith 506536db0b34SBarry Smith Output Parameter: 506636db0b34SBarry Smith . mat - the matrix 506736db0b34SBarry Smith 506836db0b34SBarry Smith Level: intermediate 506936db0b34SBarry Smith 507036db0b34SBarry Smith Notes: 50710551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 5072292fb18eSBarry Smith once the matrix is destroyed and not before 507336db0b34SBarry Smith 507436db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 507536db0b34SBarry Smith 5076bfeeae90SHong Zhang The i and j indices are 0 based 507736db0b34SBarry Smith 5078a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 5079a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 50808eef79e4SBarry Smith as shown 5081a4552177SSatish Balay 50828eef79e4SBarry Smith $ 1 0 0 50838eef79e4SBarry Smith $ 2 0 3 50848eef79e4SBarry Smith $ 4 5 6 50858eef79e4SBarry Smith $ 50868eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 50878eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 50888eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 5089a4552177SSatish Balay 509069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 509136db0b34SBarry Smith 509236db0b34SBarry Smith @*/ 5093c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 509436db0b34SBarry Smith { 5095cbcfb4deSHong Zhang PetscInt ii; 509636db0b34SBarry Smith Mat_SeqAIJ *aij; 5097cbcfb4deSHong Zhang PetscInt jj; 509836db0b34SBarry Smith 509936db0b34SBarry Smith PetscFunctionBegin; 51002c71b3e2SJacob Faibussowitsch PetscCheckFalse(m > 0 && i[0],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 51015f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(comm,mat)); 51025f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(*mat,m,n,m,n)); 51035f80ce2aSJacob Faibussowitsch /* CHKERRQ(MatSetBlockSizes(*mat,,)); */ 51045f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(*mat,MATSEQAIJ)); 51055f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL)); 5106ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 51075f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m,&aij->imax)); 51085f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(m,&aij->ilen)); 5109ab93d7beSBarry Smith 511036db0b34SBarry Smith aij->i = i; 511136db0b34SBarry Smith aij->j = j; 511236db0b34SBarry Smith aij->a = a; 511336db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 511436db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 5115e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 5116e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 511736db0b34SBarry Smith 5118cbc6b225SStefano Zampini for (ii=0,aij->nonzerorowcnt=0,aij->rmax=0; ii<m; ii++) { 511936db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 512076bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 51212c71b3e2SJacob Faibussowitsch PetscCheckFalse(i[ii+1] - i[ii] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %" PetscInt_FMT " length = %" PetscInt_FMT,ii,i[ii+1] - i[ii]); 51229985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 51232c71b3e2SJacob Faibussowitsch PetscCheckFalse(j[jj] < j[jj-1],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %" PetscInt_FMT " (actual column %" PetscInt_FMT ") in row %" PetscInt_FMT " is not sorted",jj-i[ii],j[jj],ii); 51242c71b3e2SJacob Faibussowitsch PetscCheckFalse(j[jj] == j[jj-1],PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %" PetscInt_FMT " (actual column %" PetscInt_FMT ") in row %" PetscInt_FMT " is identical to previous entry",jj-i[ii],j[jj],ii); 51259985e31cSBarry Smith } 512636db0b34SBarry Smith } 512776bd3646SJed Brown } 512876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 512936db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 51302c71b3e2SJacob Faibussowitsch PetscCheckFalse(j[ii] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %" PetscInt_FMT " index = %" PetscInt_FMT,ii,j[ii]); 51312c71b3e2SJacob Faibussowitsch PetscCheckFalse(j[ii] > n - 1,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %" PetscInt_FMT " index = %" PetscInt_FMT,ii,j[ii]); 513236db0b34SBarry Smith } 513376bd3646SJed Brown } 513436db0b34SBarry Smith 51355f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY)); 51365f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY)); 513736db0b34SBarry Smith PetscFunctionReturn(0); 513836db0b34SBarry Smith } 5139cbc6b225SStefano Zampini 514080ef6e79SMatthew G Knepley /*@C 5141d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 51428a0b0e6bSVictor Minden provided by the user. 51438a0b0e6bSVictor Minden 5144d083f849SBarry Smith Collective 51458a0b0e6bSVictor Minden 51468a0b0e6bSVictor Minden Input Parameters: 51478a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 51488a0b0e6bSVictor Minden . m - number of rows 51498a0b0e6bSVictor Minden . n - number of columns 51508a0b0e6bSVictor Minden . i - row indices 51518a0b0e6bSVictor Minden . j - column indices 51521230e6d1SVictor Minden . a - matrix values 51531230e6d1SVictor Minden . nz - number of nonzeros 51541230e6d1SVictor Minden - idx - 0 or 1 based 51558a0b0e6bSVictor Minden 51568a0b0e6bSVictor Minden Output Parameter: 51578a0b0e6bSVictor Minden . mat - the matrix 51588a0b0e6bSVictor Minden 51598a0b0e6bSVictor Minden Level: intermediate 51608a0b0e6bSVictor Minden 51618a0b0e6bSVictor Minden Notes: 51629e99939fSJunchao Zhang The i and j indices are 0 based. The format which is used for the sparse matrix input, is equivalent to a row-major ordering. i.e for the following matrix, 51639e99939fSJunchao Zhang the input data expected is as shown 51649e99939fSJunchao Zhang .vb 51658a0b0e6bSVictor Minden 1 0 0 51668a0b0e6bSVictor Minden 2 0 3 51678a0b0e6bSVictor Minden 4 5 6 51688a0b0e6bSVictor Minden 51698a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 51708a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 51718a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 51729e99939fSJunchao Zhang .ve 51738a0b0e6bSVictor Minden 517469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 51758a0b0e6bSVictor Minden 51768a0b0e6bSVictor Minden @*/ 5177c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 51788a0b0e6bSVictor Minden { 5179d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 51808a0b0e6bSVictor Minden 51818a0b0e6bSVictor Minden PetscFunctionBegin; 51825f80ce2aSJacob Faibussowitsch CHKERRQ(PetscCalloc1(m,&nnz)); 51831230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 5184c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 51851230e6d1SVictor Minden } 51865f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(comm,mat)); 51875f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(*mat,m,n,m,n)); 51885f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetType(*mat,MATSEQAIJ)); 51895f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz)); 51901230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 51911230e6d1SVictor Minden if (idx) { 51921230e6d1SVictor Minden row = i[ii] - 1; 51931230e6d1SVictor Minden col = j[ii] - 1; 51941230e6d1SVictor Minden } else { 51951230e6d1SVictor Minden row = i[ii]; 51961230e6d1SVictor Minden col = j[ii]; 51978a0b0e6bSVictor Minden } 51985f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES)); 51998a0b0e6bSVictor Minden } 52005f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY)); 52015f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY)); 52025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(nnz)); 52038a0b0e6bSVictor Minden PetscFunctionReturn(0); 52048a0b0e6bSVictor Minden } 520536db0b34SBarry Smith 5206acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 5207acf2f550SJed Brown { 5208acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5209acf2f550SJed Brown 5210acf2f550SJed Brown PetscFunctionBegin; 5211acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5212acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 52132205254eSKarl Rupp 52145f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJInvalidateDiagonal_Inode(A)); 5215acf2f550SJed Brown PetscFunctionReturn(0); 5216acf2f550SJed Brown } 5217acf2f550SJed Brown 52189c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 52199c8f2541SHong Zhang { 52208761c3d6SHong Zhang PetscMPIInt size; 52219c8f2541SHong Zhang 52229c8f2541SHong Zhang PetscFunctionBegin; 52235f80ce2aSJacob Faibussowitsch CHKERRMPI(MPI_Comm_size(comm,&size)); 52247bbdc51dSHong Zhang if (size == 1) { 52257bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 52265f80ce2aSJacob Faibussowitsch CHKERRQ(MatDuplicate(inmat,MAT_COPY_VALUES,outmat)); 52277bbdc51dSHong Zhang } else { 52285f80ce2aSJacob Faibussowitsch CHKERRQ(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN)); 52297bbdc51dSHong Zhang } 52308761c3d6SHong Zhang } else { 52315f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat)); 52328761c3d6SHong Zhang } 52339c8f2541SHong Zhang PetscFunctionReturn(0); 52349c8f2541SHong Zhang } 52359c8f2541SHong Zhang 523681824310SBarry Smith /* 523753dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 523853dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 523953dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 524053dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 524153dd7562SDmitry Karpeev */ 524253dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 524353dd7562SDmitry Karpeev { 524453dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 524553dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 524653dd7562SDmitry Karpeev PetscBool seqaij; 524753dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 524853dd7562SDmitry Karpeev PetscScalar v; 524953dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 525053dd7562SDmitry Karpeev 525153dd7562SDmitry Karpeev PetscFunctionBegin; 525253dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 525353dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 52545f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij)); 5255*28b400f6SJacob Faibussowitsch PetscCheck(seqaij,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 525653dd7562SDmitry Karpeev if (rowemb) { 52575f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(rowemb,&m)); 52582c71b3e2SJacob Faibussowitsch PetscCheckFalse(m != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Row IS of size %" PetscInt_FMT " is incompatible with matrix row size %" PetscInt_FMT,m,B->rmap->n); 525953dd7562SDmitry Karpeev } else { 52602c71b3e2SJacob Faibussowitsch PetscCheckFalse(C->rmap->n != B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 526153dd7562SDmitry Karpeev } 526253dd7562SDmitry Karpeev if (colemb) { 52635f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetLocalSize(colemb,&n)); 52642c71b3e2SJacob Faibussowitsch PetscCheckFalse(n != B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Diag col IS of size %" PetscInt_FMT " is incompatible with input matrix col size %" PetscInt_FMT,n,B->cmap->n); 526553dd7562SDmitry Karpeev } else { 52662c71b3e2SJacob Faibussowitsch PetscCheckFalse(C->cmap->n != B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 526753dd7562SDmitry Karpeev } 526853dd7562SDmitry Karpeev 526953dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 527053dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 52715f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(B->rmap->n,&nz)); 527253dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 527353dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 527453dd7562SDmitry Karpeev } 52755f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(C,0,nz)); 52765f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(nz)); 527753dd7562SDmitry Karpeev } 527853dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 52795f80ce2aSJacob Faibussowitsch CHKERRQ(MatZeroEntries(C)); 528053dd7562SDmitry Karpeev } 528153dd7562SDmitry Karpeev count = 0; 528253dd7562SDmitry Karpeev rowindices = NULL; 528353dd7562SDmitry Karpeev colindices = NULL; 528453dd7562SDmitry Karpeev if (rowemb) { 52855f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(rowemb,&rowindices)); 528653dd7562SDmitry Karpeev } 528753dd7562SDmitry Karpeev if (colemb) { 52885f80ce2aSJacob Faibussowitsch CHKERRQ(ISGetIndices(colemb,&colindices)); 528953dd7562SDmitry Karpeev } 529053dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 529153dd7562SDmitry Karpeev PetscInt row; 529253dd7562SDmitry Karpeev row = i; 529353dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 529453dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 529553dd7562SDmitry Karpeev PetscInt col; 529653dd7562SDmitry Karpeev col = Baij->j[count]; 529753dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 529853dd7562SDmitry Karpeev v = Baij->a[count]; 52995f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES)); 530053dd7562SDmitry Karpeev ++count; 530153dd7562SDmitry Karpeev } 530253dd7562SDmitry Karpeev } 530353dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 530453dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 530553dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 530653dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 530753dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 530853dd7562SDmitry Karpeev PetscFunctionReturn(0); 530953dd7562SDmitry Karpeev } 531053dd7562SDmitry Karpeev 53114099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 53124099cc6bSBarry Smith 53134099cc6bSBarry Smith /*@C 53144099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 53154099cc6bSBarry Smith 53164099cc6bSBarry Smith Collective on Mat 53174099cc6bSBarry Smith 53184099cc6bSBarry Smith Input Parameters: 53194099cc6bSBarry Smith + mat - the matrix object 53204099cc6bSBarry Smith - matype - matrix type 53214099cc6bSBarry Smith 53224099cc6bSBarry Smith Options Database Key: 53234099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 53244099cc6bSBarry Smith 53254099cc6bSBarry Smith Level: intermediate 53264099cc6bSBarry Smith 53274099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 53284099cc6bSBarry Smith @*/ 53294099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 53304099cc6bSBarry Smith { 53314099cc6bSBarry Smith PetscBool sametype; 53325f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(Mat,MatType,MatReuse,Mat*); 53334099cc6bSBarry Smith 53344099cc6bSBarry Smith PetscFunctionBegin; 53354099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 53365f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)mat,matype,&sametype)); 53374099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 53384099cc6bSBarry Smith 53395f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListFind(MatSeqAIJList,matype,&r)); 53405f80ce2aSJacob Faibussowitsch PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 53415f80ce2aSJacob Faibussowitsch CHKERRQ((*r)(mat,matype,MAT_INPLACE_MATRIX,&mat)); 53424099cc6bSBarry Smith PetscFunctionReturn(0); 53434099cc6bSBarry Smith } 53444099cc6bSBarry Smith 53454099cc6bSBarry Smith /*@C 53464099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 53474099cc6bSBarry Smith 53484099cc6bSBarry Smith Not Collective 53494099cc6bSBarry Smith 53504099cc6bSBarry Smith Input Parameters: 53514099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 53524099cc6bSBarry Smith - function - routine to convert to subtype 53534099cc6bSBarry Smith 53544099cc6bSBarry Smith Notes: 53554099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 53564099cc6bSBarry Smith 53574099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 53584099cc6bSBarry Smith $ -mat_seqaij_type my_mat 53594099cc6bSBarry Smith 53604099cc6bSBarry Smith Level: advanced 53614099cc6bSBarry Smith 53624099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 53634099cc6bSBarry Smith 53644099cc6bSBarry Smith Level: advanced 53654099cc6bSBarry Smith @*/ 5366388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 53674099cc6bSBarry Smith { 53684099cc6bSBarry Smith PetscFunctionBegin; 53695f80ce2aSJacob Faibussowitsch CHKERRQ(MatInitializePackage()); 53705f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFunctionListAdd(&MatSeqAIJList,sname,function)); 53714099cc6bSBarry Smith PetscFunctionReturn(0); 53724099cc6bSBarry Smith } 53734099cc6bSBarry Smith 53744099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 53754099cc6bSBarry Smith 53764099cc6bSBarry Smith /*@C 53774099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 53784099cc6bSBarry Smith 53794099cc6bSBarry Smith Not Collective 53804099cc6bSBarry Smith 53814099cc6bSBarry Smith Level: advanced 53824099cc6bSBarry Smith 53834099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 53844099cc6bSBarry Smith @*/ 53854099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 53864099cc6bSBarry Smith { 53874099cc6bSBarry Smith PetscFunctionBegin; 53884099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 53894099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 53904099cc6bSBarry Smith 53915f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL)); 53925f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM)); 53935f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL)); 53949779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 53955f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL)); 5396485f9817SRichard Tran Mills #endif 53975063d097SStefano Zampini #if defined(PETSC_HAVE_CUDA) 53985f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATSEQAIJCUSPARSE, MatConvert_SeqAIJ_SeqAIJCUSPARSE)); 53995063d097SStefano Zampini #endif 54005063d097SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 54015f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATSEQAIJKOKKOS, MatConvert_SeqAIJ_SeqAIJKokkos)); 54025063d097SStefano Zampini #endif 54034099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 54045f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL)); 54054099cc6bSBarry Smith #endif 54064099cc6bSBarry Smith PetscFunctionReturn(0); 54074099cc6bSBarry Smith } 540853dd7562SDmitry Karpeev 540953dd7562SDmitry Karpeev /* 541081824310SBarry Smith Special version for direct calls from Fortran 541181824310SBarry Smith */ 5412af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 541381824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 541481824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 541581824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 541681824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 541781824310SBarry Smith #endif 541881824310SBarry Smith 541981824310SBarry Smith /* Change these macros so can be used in void function */ 542098921bdaSJacob Faibussowitsch 542198921bdaSJacob Faibussowitsch /* Change these macros so can be used in void function */ 542298921bdaSJacob Faibussowitsch /* Identical to CHKERRV, except it assigns to *_ierr */ 542381824310SBarry Smith #undef CHKERRQ 54245f80ce2aSJacob Faibussowitsch #define CHKERRQ(...) do { \ 54255f80ce2aSJacob Faibussowitsch PetscErrorCode ierr_msv_mpiaij = __VA_ARGS__; \ 542698921bdaSJacob Faibussowitsch if (PetscUnlikely(ierr_msv_mpiaij)) { \ 542798921bdaSJacob Faibussowitsch *_ierr = PetscError(PETSC_COMM_SELF,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr_msv_mpiaij,PETSC_ERROR_REPEAT," "); \ 542898921bdaSJacob Faibussowitsch return; \ 542998921bdaSJacob Faibussowitsch } \ 543098921bdaSJacob Faibussowitsch } while (0) 543198921bdaSJacob Faibussowitsch 543298921bdaSJacob Faibussowitsch #undef SETERRQ 543398921bdaSJacob Faibussowitsch #define SETERRQ(comm,ierr,...) do { \ 543498921bdaSJacob Faibussowitsch *_ierr = PetscError(comm,__LINE__,PETSC_FUNCTION_NAME,__FILE__,ierr,PETSC_ERROR_INITIAL,__VA_ARGS__); \ 543598921bdaSJacob Faibussowitsch return; \ 543698921bdaSJacob Faibussowitsch } while (0) 543781824310SBarry Smith 543819caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 543981824310SBarry Smith { 544081824310SBarry Smith Mat A = *AA; 544181824310SBarry Smith PetscInt m = *mm, n = *nn; 544281824310SBarry Smith InsertMode is = *isis; 544381824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 544481824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 544581824310SBarry Smith PetscInt *imax,*ai,*ailen; 544681824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 544754f21887SBarry Smith MatScalar *ap,value,*aa; 5448ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5449ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 545081824310SBarry Smith 545181824310SBarry Smith PetscFunctionBegin; 54524994cf47SJed Brown MatCheckPreallocated(A,1); 545381824310SBarry Smith imax = a->imax; 545481824310SBarry Smith ai = a->i; 545581824310SBarry Smith ailen = a->ilen; 545681824310SBarry Smith aj = a->j; 545781824310SBarry Smith aa = a->a; 545881824310SBarry Smith 545981824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 546081824310SBarry Smith row = im[k]; 546181824310SBarry Smith if (row < 0) continue; 54625f80ce2aSJacob Faibussowitsch PetscCheck(row < A->rmap->n,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 546381824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 546481824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 546581824310SBarry Smith low = 0; 546681824310SBarry Smith high = nrow; 546781824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 546881824310SBarry Smith if (in[l] < 0) continue; 54695f80ce2aSJacob Faibussowitsch PetscCheck(in[l] < A->cmap->n,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 547081824310SBarry Smith col = in[l]; 54712205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 54722205254eSKarl Rupp else value = v[k + l*m]; 54732205254eSKarl Rupp 547481824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 547581824310SBarry Smith 54762205254eSKarl Rupp if (col <= lastcol) low = 0; 54772205254eSKarl Rupp else high = nrow; 547881824310SBarry Smith lastcol = col; 547981824310SBarry Smith while (high-low > 5) { 548081824310SBarry Smith t = (low+high)/2; 548181824310SBarry Smith if (rp[t] > col) high = t; 548281824310SBarry Smith else low = t; 548381824310SBarry Smith } 548481824310SBarry Smith for (i=low; i<high; i++) { 548581824310SBarry Smith if (rp[i] > col) break; 548681824310SBarry Smith if (rp[i] == col) { 548781824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 548881824310SBarry Smith else ap[i] = value; 548981824310SBarry Smith goto noinsert; 549081824310SBarry Smith } 549181824310SBarry Smith } 549281824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 549381824310SBarry Smith if (nonew == 1) goto noinsert; 54945f80ce2aSJacob Faibussowitsch PetscCheck(nonew != -1,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5495fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 549681824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 549781824310SBarry Smith /* shift up all the later entries in this row */ 549881824310SBarry Smith for (ii=N; ii>=i; ii--) { 549981824310SBarry Smith rp[ii+1] = rp[ii]; 550081824310SBarry Smith ap[ii+1] = ap[ii]; 550181824310SBarry Smith } 550281824310SBarry Smith rp[i] = col; 550381824310SBarry Smith ap[i] = value; 5504e56f5c9eSBarry Smith A->nonzerostate++; 550581824310SBarry Smith noinsert:; 550681824310SBarry Smith low = i + 1; 550781824310SBarry Smith } 550881824310SBarry Smith ailen[row] = nrow; 550981824310SBarry Smith } 551081824310SBarry Smith PetscFunctionReturnVoid(); 551181824310SBarry Smith } 551298921bdaSJacob Faibussowitsch /* Undefining these here since they were redefined from their original definition above! No 551398921bdaSJacob Faibussowitsch * other PETSc functions should be defined past this point, as it is impossible to recover the 551498921bdaSJacob Faibussowitsch * original definitions */ 551598921bdaSJacob Faibussowitsch #undef CHKERRQ 551698921bdaSJacob Faibussowitsch #undef SETERRQ 5517