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); 194099cc6bSBarry Smith ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr); 204099cc6bSBarry Smith if (flg) { 214099cc6bSBarry Smith ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr); 224099cc6bSBarry Smith } 234099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 244099cc6bSBarry Smith PetscFunctionReturn(0); 254099cc6bSBarry Smith } 264099cc6bSBarry Smith 27857cbf51SRichard Tran Mills PetscErrorCode MatGetColumnReductions_SeqAIJ(Mat A,PetscInt type,PetscReal *reductions) 280716a85fSBarry Smith { 290716a85fSBarry Smith PetscErrorCode ierr; 300716a85fSBarry Smith PetscInt i,m,n; 310716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 320716a85fSBarry Smith 330716a85fSBarry Smith PetscFunctionBegin; 340716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 35a873a8cdSSam Reynolds ierr = PetscArrayzero(reductions,n);CHKERRQ(ierr); 360716a85fSBarry Smith if (type == NORM_2) { 370716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 38a873a8cdSSam Reynolds reductions[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 390716a85fSBarry Smith } 400716a85fSBarry Smith } else if (type == NORM_1) { 410716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 42a873a8cdSSam Reynolds reductions[aij->j[i]] += PetscAbsScalar(aij->a[i]); 430716a85fSBarry Smith } 440716a85fSBarry Smith } else if (type == NORM_INFINITY) { 450716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 46a873a8cdSSam Reynolds reductions[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),reductions[aij->j[i]]); 470716a85fSBarry Smith } 48857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 49a873a8cdSSam Reynolds for (i=0; i<aij->i[m]; i++) { 50857cbf51SRichard Tran Mills reductions[aij->j[i]] += PetscRealPart(aij->a[i]); 51a873a8cdSSam Reynolds } 52857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 53857cbf51SRichard Tran Mills for (i=0; i<aij->i[m]; i++) { 54857cbf51SRichard Tran Mills reductions[aij->j[i]] += PetscImaginaryPart(aij->a[i]); 55857cbf51SRichard Tran Mills } 56857cbf51SRichard Tran Mills } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown reduction type"); 570716a85fSBarry Smith 580716a85fSBarry Smith if (type == NORM_2) { 59a873a8cdSSam Reynolds for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 60857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 61a873a8cdSSam Reynolds for (i=0; i<n; i++) reductions[i] /= m; 620716a85fSBarry Smith } 630716a85fSBarry Smith PetscFunctionReturn(0); 640716a85fSBarry Smith } 650716a85fSBarry Smith 663a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 673a062f41SBarry Smith { 683a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 693a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 703a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 713a062f41SBarry Smith PetscInt *rows; 723a062f41SBarry Smith PetscErrorCode ierr; 733a062f41SBarry Smith 743a062f41SBarry Smith PetscFunctionBegin; 753a062f41SBarry Smith for (i=0; i<m; i++) { 763a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 773a062f41SBarry Smith cnt++; 783a062f41SBarry Smith } 793a062f41SBarry Smith } 803a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 813a062f41SBarry Smith cnt = 0; 823a062f41SBarry Smith for (i=0; i<m; i++) { 833a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 843a062f41SBarry Smith rows[cnt] = i; 853a062f41SBarry Smith cnt++; 863a062f41SBarry Smith } 873a062f41SBarry Smith } 883a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 893a062f41SBarry Smith PetscFunctionReturn(0); 903a062f41SBarry Smith } 913a062f41SBarry Smith 92f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 936ce1633cSBarry Smith { 946ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 95*fff043a9SJunchao Zhang const MatScalar *aa; 966ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 97b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 986ce1633cSBarry Smith PetscInt *rows; 996ce1633cSBarry Smith PetscErrorCode ierr; 1006ce1633cSBarry Smith 1016ce1633cSBarry Smith PetscFunctionBegin; 102*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1036ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1046ce1633cSBarry Smith diag = a->diag; 1056ce1633cSBarry Smith for (i=0; i<m; i++) { 106b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1076ce1633cSBarry Smith cnt++; 1086ce1633cSBarry Smith } 1096ce1633cSBarry Smith } 110785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1116ce1633cSBarry Smith cnt = 0; 1126ce1633cSBarry Smith for (i=0; i<m; i++) { 113b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1146ce1633cSBarry Smith rows[cnt++] = i; 1156ce1633cSBarry Smith } 1166ce1633cSBarry Smith } 117f1f41ecbSJed Brown *nrows = cnt; 118f1f41ecbSJed Brown *zrows = rows; 119*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 120f1f41ecbSJed Brown PetscFunctionReturn(0); 121f1f41ecbSJed Brown } 122f1f41ecbSJed Brown 123f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 124f1f41ecbSJed Brown { 125f1f41ecbSJed Brown PetscInt nrows,*rows; 126f1f41ecbSJed Brown PetscErrorCode ierr; 127f1f41ecbSJed Brown 128f1f41ecbSJed Brown PetscFunctionBegin; 1290298fd71SBarry Smith *zrows = NULL; 130f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 131ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1326ce1633cSBarry Smith PetscFunctionReturn(0); 1336ce1633cSBarry Smith } 1346ce1633cSBarry Smith 135b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 136b3a44c85SBarry Smith { 137b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 138b3a44c85SBarry Smith const MatScalar *aa; 139b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 140b3a44c85SBarry Smith const PetscInt *ii; 141b3a44c85SBarry Smith PetscInt n,i,j,*rows; 142b3a44c85SBarry Smith PetscErrorCode ierr; 143b3a44c85SBarry Smith 144b3a44c85SBarry Smith PetscFunctionBegin; 1452e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 146f4259b30SLisandro Dalcin *keptrows = NULL; 147b3a44c85SBarry Smith ii = a->i; 148b3a44c85SBarry Smith for (i=0; i<m; i++) { 149b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 150b3a44c85SBarry Smith if (!n) { 151b3a44c85SBarry Smith cnt++; 152b3a44c85SBarry Smith goto ok1; 153b3a44c85SBarry Smith } 1542e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 155b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 156b3a44c85SBarry Smith } 157b3a44c85SBarry Smith cnt++; 158b3a44c85SBarry Smith ok1:; 159b3a44c85SBarry Smith } 1602e5835c6SStefano Zampini if (!cnt) { 1612e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 1622e5835c6SStefano Zampini PetscFunctionReturn(0); 1632e5835c6SStefano Zampini } 164854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 165b3a44c85SBarry Smith cnt = 0; 166b3a44c85SBarry Smith for (i=0; i<m; i++) { 167b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 168b3a44c85SBarry Smith if (!n) continue; 1692e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 170b3a44c85SBarry Smith if (aa[j] != 0.0) { 171b3a44c85SBarry Smith rows[cnt++] = i; 172b3a44c85SBarry Smith break; 173b3a44c85SBarry Smith } 174b3a44c85SBarry Smith } 175b3a44c85SBarry Smith } 1762e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 177b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 178b3a44c85SBarry Smith PetscFunctionReturn(0); 179b3a44c85SBarry Smith } 180b3a44c85SBarry Smith 1817087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 18279299369SBarry Smith { 18379299369SBarry Smith PetscErrorCode ierr; 18479299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 18599e65526SBarry Smith PetscInt i,m = Y->rmap->n; 18699e65526SBarry Smith const PetscInt *diag; 1872e5835c6SStefano Zampini MatScalar *aa; 18899e65526SBarry Smith const PetscScalar *v; 189ace3abfcSBarry Smith PetscBool missing; 19079299369SBarry Smith 19179299369SBarry Smith PetscFunctionBegin; 19209f38230SBarry Smith if (Y->assembled) { 1930298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 19409f38230SBarry Smith if (!missing) { 19579299369SBarry Smith diag = aij->diag; 19699e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 1972e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&aa);CHKERRQ(ierr); 19879299369SBarry Smith if (is == INSERT_VALUES) { 19979299369SBarry Smith for (i=0; i<m; i++) { 20079299369SBarry Smith aa[diag[i]] = v[i]; 20179299369SBarry Smith } 20279299369SBarry Smith } else { 20379299369SBarry Smith for (i=0; i<m; i++) { 20479299369SBarry Smith aa[diag[i]] += v[i]; 20579299369SBarry Smith } 20679299369SBarry Smith } 2072e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&aa);CHKERRQ(ierr); 20899e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 20979299369SBarry Smith PetscFunctionReturn(0); 21079299369SBarry Smith } 211acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 21209f38230SBarry Smith } 21309f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 21409f38230SBarry Smith PetscFunctionReturn(0); 21509f38230SBarry Smith } 21679299369SBarry Smith 2171a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 21817ab2063SBarry Smith { 219416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 220dfbe8321SBarry Smith PetscErrorCode ierr; 22197f1f81fSBarry Smith PetscInt i,ishift; 22217ab2063SBarry Smith 2233a40ed3dSBarry Smith PetscFunctionBegin; 224d0f46423SBarry Smith *m = A->rmap->n; 2253a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 226bfeeae90SHong Zhang ishift = 0; 22753e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2282462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 229bfeeae90SHong Zhang } else if (oshift == 1) { 2301a83f524SJed Brown PetscInt *tia; 231d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2323b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 233854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2341a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2351a83f524SJed Brown *ia = tia; 236ecc77c7aSBarry Smith if (ja) { 2371a83f524SJed Brown PetscInt *tja; 238854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2391a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2401a83f524SJed Brown *ja = tja; 241ecc77c7aSBarry Smith } 2426945ee14SBarry Smith } else { 243ecc77c7aSBarry Smith *ia = a->i; 244ecc77c7aSBarry Smith if (ja) *ja = a->j; 245a2ce50c7SBarry Smith } 2463a40ed3dSBarry Smith PetscFunctionReturn(0); 247a2744918SBarry Smith } 248a2744918SBarry Smith 2491a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2506945ee14SBarry Smith { 251dfbe8321SBarry Smith PetscErrorCode ierr; 2526945ee14SBarry Smith 2533a40ed3dSBarry Smith PetscFunctionBegin; 2543a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 255bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 256606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 257ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 258bcd2baecSBarry Smith } 2593a40ed3dSBarry Smith PetscFunctionReturn(0); 26017ab2063SBarry Smith } 26117ab2063SBarry Smith 2621a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2633b2fbd54SBarry Smith { 2643b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 265dfbe8321SBarry Smith PetscErrorCode ierr; 266d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 26797f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2683b2fbd54SBarry Smith 2693a40ed3dSBarry Smith PetscFunctionBegin; 270899cda47SBarry Smith *nn = n; 2713a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2723b2fbd54SBarry Smith if (symmetric) { 2732462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2743b2fbd54SBarry Smith } else { 275b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 276854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 277b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2783b2fbd54SBarry Smith jj = a->j; 2793b2fbd54SBarry Smith for (i=0; i<nz; i++) { 280bfeeae90SHong Zhang collengths[jj[i]]++; 2813b2fbd54SBarry Smith } 2823b2fbd54SBarry Smith cia[0] = oshift; 2833b2fbd54SBarry Smith for (i=0; i<n; i++) { 2843b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2853b2fbd54SBarry Smith } 286580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2873b2fbd54SBarry Smith jj = a->j; 288a93ec695SBarry Smith for (row=0; row<m; row++) { 289a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 290a93ec695SBarry Smith for (i=0; i<mr; i++) { 291bfeeae90SHong Zhang col = *jj++; 2922205254eSKarl Rupp 2933b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2943b2fbd54SBarry Smith } 2953b2fbd54SBarry Smith } 296606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2973b2fbd54SBarry Smith *ia = cia; *ja = cja; 2983b2fbd54SBarry Smith } 2993a40ed3dSBarry Smith PetscFunctionReturn(0); 3003b2fbd54SBarry Smith } 3013b2fbd54SBarry Smith 3021a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 3033b2fbd54SBarry Smith { 304dfbe8321SBarry Smith PetscErrorCode ierr; 305606d414cSSatish Balay 3063a40ed3dSBarry Smith PetscFunctionBegin; 3073a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 3083b2fbd54SBarry Smith 309606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 310606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3113a40ed3dSBarry Smith PetscFunctionReturn(0); 3123b2fbd54SBarry Smith } 3133b2fbd54SBarry Smith 3147cee066cSHong Zhang /* 3157cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3167cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 317040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3187cee066cSHong Zhang */ 3197cee066cSHong 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) 3207cee066cSHong Zhang { 3217cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3227cee066cSHong Zhang PetscErrorCode ierr; 3237cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 324071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3257cee066cSHong Zhang PetscInt *cspidx; 326071fcb05SBarry Smith const PetscInt *jj; 3277cee066cSHong Zhang 3287cee066cSHong Zhang PetscFunctionBegin; 3297cee066cSHong Zhang *nn = n; 3307cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 331625f6d37SHong Zhang 332b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 333854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 334b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 335b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3367cee066cSHong Zhang jj = a->j; 3377cee066cSHong Zhang for (i=0; i<nz; i++) { 3387cee066cSHong Zhang collengths[jj[i]]++; 3397cee066cSHong Zhang } 3407cee066cSHong Zhang cia[0] = oshift; 3417cee066cSHong Zhang for (i=0; i<n; i++) { 3427cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3437cee066cSHong Zhang } 344580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3457cee066cSHong Zhang jj = a->j; 3467cee066cSHong Zhang for (row=0; row<m; row++) { 3477cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3487cee066cSHong Zhang for (i=0; i<mr; i++) { 3497cee066cSHong Zhang col = *jj++; 350071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 351071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 352071fcb05SBarry Smith cja[tmp] = row + oshift; 3537cee066cSHong Zhang } 3547cee066cSHong Zhang } 3557cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 356071fcb05SBarry Smith *ia = cia; 357071fcb05SBarry Smith *ja = cja; 3587cee066cSHong Zhang *spidx = cspidx; 3597cee066cSHong Zhang PetscFunctionReturn(0); 3607cee066cSHong Zhang } 3617cee066cSHong Zhang 3627cee066cSHong 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) 3637cee066cSHong Zhang { 3647cee066cSHong Zhang PetscErrorCode ierr; 3657cee066cSHong Zhang 3667cee066cSHong Zhang PetscFunctionBegin; 3675243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3687cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3697cee066cSHong Zhang PetscFunctionReturn(0); 3707cee066cSHong Zhang } 3717cee066cSHong Zhang 37287d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 37387d4246cSBarry Smith { 37487d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 37587d4246cSBarry Smith PetscInt *ai = a->i; 376*fff043a9SJunchao Zhang PetscScalar *aa; 37787d4246cSBarry Smith PetscErrorCode ierr; 37887d4246cSBarry Smith 37987d4246cSBarry Smith PetscFunctionBegin; 380*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 381*fff043a9SJunchao Zhang ierr = PetscArraycpy(aa+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 382*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 38387d4246cSBarry Smith PetscFunctionReturn(0); 38487d4246cSBarry Smith } 38587d4246cSBarry Smith 386bd04181cSBarry Smith /* 387bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 388bd04181cSBarry Smith 389bd04181cSBarry Smith - a single row of values is set with each call 390bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 391bd04181cSBarry Smith - the values are always added to the matrix, not set 392bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 393bd04181cSBarry Smith 3941f763a69SBarry Smith This does NOT assume the global column indices are sorted 395bd04181cSBarry Smith 3961f763a69SBarry Smith */ 397bd04181cSBarry Smith 398af0996ceSBarry Smith #include <petsc/private/isimpl.h> 399189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 400189e4007SBarry Smith { 401*fff043a9SJunchao Zhang PetscErrorCode ierr; 402189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4031f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 4041f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 4051f763a69SBarry Smith PetscInt lastcol = -1; 406*fff043a9SJunchao Zhang MatScalar *ap,value,*aa; 407189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 408189e4007SBarry Smith 409*fff043a9SJunchao Zhang PetscFunctionBegin; 410*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 411f38dd0b8SBarry Smith row = ridx[im[0]]; 4121f763a69SBarry Smith rp = aj + ai[row]; 4131f763a69SBarry Smith ap = aa + ai[row]; 4141f763a69SBarry Smith nrow = ailen[row]; 415189e4007SBarry Smith low = 0; 416189e4007SBarry Smith high = nrow; 417189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 418189e4007SBarry Smith col = cidx[in[l]]; 419f38dd0b8SBarry Smith value = v[l]; 420189e4007SBarry Smith 421189e4007SBarry Smith if (col <= lastcol) low = 0; 422189e4007SBarry Smith else high = nrow; 423189e4007SBarry Smith lastcol = col; 424189e4007SBarry Smith while (high-low > 5) { 425189e4007SBarry Smith t = (low+high)/2; 426189e4007SBarry Smith if (rp[t] > col) high = t; 427189e4007SBarry Smith else low = t; 428189e4007SBarry Smith } 429189e4007SBarry Smith for (i=low; i<high; i++) { 430189e4007SBarry Smith if (rp[i] == col) { 4311f763a69SBarry Smith ap[i] += value; 432189e4007SBarry Smith low = i + 1; 4331f763a69SBarry Smith break; 434189e4007SBarry Smith } 435189e4007SBarry Smith } 436189e4007SBarry Smith } 437*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 438f38dd0b8SBarry Smith return 0; 439189e4007SBarry Smith } 440189e4007SBarry Smith 44197f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 44217ab2063SBarry Smith { 443*fff043a9SJunchao Zhang PetscErrorCode ierr; 444416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 445e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 44697f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 447e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 448ce496241SStefano Zampini MatScalar *ap=NULL,value=0.0,*aa; 449ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 450ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 45117ab2063SBarry Smith 4523a40ed3dSBarry Smith PetscFunctionBegin; 453*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 45417ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 455416022c9SBarry Smith row = im[k]; 4565ef9f2a5SBarry Smith if (row < 0) continue; 457cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 458720833daSHong Zhang rp = aj + ai[row]; 459876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 46017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 461416022c9SBarry Smith low = 0; 462c71e6ed7SBarry Smith high = nrow; 46317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4645ef9f2a5SBarry Smith if (in[l] < 0) continue; 465cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 466bfeeae90SHong Zhang col = in[l]; 467071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 468071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 46936db0b34SBarry Smith 4702205254eSKarl Rupp if (col <= lastcol) low = 0; 4712205254eSKarl Rupp else high = nrow; 472e2ee6c50SBarry Smith lastcol = col; 473416022c9SBarry Smith while (high-low > 5) { 474416022c9SBarry Smith t = (low+high)/2; 475416022c9SBarry Smith if (rp[t] > col) high = t; 476416022c9SBarry Smith else low = t; 47717ab2063SBarry Smith } 478416022c9SBarry Smith for (i=low; i<high; i++) { 47917ab2063SBarry Smith if (rp[i] > col) break; 48017ab2063SBarry Smith if (rp[i] == col) { 481876c6284SHong Zhang if (!A->structure_only) { 4820c0d7e18SFande Kong if (is == ADD_VALUES) { 4830c0d7e18SFande Kong ap[i] += value; 4840c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4850c0d7e18SFande Kong } 48617ab2063SBarry Smith else ap[i] = value; 487720833daSHong Zhang } 488e44c0bd4SBarry Smith low = i + 1; 48917ab2063SBarry Smith goto noinsert; 49017ab2063SBarry Smith } 49117ab2063SBarry Smith } 492dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 493c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 494e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 495720833daSHong Zhang if (A->structure_only) { 496876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 497720833daSHong Zhang } else { 498fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 499720833daSHong Zhang } 500c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 501416022c9SBarry Smith /* shift up all the later entries in this row */ 502580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 50317ab2063SBarry Smith rp[i] = col; 504580bdb30SBarry Smith if (!A->structure_only) { 505580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 506580bdb30SBarry Smith ap[i] = value; 507580bdb30SBarry Smith } 508416022c9SBarry Smith low = i + 1; 509e56f5c9eSBarry Smith A->nonzerostate++; 510e44c0bd4SBarry Smith noinsert:; 51117ab2063SBarry Smith } 51217ab2063SBarry Smith ailen[row] = nrow; 51317ab2063SBarry Smith } 514*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 5153a40ed3dSBarry Smith PetscFunctionReturn(0); 51617ab2063SBarry Smith } 51717ab2063SBarry Smith 51819b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 51919b08ed1SBarry Smith { 52019b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 52119b08ed1SBarry Smith PetscInt *rp,k,row; 52219b08ed1SBarry Smith PetscInt *ai = a->i; 52319b08ed1SBarry Smith PetscErrorCode ierr; 52419b08ed1SBarry Smith PetscInt *aj = a->j; 525*fff043a9SJunchao Zhang MatScalar *aa,*ap; 52619b08ed1SBarry Smith 52719b08ed1SBarry Smith PetscFunctionBegin; 52819b08ed1SBarry Smith if (A->was_assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 52919b08ed1SBarry Smith if (m*n+a->nz > a->maxnz) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of entries in matrix will be larger than maximum nonzeros allocated for %D in MatSeqAIJSetTotalPreallocation()",a->maxnz); 530*fff043a9SJunchao Zhang 531*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 53219b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 53319b08ed1SBarry Smith row = im[k]; 53419b08ed1SBarry Smith rp = aj + ai[row]; 53519b08ed1SBarry Smith ap = aa + ai[row]; 53619b08ed1SBarry Smith 53719b08ed1SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 53819b08ed1SBarry Smith if (!A->structure_only) { 53919b08ed1SBarry Smith if (v) { 54019b08ed1SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 54119b08ed1SBarry Smith v += n; 54219b08ed1SBarry Smith } else { 54319b08ed1SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 54419b08ed1SBarry Smith } 54519b08ed1SBarry Smith } 54619b08ed1SBarry Smith a->ilen[row] = n; 54719b08ed1SBarry Smith a->imax[row] = n; 54819b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 54919b08ed1SBarry Smith a->nz += n; 55019b08ed1SBarry Smith } 551*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 55219b08ed1SBarry Smith PetscFunctionReturn(0); 55319b08ed1SBarry Smith } 55419b08ed1SBarry Smith 55519b08ed1SBarry Smith /*@ 55619b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 55719b08ed1SBarry Smith 55819b08ed1SBarry Smith Input Parameters: 55919b08ed1SBarry Smith + A - the SeqAIJ matrix 56019b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 56119b08ed1SBarry Smith 56219b08ed1SBarry Smith Level: advanced 56319b08ed1SBarry Smith 56419b08ed1SBarry Smith Notes: 56519b08ed1SBarry 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. 56619b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 56719b08ed1SBarry Smith as always with multiple matrix assemblies. 56819b08ed1SBarry Smith 56919b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 57019b08ed1SBarry Smith @*/ 57119b08ed1SBarry Smith 57219b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 57319b08ed1SBarry Smith { 57419b08ed1SBarry Smith PetscErrorCode ierr; 57519b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 57619b08ed1SBarry Smith 57719b08ed1SBarry Smith PetscFunctionBegin; 57819b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 57919b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 58019b08ed1SBarry Smith a->maxnz = nztotal; 58119b08ed1SBarry Smith if (!a->imax) { 58219b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr); 58319b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 58419b08ed1SBarry Smith } 58519b08ed1SBarry Smith if (!a->ilen) { 58619b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr); 58719b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 58819b08ed1SBarry Smith } else { 58919b08ed1SBarry Smith ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 59019b08ed1SBarry Smith } 59119b08ed1SBarry Smith 59219b08ed1SBarry Smith /* allocate the matrix space */ 59319b08ed1SBarry Smith if (A->structure_only) { 59419b08ed1SBarry Smith ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr); 59519b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr); 59619b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr); 59719b08ed1SBarry Smith } else { 59819b08ed1SBarry Smith ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr); 59919b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 60019b08ed1SBarry Smith } 60119b08ed1SBarry Smith a->i[0] = 0; 60219b08ed1SBarry Smith if (A->structure_only) { 60319b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 60419b08ed1SBarry Smith a->free_a = PETSC_FALSE; 60519b08ed1SBarry Smith } else { 60619b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 60719b08ed1SBarry Smith a->free_a = PETSC_TRUE; 60819b08ed1SBarry Smith } 60919b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 61019b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 61119b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 61219b08ed1SBarry Smith PetscFunctionReturn(0); 61319b08ed1SBarry Smith } 61419b08ed1SBarry Smith 615071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 616071fcb05SBarry Smith { 617071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 618071fcb05SBarry Smith PetscInt *rp,k,row; 619071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 620071fcb05SBarry Smith PetscErrorCode ierr; 621071fcb05SBarry Smith PetscInt *aj = a->j; 622*fff043a9SJunchao Zhang MatScalar *aa,*ap; 623071fcb05SBarry Smith 624071fcb05SBarry Smith PetscFunctionBegin; 625*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 626071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 627071fcb05SBarry Smith row = im[k]; 62819b08ed1SBarry Smith if (PetscUnlikelyDebug(n > a->imax[row])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Preallocation for row %D does not match number of columns provided",n); 629071fcb05SBarry Smith rp = aj + ai[row]; 630071fcb05SBarry Smith ap = aa + ai[row]; 631071fcb05SBarry Smith if (!A->was_assembled) { 632071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 633071fcb05SBarry Smith } 634071fcb05SBarry Smith if (!A->structure_only) { 635071fcb05SBarry Smith if (v) { 636071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 637071fcb05SBarry Smith v += n; 638071fcb05SBarry Smith } else { 639071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 640071fcb05SBarry Smith } 641071fcb05SBarry Smith } 642071fcb05SBarry Smith ailen[row] = n; 643071fcb05SBarry Smith a->nz += n; 644071fcb05SBarry Smith } 645*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 646071fcb05SBarry Smith PetscFunctionReturn(0); 647071fcb05SBarry Smith } 648071fcb05SBarry Smith 649a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6507eb43aa7SLois Curfman McInnes { 651*fff043a9SJunchao Zhang PetscErrorCode ierr; 6527eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 65397f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 65497f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 655*fff043a9SJunchao Zhang MatScalar *ap,*aa; 6567eb43aa7SLois Curfman McInnes 6573a40ed3dSBarry Smith PetscFunctionBegin; 658*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 6597eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6607eb43aa7SLois Curfman McInnes row = im[k]; 661e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 662e32f2f54SBarry Smith if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 663bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6647eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6657eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 666e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 667e32f2f54SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 668bfeeae90SHong Zhang col = in[l]; 6697eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6707eb43aa7SLois Curfman McInnes while (high-low > 5) { 6717eb43aa7SLois Curfman McInnes t = (low+high)/2; 6727eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6737eb43aa7SLois Curfman McInnes else low = t; 6747eb43aa7SLois Curfman McInnes } 6757eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6767eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6777eb43aa7SLois Curfman McInnes if (rp[i] == col) { 678b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6797eb43aa7SLois Curfman McInnes goto finished; 6807eb43aa7SLois Curfman McInnes } 6817eb43aa7SLois Curfman McInnes } 68297e567efSBarry Smith *v++ = 0.0; 6837eb43aa7SLois Curfman McInnes finished:; 6847eb43aa7SLois Curfman McInnes } 6857eb43aa7SLois Curfman McInnes } 686*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 6873a40ed3dSBarry Smith PetscFunctionReturn(0); 6887eb43aa7SLois Curfman McInnes } 6897eb43aa7SLois Curfman McInnes 6903ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 69117ab2063SBarry Smith { 6923ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 693c898d852SStefano Zampini const PetscScalar *av; 6943ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 6953ea6fe3dSLisandro Dalcin PetscInt *rowlens; 6966849ba73SBarry Smith PetscErrorCode ierr; 69717ab2063SBarry Smith 6983a40ed3dSBarry Smith PetscFunctionBegin; 6993ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7002205254eSKarl Rupp 7013ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7023ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7033ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7043ea6fe3dSLisandro Dalcin nz = A->nz; 705416022c9SBarry Smith 7063ea6fe3dSLisandro Dalcin /* write matrix header */ 7073ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7083ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7093ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 710416022c9SBarry Smith 7113ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7123ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7133ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7143ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7153ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7163ea6fe3dSLisandro Dalcin /* store column indices */ 7173ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 718416022c9SBarry Smith /* store nonzero values */ 719c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr); 720c898d852SStefano Zampini ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr); 721c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr); 722b37d52dbSMark F. Adams 7233ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7243ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7253a40ed3dSBarry Smith PetscFunctionReturn(0); 72617ab2063SBarry Smith } 727416022c9SBarry Smith 7287dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7297dc0baabSHong Zhang { 7307dc0baabSHong Zhang PetscErrorCode ierr; 7317dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7327dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7337dc0baabSHong Zhang 7347dc0baabSHong Zhang PetscFunctionBegin; 7357dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7367dc0baabSHong Zhang for (i=0; i<m; i++) { 7377dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7387dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7397dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7407dc0baabSHong Zhang } 7417dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7427dc0baabSHong Zhang } 7437dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7447dc0baabSHong Zhang PetscFunctionReturn(0); 7457dc0baabSHong Zhang } 7467dc0baabSHong Zhang 74709573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 748cd155464SBarry Smith 749dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 750416022c9SBarry Smith { 751416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 752c898d852SStefano Zampini const PetscScalar *av; 753dfbe8321SBarry Smith PetscErrorCode ierr; 75460e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 755e060cb09SBarry Smith const char *name; 756f3ef73ceSBarry Smith PetscViewerFormat format; 75717ab2063SBarry Smith 7583a40ed3dSBarry Smith PetscFunctionBegin; 7597dc0baabSHong Zhang if (A->structure_only) { 7607dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7617dc0baabSHong Zhang PetscFunctionReturn(0); 7627dc0baabSHong Zhang } 76343e49210SHong Zhang 764b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 7652e5835c6SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 7662e5835c6SStefano Zampini 767c898d852SStefano Zampini /* trigger copy to CPU if needed */ 768c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 769c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 77071c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 77197f1f81fSBarry Smith PetscInt nofinalvalue = 0; 77260e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 773c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 774d00d2cf4SBarry Smith nofinalvalue = 1; 775d00d2cf4SBarry Smith } 776d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 777d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 77877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 779fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 780fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 781fbfe6fa7SJed Brown #else 78277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 783fbfe6fa7SJed Brown #endif 784b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 78517ab2063SBarry Smith 78617ab2063SBarry Smith for (i=0; i<m; i++) { 78760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 788aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 789a9bf72d8SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 79017ab2063SBarry Smith #else 79160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 79217ab2063SBarry Smith #endif 79317ab2063SBarry Smith } 79417ab2063SBarry Smith } 795d00d2cf4SBarry Smith if (nofinalvalue) { 796c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 797c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 798c337ccceSJed Brown #else 799d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 800c337ccceSJed Brown #endif 801d00d2cf4SBarry Smith } 802317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 803fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 804d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 805fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 806d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 80744cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 80877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 80960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 810aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 81136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 81260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 81336db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 81460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 81536db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 81660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8176831982aSBarry Smith } 81844cd7ae7SLois Curfman McInnes #else 81960e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 82044cd7ae7SLois Curfman McInnes #endif 82144cd7ae7SLois Curfman McInnes } 822b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 82344cd7ae7SLois Curfman McInnes } 824d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 825fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 82697f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 827d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 828854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 829496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 830496be53dSLois Curfman McInnes sptr[i] = nzd+1; 83160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 832496be53dSLois Curfman McInnes if (a->j[j] >= i) { 833aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 83436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 835496be53dSLois Curfman McInnes #else 836496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 837496be53dSLois Curfman McInnes #endif 838496be53dSLois Curfman McInnes } 839496be53dSLois Curfman McInnes } 840496be53dSLois Curfman McInnes } 8412e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 84277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8432e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8442205254eSKarl Rupp if (i+4<m) { 8452205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr); 8462205254eSKarl Rupp } else if (i+3<m) { 8472205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr); 8482205254eSKarl Rupp } else if (i+2<m) { 8492205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8502205254eSKarl Rupp } else if (i+1<m) { 8512205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8522205254eSKarl Rupp } else if (i<m) { 8532205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8542205254eSKarl Rupp } else { 8552205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8562205254eSKarl Rupp } 857496be53dSLois Curfman McInnes } 858b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 859606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 860496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 86160e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 86277431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 863496be53dSLois Curfman McInnes } 864b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 865496be53dSLois Curfman McInnes } 866b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 867496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 86860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 869496be53dSLois Curfman McInnes if (a->j[j] >= i) { 870aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 87136db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 87260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8736831982aSBarry Smith } 874496be53dSLois Curfman McInnes #else 87560e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 876496be53dSLois Curfman McInnes #endif 877496be53dSLois Curfman McInnes } 878496be53dSLois Curfman McInnes } 879b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 880496be53dSLois Curfman McInnes } 881d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 882fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 88397f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 88487828ca2SBarry Smith PetscScalar value; 88568f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 88668f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 88768f1ed48SBarry Smith 88868f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 88968f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 89068f1ed48SBarry Smith realonly = PETSC_FALSE; 89168f1ed48SBarry Smith break; 89268f1ed48SBarry Smith } 89368f1ed48SBarry Smith } 89468f1ed48SBarry Smith #endif 89502594712SBarry Smith 896d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 89702594712SBarry Smith for (i=0; i<m; i++) { 89802594712SBarry Smith jcnt = 0; 899d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 900e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 90102594712SBarry Smith value = a->a[cnt++]; 902e24b481bSBarry Smith jcnt++; 90302594712SBarry Smith } else { 90402594712SBarry Smith value = 0.0; 90502594712SBarry Smith } 906aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 90768f1ed48SBarry Smith if (realonly) { 90860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 90968f1ed48SBarry Smith } else { 91060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 91168f1ed48SBarry Smith } 91202594712SBarry Smith #else 91360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 91402594712SBarry Smith #endif 91502594712SBarry Smith } 916b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 91702594712SBarry Smith } 918d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9193c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 920150b93efSMatthew G. Knepley PetscInt fshift=1; 921d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9223c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 92319303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9243c215bfdSMatthew Knepley #else 92519303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9263c215bfdSMatthew Knepley #endif 927d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9283c215bfdSMatthew Knepley for (i=0; i<m; i++) { 92960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9303c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 931a9a0e077SKarl Rupp ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 9323c215bfdSMatthew Knepley #else 933150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9343c215bfdSMatthew Knepley #endif 9353c215bfdSMatthew Knepley } 9363c215bfdSMatthew Knepley } 937d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9383a40ed3dSBarry Smith } else { 939d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 940d5f3da31SBarry Smith if (A->factortype) { 94116cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 94216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 94316cd7e1dSShri Abhyankar /* L part */ 94460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 94516cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 94616cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 94760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 94816cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9496712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 95016cd7e1dSShri Abhyankar } else { 95160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 95216cd7e1dSShri Abhyankar } 95316cd7e1dSShri Abhyankar #else 95460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 95516cd7e1dSShri Abhyankar #endif 95616cd7e1dSShri Abhyankar } 95716cd7e1dSShri Abhyankar /* diagonal */ 95816cd7e1dSShri Abhyankar j = a->diag[i]; 95916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 96016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 96160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 96216cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9636712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr); 96416cd7e1dSShri Abhyankar } else { 96560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 96616cd7e1dSShri Abhyankar } 96716cd7e1dSShri Abhyankar #else 96860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 96916cd7e1dSShri Abhyankar #endif 97016cd7e1dSShri Abhyankar 97116cd7e1dSShri Abhyankar /* U part */ 97260e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 97316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 97560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 97616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 97722ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 97816cd7e1dSShri Abhyankar } else { 97960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 98016cd7e1dSShri Abhyankar } 98116cd7e1dSShri Abhyankar #else 98260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 98316cd7e1dSShri Abhyankar #endif 98416cd7e1dSShri Abhyankar } 98516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 98616cd7e1dSShri Abhyankar } 98716cd7e1dSShri Abhyankar } else { 98817ab2063SBarry Smith for (i=0; i<m; i++) { 98977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 99060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 991aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 99236db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 99360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 99436db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 99560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 9963a40ed3dSBarry Smith } else { 99760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 99817ab2063SBarry Smith } 99917ab2063SBarry Smith #else 100060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 100117ab2063SBarry Smith #endif 100217ab2063SBarry Smith } 1003b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 100417ab2063SBarry Smith } 100516cd7e1dSShri Abhyankar } 1006d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 100717ab2063SBarry Smith } 1008b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10093a40ed3dSBarry Smith PetscFunctionReturn(0); 1010416022c9SBarry Smith } 1011416022c9SBarry Smith 10129804daf3SBarry Smith #include <petscdraw.h> 1013dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1014416022c9SBarry Smith { 1015480ef9eaSBarry Smith Mat A = (Mat) Aa; 1016416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1017dfbe8321SBarry Smith PetscErrorCode ierr; 1018383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1019383922c3SLisandro Dalcin int color; 1020b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1021b0a32e0cSBarry Smith PetscViewer viewer; 1022f3ef73ceSBarry Smith PetscViewerFormat format; 1023*fff043a9SJunchao Zhang const PetscScalar *aa; 1024cddf8d76SBarry Smith 10253a40ed3dSBarry Smith PetscFunctionBegin; 1026480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1027b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1028b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1029383922c3SLisandro Dalcin 1030416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 1031*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1032fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1033383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10340513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1035b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1036416022c9SBarry Smith for (i=0; i<m; i++) { 1037cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1038bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1039bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1040*fff043a9SJunchao Zhang if (PetscRealPart(aa[j]) >= 0.) continue; 1041b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1042cddf8d76SBarry Smith } 1043cddf8d76SBarry Smith } 1044b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1045cddf8d76SBarry Smith for (i=0; i<m; i++) { 1046cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1047bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1048bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1049*fff043a9SJunchao Zhang if (aa[j] != 0.) continue; 1050b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1051cddf8d76SBarry Smith } 1052cddf8d76SBarry Smith } 1053b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1054cddf8d76SBarry Smith for (i=0; i<m; i++) { 1055cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1056bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1057bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1058*fff043a9SJunchao Zhang if (PetscRealPart(aa[j]) <= 0.) continue; 1059b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1060416022c9SBarry Smith } 1061416022c9SBarry Smith } 1062383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10630513a670SBarry Smith } else { 10640513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10650513a670SBarry Smith /* first determine max of all nonzero values */ 1066b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1067383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1068b0a32e0cSBarry Smith PetscDraw popup; 10690513a670SBarry Smith 10700513a670SBarry Smith for (i=0; i<nz; i++) { 1071*fff043a9SJunchao Zhang if (PetscAbsScalar(aa[i]) > maxv) maxv = PetscAbsScalar(aa[i]); 10720513a670SBarry Smith } 1073383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1074b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 107545f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1076383922c3SLisandro Dalcin 1077383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10780513a670SBarry Smith for (i=0; i<m; i++) { 1079383922c3SLisandro Dalcin y_l = m - i - 1.0; 1080383922c3SLisandro Dalcin y_r = y_l + 1.0; 1081bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1082383922c3SLisandro Dalcin x_l = a->j[j]; 1083383922c3SLisandro Dalcin x_r = x_l + 1.0; 1084*fff043a9SJunchao Zhang color = PetscDrawRealToColor(PetscAbsScalar(aa[count]),minv,maxv); 1085b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 10860513a670SBarry Smith count++; 10870513a670SBarry Smith } 10880513a670SBarry Smith } 1089383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10900513a670SBarry Smith } 1091*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 1092480ef9eaSBarry Smith PetscFunctionReturn(0); 1093480ef9eaSBarry Smith } 1094cddf8d76SBarry Smith 10959804daf3SBarry Smith #include <petscdraw.h> 1096dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1097480ef9eaSBarry Smith { 1098dfbe8321SBarry Smith PetscErrorCode ierr; 1099b0a32e0cSBarry Smith PetscDraw draw; 110036db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1101ace3abfcSBarry Smith PetscBool isnull; 1102480ef9eaSBarry Smith 1103480ef9eaSBarry Smith PetscFunctionBegin; 1104b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1105b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1106480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1107480ef9eaSBarry Smith 1108d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1109480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1110b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1111832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1112b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11130298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1114832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11153a40ed3dSBarry Smith PetscFunctionReturn(0); 1116416022c9SBarry Smith } 1117416022c9SBarry Smith 1118dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1119416022c9SBarry Smith { 1120dfbe8321SBarry Smith PetscErrorCode ierr; 1121ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1122416022c9SBarry Smith 11233a40ed3dSBarry Smith PetscFunctionBegin; 1124251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1125251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1126251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1127c45a1595SBarry Smith if (iascii) { 11283a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11290f5bd95cSBarry Smith } else if (isbinary) { 11303a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11310f5bd95cSBarry Smith } else if (isdraw) { 11323a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 113311aeaf0aSBarry Smith } 11344108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11353a40ed3dSBarry Smith PetscFunctionReturn(0); 113617ab2063SBarry Smith } 113719bcc07fSBarry Smith 1138dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 113917ab2063SBarry Smith { 1140416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11416849ba73SBarry Smith PetscErrorCode ierr; 1142580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1143d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 114454f21887SBarry Smith MatScalar *aa = a->a,*ap; 11453447b6efSHong Zhang PetscReal ratio = 0.6; 114617ab2063SBarry Smith 11473a40ed3dSBarry Smith PetscFunctionBegin; 11483a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1149071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1150b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1151b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 1152b215bc84SStefano Zampini ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1153b215bc84SStefano Zampini PetscFunctionReturn(0); 1154b215bc84SStefano Zampini } 115517ab2063SBarry Smith 115643ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 115717ab2063SBarry Smith for (i=1; i<m; i++) { 1158416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 115917ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 116094a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 116117ab2063SBarry Smith if (fshift) { 1162bfeeae90SHong Zhang ip = aj + ai[i]; 1163bfeeae90SHong Zhang ap = aa + ai[i]; 116417ab2063SBarry Smith N = ailen[i]; 1165580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1166580bdb30SBarry Smith if (!A->structure_only) { 1167580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 116817ab2063SBarry Smith } 116917ab2063SBarry Smith } 117017ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 117117ab2063SBarry Smith } 117217ab2063SBarry Smith if (m) { 117317ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 117417ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 117517ab2063SBarry Smith } 11767b083b7cSBarry Smith 117717ab2063SBarry Smith /* reset ilen and imax for each row */ 11787b083b7cSBarry Smith a->nonzerorowcnt = 0; 1179396832f4SHong Zhang if (A->structure_only) { 1180071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1181071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1182396832f4SHong Zhang } else { /* !A->structure_only */ 118317ab2063SBarry Smith for (i=0; i<m; i++) { 118417ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 11857b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 118617ab2063SBarry Smith } 1187396832f4SHong Zhang } 1188bfeeae90SHong Zhang a->nz = ai[m]; 118965e19b50SBarry Smith if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift); 119017ab2063SBarry Smith 119109f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1192d0f46423SBarry Smith ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr); 1193ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1194ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 11952205254eSKarl Rupp 11968e58a170SBarry Smith A->info.mallocs += a->reallocs; 1197dd5f02e7SSatish Balay a->reallocs = 0; 11986712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 119936db0b34SBarry Smith a->rmax = rmax; 12004e220ebcSLois Curfman McInnes 1201396832f4SHong Zhang if (!A->structure_only) { 120211e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1203396832f4SHong Zhang } 12044108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 12053a40ed3dSBarry Smith PetscFunctionReturn(0); 120617ab2063SBarry Smith } 120717ab2063SBarry Smith 120899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 120999cafbc1SBarry Smith { 121099cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 121199cafbc1SBarry Smith PetscInt i,nz = a->nz; 12122e5835c6SStefano Zampini MatScalar *aa; 1213acf2f550SJed Brown PetscErrorCode ierr; 121499cafbc1SBarry Smith 121599cafbc1SBarry Smith PetscFunctionBegin; 12162e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 121799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 12182e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1219acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 122099cafbc1SBarry Smith PetscFunctionReturn(0); 122199cafbc1SBarry Smith } 122299cafbc1SBarry Smith 122399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 122499cafbc1SBarry Smith { 122599cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 122699cafbc1SBarry Smith PetscInt i,nz = a->nz; 12272e5835c6SStefano Zampini MatScalar *aa; 1228acf2f550SJed Brown PetscErrorCode ierr; 122999cafbc1SBarry Smith 123099cafbc1SBarry Smith PetscFunctionBegin; 12312e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 123299cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 12332e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1234acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 123599cafbc1SBarry Smith PetscFunctionReturn(0); 123699cafbc1SBarry Smith } 123799cafbc1SBarry Smith 1238dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 123917ab2063SBarry Smith { 1240dfbe8321SBarry Smith PetscErrorCode ierr; 1241*fff043a9SJunchao Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1242*fff043a9SJunchao Zhang MatScalar *aa; 12433a40ed3dSBarry Smith 12443a40ed3dSBarry Smith PetscFunctionBegin; 1245*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayWrite(A,&aa);CHKERRQ(ierr); 1246*fff043a9SJunchao Zhang ierr = PetscArrayzero(aa,a->i[A->rmap->n]);CHKERRQ(ierr); 1247*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayWrite(A,&aa);CHKERRQ(ierr); 1248acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12493a40ed3dSBarry Smith PetscFunctionReturn(0); 125017ab2063SBarry Smith } 1251416022c9SBarry Smith 1252dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 125317ab2063SBarry Smith { 1254416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1255dfbe8321SBarry Smith PetscErrorCode ierr; 1256d5d45c9bSBarry Smith 12573a40ed3dSBarry Smith PetscFunctionBegin; 1258aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1259d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 126017ab2063SBarry Smith #endif 1261e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12626bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12636bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 126405b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1265d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1266071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1267071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1268846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 126971f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 127005b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12716bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 127205b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1273cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1274a30b2313SHong Zhang 12754108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1276bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1277901853e0SKris Buschelman 12786718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 12796718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 12806718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 12816718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 12826718818eSStefano Zampini due to different matrix sizes */ 12836718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 12846718818eSStefano Zampini 1285f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1286bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1287bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1288bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1289bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1290bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1291bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 12924222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 12934222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1294e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1295fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 12964222ddf1SHong Zhang #endif 12973d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 12983d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 12993d0639e7SStefano Zampini #endif 13004222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1301af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1302af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1303af8000cdSHong Zhang #endif 1304d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1305d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1306d24d4204SJose E. Roman #endif 130763c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 130863c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13094222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 131063c07aadSStefano Zampini #endif 1311b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1312c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1313c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1314bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1315bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1316846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1317bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1318bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13194222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13204222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13214222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 1322ad7e164aSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJKron_C",NULL);CHKERRQ(ierr); 13233a40ed3dSBarry Smith PetscFunctionReturn(0); 132417ab2063SBarry Smith } 132517ab2063SBarry Smith 1326ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 132717ab2063SBarry Smith { 1328416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13294846f1f5SKris Buschelman PetscErrorCode ierr; 13303a40ed3dSBarry Smith 13313a40ed3dSBarry Smith PetscFunctionBegin; 1332a65d3064SKris Buschelman switch (op) { 1333a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13344e0d8c25SBarry Smith a->roworiented = flg; 1335a65d3064SKris Buschelman break; 1336a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1337a9817697SBarry Smith a->keepnonzeropattern = flg; 1338a65d3064SKris Buschelman break; 1339512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1340512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1341a65d3064SKris Buschelman break; 1342a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13434e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1344a65d3064SKris Buschelman break; 1345a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13464e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1347a65d3064SKris Buschelman break; 134828b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 134928b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 135028b2fa4aSMatthew Knepley break; 1351a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13524e0d8c25SBarry Smith a->ignorezeroentries = flg; 13530df259c2SBarry Smith break; 13543d472b54SHong Zhang case MAT_SPD: 1355b1646e73SJed Brown case MAT_SYMMETRIC: 1356b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1357b1646e73SJed Brown case MAT_HERMITIAN: 1358b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1359957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13605021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13615021d80fSJed Brown break; 13628c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1363a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1364a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1365290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1366a65d3064SKris Buschelman break; 1367b87ac2d8SJed Brown case MAT_USE_INODES: 1368b215bc84SStefano Zampini ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr); 1369b87ac2d8SJed Brown break; 1370c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1371c10200c1SHong Zhang A->submat_singleis = flg; 1372c10200c1SHong Zhang break; 1373071fcb05SBarry Smith case MAT_SORTED_FULL: 1374071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1375071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1376071fcb05SBarry Smith break; 13771a2c6b5cSJunchao Zhang case MAT_FORM_EXPLICIT_TRANSPOSE: 13781a2c6b5cSJunchao Zhang A->form_explicit_transpose = flg; 13791a2c6b5cSJunchao Zhang break; 1380a65d3064SKris Buschelman default: 1381e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1382a65d3064SKris Buschelman } 13833a40ed3dSBarry Smith PetscFunctionReturn(0); 138417ab2063SBarry Smith } 138517ab2063SBarry Smith 1386dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 138717ab2063SBarry Smith { 1388416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13896849ba73SBarry Smith PetscErrorCode ierr; 1390fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1391c898d852SStefano Zampini PetscScalar *x; 1392c898d852SStefano Zampini const PetscScalar *aa; 139317ab2063SBarry Smith 13943a40ed3dSBarry Smith PetscFunctionBegin; 1395d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1396e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1397c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1398d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1399d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1400fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 14012c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1402fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1403c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 140435e7444dSHong Zhang PetscFunctionReturn(0); 140535e7444dSHong Zhang } 140635e7444dSHong Zhang 1407fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 140835e7444dSHong Zhang for (i=0; i<n; i++) { 1409fdc842d1SBarry Smith x[i] = 0.0; 141035e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 141135e7444dSHong Zhang if (aj[j] == i) { 141235e7444dSHong Zhang x[i] = aa[j]; 141317ab2063SBarry Smith break; 141417ab2063SBarry Smith } 141517ab2063SBarry Smith } 141617ab2063SBarry Smith } 1417fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1418c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14193a40ed3dSBarry Smith PetscFunctionReturn(0); 142017ab2063SBarry Smith } 142117ab2063SBarry Smith 1422c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1423dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 142417ab2063SBarry Smith { 1425416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1426d9ca1df4SBarry Smith PetscScalar *y; 1427d9ca1df4SBarry Smith const PetscScalar *x; 1428dfbe8321SBarry Smith PetscErrorCode ierr; 1429d0f46423SBarry Smith PetscInt m = A->rmap->n; 14305c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1431*fff043a9SJunchao Zhang const MatScalar *v,*aa; 1432a77337e4SBarry Smith PetscScalar alpha; 1433d9ca1df4SBarry Smith PetscInt n,i,j; 1434d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14353447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1436ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14375c897100SBarry Smith #endif 143817ab2063SBarry Smith 14393a40ed3dSBarry Smith PetscFunctionBegin; 14402e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1441d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14421ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1443*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 14445c897100SBarry Smith 14455c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1446*fff043a9SJunchao Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,aa,y); 14475c897100SBarry Smith #else 14483447b6efSHong Zhang if (usecprow) { 14493447b6efSHong Zhang m = cprow.nrows; 14503447b6efSHong Zhang ii = cprow.i; 14517b2bb3b9SHong Zhang ridx = cprow.rindex; 14523447b6efSHong Zhang } else { 14533447b6efSHong Zhang ii = a->i; 14543447b6efSHong Zhang } 145517ab2063SBarry Smith for (i=0; i<m; i++) { 14563447b6efSHong Zhang idx = a->j + ii[i]; 1457*fff043a9SJunchao Zhang v = aa + ii[i]; 14583447b6efSHong Zhang n = ii[i+1] - ii[i]; 14593447b6efSHong Zhang if (usecprow) { 14607b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14613447b6efSHong Zhang } else { 146217ab2063SBarry Smith alpha = x[i]; 14633447b6efSHong Zhang } 146404fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 146517ab2063SBarry Smith } 14665c897100SBarry Smith #endif 1467dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1468d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14691ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1470*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14713a40ed3dSBarry Smith PetscFunctionReturn(0); 147217ab2063SBarry Smith } 147317ab2063SBarry Smith 1474dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14755c897100SBarry Smith { 1476dfbe8321SBarry Smith PetscErrorCode ierr; 14775c897100SBarry Smith 14785c897100SBarry Smith PetscFunctionBegin; 1479170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 14805c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 14815c897100SBarry Smith PetscFunctionReturn(0); 14825c897100SBarry Smith } 14835c897100SBarry Smith 1484c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 148578b84d54SShri Abhyankar 1486dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 148717ab2063SBarry Smith { 1488416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1489d9fead3dSBarry Smith PetscScalar *y; 149054f21887SBarry Smith const PetscScalar *x; 1491*fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1492dfbe8321SBarry Smith PetscErrorCode ierr; 1493003131ecSBarry Smith PetscInt m=A->rmap->n; 14940298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 14957b083b7cSBarry Smith PetscInt n,i; 1496362ced78SSatish Balay PetscScalar sum; 1497ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 149817ab2063SBarry Smith 1499b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 150097952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1501fee21e36SBarry Smith #endif 1502fee21e36SBarry Smith 15033a40ed3dSBarry Smith PetscFunctionBegin; 1504b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1505b215bc84SStefano Zampini ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr); 1506b215bc84SStefano Zampini PetscFunctionReturn(0); 1507b215bc84SStefano Zampini } 1508*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr); 15093649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15101ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1511416022c9SBarry Smith ii = a->i; 15124eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1513580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 151497952fefSHong Zhang m = a->compressedrow.nrows; 151597952fefSHong Zhang ii = a->compressedrow.i; 151697952fefSHong Zhang ridx = a->compressedrow.rindex; 151797952fefSHong Zhang for (i=0; i<m; i++) { 151897952fefSHong Zhang n = ii[i+1] - ii[i]; 151997952fefSHong Zhang aj = a->j + ii[i]; 1520*fff043a9SJunchao Zhang aa = a_a + ii[i]; 152197952fefSHong Zhang sum = 0.0; 1522003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1523003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 152497952fefSHong Zhang y[*ridx++] = sum; 152597952fefSHong Zhang } 152697952fefSHong Zhang } else { /* do not use compressed row format */ 1527b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15283d3eaba7SBarry Smith aj = a->j; 1529*fff043a9SJunchao Zhang aa = a_a; 1530b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1531b05257ddSBarry Smith #else 153217ab2063SBarry Smith for (i=0; i<m; i++) { 1533003131ecSBarry Smith n = ii[i+1] - ii[i]; 1534003131ecSBarry Smith aj = a->j + ii[i]; 1535*fff043a9SJunchao Zhang aa = a_a + ii[i]; 153617ab2063SBarry Smith sum = 0.0; 1537003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 153817ab2063SBarry Smith y[i] = sum; 153917ab2063SBarry Smith } 15408d195f9aSBarry Smith #endif 1541b05257ddSBarry Smith } 15427b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15433649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15441ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1545*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr); 15463a40ed3dSBarry Smith PetscFunctionReturn(0); 154717ab2063SBarry Smith } 154817ab2063SBarry Smith 1549b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1550b434eb95SMatthew G. Knepley { 1551b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1552b434eb95SMatthew G. Knepley PetscScalar *y; 1553b434eb95SMatthew G. Knepley const PetscScalar *x; 1554*fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1555b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1556b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1557b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1558b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1559b434eb95SMatthew G. Knepley PetscScalar sum; 1560b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1561b434eb95SMatthew G. Knepley 1562b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1563b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1564b434eb95SMatthew G. Knepley #endif 1565b434eb95SMatthew G. Knepley 1566b434eb95SMatthew G. Knepley PetscFunctionBegin; 1567*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr); 1568b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1569b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1570b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1571b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1572b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1573b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1574b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1575b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1576b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1577*fff043a9SJunchao Zhang aa = a_a + ii[i]; 1578b434eb95SMatthew G. Knepley sum = 0.0; 1579b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1580b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1581b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1582b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1583b434eb95SMatthew G. Knepley } 1584b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15853d3eaba7SBarry Smith ii = a->i; 1586b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1587b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1588b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1589*fff043a9SJunchao Zhang aa = a_a + ii[i]; 1590b434eb95SMatthew G. Knepley sum = 0.0; 1591b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1592b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1593b434eb95SMatthew G. Knepley y[i] = sum; 1594b434eb95SMatthew G. Knepley } 1595b434eb95SMatthew G. Knepley } 1596b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1597b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1598b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1599*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr); 1600b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1601b434eb95SMatthew G. Knepley } 1602b434eb95SMatthew G. Knepley 1603b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1604b434eb95SMatthew G. Knepley { 1605b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1606b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1607b434eb95SMatthew G. Knepley const PetscScalar *x; 1608*fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1609b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1610b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1611b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1612b434eb95SMatthew G. Knepley PetscScalar sum; 1613b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1614b434eb95SMatthew G. Knepley 1615b434eb95SMatthew G. Knepley PetscFunctionBegin; 1616*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr); 1617b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1618d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1619b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1620b434eb95SMatthew G. Knepley if (zz != yy) { 1621580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1622b434eb95SMatthew G. Knepley } 1623b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1624b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1625b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1626b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1627b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1628b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1629*fff043a9SJunchao Zhang aa = a_a + ii[i]; 1630b434eb95SMatthew G. Knepley sum = y[*ridx]; 1631b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1632b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1633b434eb95SMatthew G. Knepley } 1634b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16353d3eaba7SBarry Smith ii = a->i; 1636b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1637b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1638b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1639*fff043a9SJunchao Zhang aa = a_a + ii[i]; 1640b434eb95SMatthew G. Knepley sum = y[i]; 1641b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1642b434eb95SMatthew G. Knepley z[i] = sum; 1643b434eb95SMatthew G. Knepley } 1644b434eb95SMatthew G. Knepley } 1645b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1646b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1647d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1648*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr); 1649b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1650b434eb95SMatthew G. Knepley } 1651b434eb95SMatthew G. Knepley 1652c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1653dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 165417ab2063SBarry Smith { 1655416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1656f15663dcSBarry Smith PetscScalar *y,*z; 1657f15663dcSBarry Smith const PetscScalar *x; 1658*fff043a9SJunchao Zhang const MatScalar *aa,*a_a; 1659dfbe8321SBarry Smith PetscErrorCode ierr; 1660d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1661d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1662362ced78SSatish Balay PetscScalar sum; 1663ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16649ea0dfa2SSatish Balay 16653a40ed3dSBarry Smith PetscFunctionBegin; 1666b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1667b215bc84SStefano Zampini ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr); 1668b215bc84SStefano Zampini PetscFunctionReturn(0); 1669b215bc84SStefano Zampini } 1670*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&a_a);CHKERRQ(ierr); 1671f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1672d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16734eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16744eb6d288SHong Zhang if (zz != yy) { 1675580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16764eb6d288SHong Zhang } 167797952fefSHong Zhang m = a->compressedrow.nrows; 167897952fefSHong Zhang ii = a->compressedrow.i; 167997952fefSHong Zhang ridx = a->compressedrow.rindex; 168097952fefSHong Zhang for (i=0; i<m; i++) { 168197952fefSHong Zhang n = ii[i+1] - ii[i]; 168297952fefSHong Zhang aj = a->j + ii[i]; 1683*fff043a9SJunchao Zhang aa = a_a + ii[i]; 168497952fefSHong Zhang sum = y[*ridx]; 1685f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 168697952fefSHong Zhang z[*ridx++] = sum; 168797952fefSHong Zhang } 168897952fefSHong Zhang } else { /* do not use compressed row format */ 16893d3eaba7SBarry Smith ii = a->i; 1690f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 16913d3eaba7SBarry Smith aj = a->j; 1692*fff043a9SJunchao Zhang aa = a_a; 1693f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1694f15663dcSBarry Smith #else 169517ab2063SBarry Smith for (i=0; i<m; i++) { 1696f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1697f15663dcSBarry Smith aj = a->j + ii[i]; 1698*fff043a9SJunchao Zhang aa = a_a + ii[i]; 169917ab2063SBarry Smith sum = y[i]; 1700f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 170117ab2063SBarry Smith z[i] = sum; 170217ab2063SBarry Smith } 170302ab625aSSatish Balay #endif 1704f15663dcSBarry Smith } 1705dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1706f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1707d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1708*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&a_a);CHKERRQ(ierr); 17093a40ed3dSBarry Smith PetscFunctionReturn(0); 171017ab2063SBarry Smith } 171117ab2063SBarry Smith 171217ab2063SBarry Smith /* 171317ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 171417ab2063SBarry Smith */ 1715dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 171617ab2063SBarry Smith { 1717416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17186849ba73SBarry Smith PetscErrorCode ierr; 1719d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 172017ab2063SBarry Smith 17213a40ed3dSBarry Smith PetscFunctionBegin; 172209f38230SBarry Smith if (!a->diag) { 1723785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17243bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 172509f38230SBarry Smith } 1726d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 172709f38230SBarry Smith a->diag[i] = a->i[i+1]; 1728bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1729bfeeae90SHong Zhang if (a->j[j] == i) { 173009f38230SBarry Smith a->diag[i] = j; 173117ab2063SBarry Smith break; 173217ab2063SBarry Smith } 173317ab2063SBarry Smith } 173417ab2063SBarry Smith } 17353a40ed3dSBarry Smith PetscFunctionReturn(0); 173617ab2063SBarry Smith } 173717ab2063SBarry Smith 173861ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 173961ecd0c6SBarry Smith { 174061ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 174161ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 174261ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 174361ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 174461ecd0c6SBarry Smith PetscErrorCode ierr; 174561ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 174661ecd0c6SBarry Smith 174761ecd0c6SBarry Smith PetscFunctionBegin; 174861ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 174961ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 175061ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 175161ecd0c6SBarry Smith PetscFunctionReturn(0); 175261ecd0c6SBarry Smith } 175361ecd0c6SBarry Smith 175461ecd0c6SBarry Smith if (a->diagonaldense) { 175561ecd0c6SBarry Smith cnt = 0; 175661ecd0c6SBarry Smith } else { 175761ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 175861ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 175961ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 176061ecd0c6SBarry Smith cnt++; 176161ecd0c6SBarry Smith mdiag[i] = 1; 176261ecd0c6SBarry Smith } 176361ecd0c6SBarry Smith } 176461ecd0c6SBarry Smith } 176561ecd0c6SBarry Smith if (!cnt) { 176661ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 176761ecd0c6SBarry Smith } else { 1768b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1769b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 177061ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 177161ecd0c6SBarry Smith 177261ecd0c6SBarry Smith a->a = NULL; 177361ecd0c6SBarry Smith a->j = NULL; 177461ecd0c6SBarry Smith a->i = NULL; 177561ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 177661ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 177761ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1778447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 177961ecd0c6SBarry Smith } 178061ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 178161ecd0c6SBarry Smith 178261ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 178361ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 178461ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1785447d62f5SStefano Zampini if (i < A->cmap->n) { 178661ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 178761ecd0c6SBarry Smith } 1788447d62f5SStefano Zampini } 178961ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179061ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 179161ecd0c6SBarry Smith if (singlemalloc) { 179261ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 179361ecd0c6SBarry Smith } else { 179461ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 179561ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 179661ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 179761ecd0c6SBarry Smith } 179861ecd0c6SBarry Smith } 179961ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 180061ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 180161ecd0c6SBarry Smith PetscFunctionReturn(0); 180261ecd0c6SBarry Smith } 180361ecd0c6SBarry Smith 1804be5855fcSBarry Smith /* 1805be5855fcSBarry Smith Checks for missing diagonals 1806be5855fcSBarry Smith */ 1807ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1808be5855fcSBarry Smith { 1809be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18107734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1811994fe344SLisandro Dalcin PetscErrorCode ierr; 1812be5855fcSBarry Smith 1813be5855fcSBarry Smith PetscFunctionBegin; 181409f38230SBarry Smith *missing = PETSC_FALSE; 18157734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 181609f38230SBarry Smith *missing = PETSC_TRUE; 181709f38230SBarry Smith if (d) *d = 0; 1818994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 181909f38230SBarry Smith } else { 182001445905SHong Zhang PetscInt n; 182101445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1822f1e2ffcdSBarry Smith diag = a->diag; 182301445905SHong Zhang for (i=0; i<n; i++) { 18247734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 182509f38230SBarry Smith *missing = PETSC_TRUE; 182609f38230SBarry Smith if (d) *d = i; 1827994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1828358d2f5dSShri Abhyankar break; 182909f38230SBarry Smith } 1830be5855fcSBarry Smith } 1831be5855fcSBarry Smith } 1832be5855fcSBarry Smith PetscFunctionReturn(0); 1833be5855fcSBarry Smith } 1834be5855fcSBarry Smith 18350da83c2eSBarry Smith #include <petscblaslapack.h> 18360da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18370da83c2eSBarry Smith 18380da83c2eSBarry Smith /* 18390da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18400da83c2eSBarry Smith */ 18410da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18420da83c2eSBarry Smith { 18430da83c2eSBarry Smith PetscErrorCode ierr; 18440da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18450da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18460da83c2eSBarry Smith const PetscReal shift = 0.0; 18470da83c2eSBarry Smith PetscInt ipvt[5]; 18480da83c2eSBarry Smith PetscScalar work[25],*v_work; 18490da83c2eSBarry Smith 18500da83c2eSBarry Smith PetscFunctionBegin; 18510da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18520da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18530da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18540da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18550da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18560da83c2eSBarry Smith } 18570da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18580da83c2eSBarry Smith if (bsizemax > 7) { 18590da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18600da83c2eSBarry Smith } 18610da83c2eSBarry Smith ncnt = 0; 18620da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18630da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18640da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18650da83c2eSBarry Smith switch (bsizes[i]) { 18660da83c2eSBarry Smith case 1: 18670da83c2eSBarry Smith *diag = 1.0/(*diag); 18680da83c2eSBarry Smith break; 18690da83c2eSBarry Smith case 2: 18700da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18710da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18720da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18730da83c2eSBarry Smith break; 18740da83c2eSBarry Smith case 3: 18750da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18760da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18770da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18780da83c2eSBarry Smith break; 18790da83c2eSBarry Smith case 4: 18800da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18810da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18820da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 18830da83c2eSBarry Smith break; 18840da83c2eSBarry Smith case 5: 18850da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18860da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18870da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 18880da83c2eSBarry Smith break; 18890da83c2eSBarry Smith case 6: 18900da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18910da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18920da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 18930da83c2eSBarry Smith break; 18940da83c2eSBarry Smith case 7: 18950da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18960da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18970da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 18980da83c2eSBarry Smith break; 18990da83c2eSBarry Smith default: 19000da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19010da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19020da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 19030da83c2eSBarry Smith } 19040da83c2eSBarry Smith ncnt += bsizes[i]; 19050da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 19060da83c2eSBarry Smith } 19070da83c2eSBarry Smith if (bsizemax > 7) { 19080da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 19090da83c2eSBarry Smith } 19100da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 19110da83c2eSBarry Smith PetscFunctionReturn(0); 19120da83c2eSBarry Smith } 19130da83c2eSBarry Smith 1914422a814eSBarry Smith /* 1915422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1916422a814eSBarry Smith */ 19177087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 191871f1c65dSBarry Smith { 191971f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 192071f1c65dSBarry Smith PetscErrorCode ierr; 1921d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 19222e5835c6SStefano Zampini const MatScalar *v; 192354f21887SBarry Smith PetscScalar *idiag,*mdiag; 192471f1c65dSBarry Smith 192571f1c65dSBarry Smith PetscFunctionBegin; 192671f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 192771f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 192871f1c65dSBarry Smith diag = a->diag; 192971f1c65dSBarry Smith if (!a->idiag) { 1930dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19313bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar));CHKERRQ(ierr); 193271f1c65dSBarry Smith } 19332e5835c6SStefano Zampini 193471f1c65dSBarry Smith mdiag = a->mdiag; 193571f1c65dSBarry Smith idiag = a->idiag; 19362e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 1937422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 193871f1c65dSBarry Smith for (i=0; i<m; i++) { 193971f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1940899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1941899639b0SHong Zhang if (PetscRealPart(fshift)) { 1942899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19437b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19447b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19457b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1946a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1947899639b0SHong Zhang } 194871f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 194971f1c65dSBarry Smith } 195071f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 195171f1c65dSBarry Smith } else { 195271f1c65dSBarry Smith for (i=0; i<m; i++) { 195371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 195471f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 195571f1c65dSBarry Smith } 1956dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 195771f1c65dSBarry Smith } 195871f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 19592e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 196071f1c65dSBarry Smith PetscFunctionReturn(0); 196171f1c65dSBarry Smith } 196271f1c65dSBarry Smith 1963c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 196441f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 196517ab2063SBarry Smith { 1966416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1967e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 19682e5835c6SStefano Zampini const MatScalar *v,*idiag=NULL,*mdiag,*aa; 196954f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1970dfbe8321SBarry Smith PetscErrorCode ierr; 19713d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 197297f1f81fSBarry Smith const PetscInt *idx,*diag; 197317ab2063SBarry Smith 19743a40ed3dSBarry Smith PetscFunctionBegin; 1975b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 1976b215bc84SStefano Zampini ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 1977b215bc84SStefano Zampini PetscFunctionReturn(0); 1978b215bc84SStefano Zampini } 1979b965ef7fSBarry Smith its = its*lits; 198091723122SBarry Smith 198171f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 198271f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 198371f1c65dSBarry Smith a->fshift = fshift; 198471f1c65dSBarry Smith a->omega = omega; 1985ed480e8bSBarry Smith 198671f1c65dSBarry Smith diag = a->diag; 198771f1c65dSBarry Smith t = a->ssor_work; 1988ed480e8bSBarry Smith idiag = a->idiag; 198971f1c65dSBarry Smith mdiag = a->mdiag; 1990ed480e8bSBarry Smith 19912e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 19921ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 19933649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1994ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 199517ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 199617ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1997ed480e8bSBarry Smith bs = b; 199817ab2063SBarry Smith for (i=0; i<m; i++) { 199971f1c65dSBarry Smith d = fshift + mdiag[i]; 2000416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2001ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20022e5835c6SStefano Zampini v = aa + diag[i] + 1; 200317ab2063SBarry Smith sum = b[i]*d/omega; 2004003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 200517ab2063SBarry Smith x[i] = sum; 200617ab2063SBarry Smith } 20071ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20083649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20092e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 2010efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20113a40ed3dSBarry Smith PetscFunctionReturn(0); 201217ab2063SBarry Smith } 2013c783ea89SBarry Smith 20142205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 20152205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 20164c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 2017887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 201817ab2063SBarry Smith 201917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 202017ab2063SBarry Smith 2021887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 202217ab2063SBarry Smith */ 202317ab2063SBarry Smith scale = (2.0/omega) - 1.0; 202417ab2063SBarry Smith 202517ab2063SBarry Smith /* x = (E + U)^{-1} b */ 202617ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2027416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2028ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20292e5835c6SStefano Zampini v = aa + diag[i] + 1; 203017ab2063SBarry Smith sum = b[i]; 2031e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2032ed480e8bSBarry Smith x[i] = sum*idiag[i]; 203317ab2063SBarry Smith } 203417ab2063SBarry Smith 203517ab2063SBarry Smith /* t = b - (2*E - D)x */ 20362e5835c6SStefano Zampini v = aa; 20372205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 203817ab2063SBarry Smith 203917ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2040ed480e8bSBarry Smith ts = t; 2041416022c9SBarry Smith diag = a->diag; 204217ab2063SBarry Smith for (i=0; i<m; i++) { 2043416022c9SBarry Smith n = diag[i] - a->i[i]; 2044ed480e8bSBarry Smith idx = a->j + a->i[i]; 20452e5835c6SStefano Zampini v = aa + a->i[i]; 204617ab2063SBarry Smith sum = t[i]; 2047003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2048ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2049733d66baSBarry Smith /* x = x + t */ 2050733d66baSBarry Smith x[i] += t[i]; 205117ab2063SBarry Smith } 205217ab2063SBarry Smith 2053dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20541ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20553649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20563a40ed3dSBarry Smith PetscFunctionReturn(0); 205717ab2063SBarry Smith } 205817ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 205917ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 206017ab2063SBarry Smith for (i=0; i<m; i++) { 2061416022c9SBarry Smith n = diag[i] - a->i[i]; 2062ed480e8bSBarry Smith idx = a->j + a->i[i]; 20632e5835c6SStefano Zampini v = aa + a->i[i]; 206417ab2063SBarry Smith sum = b[i]; 2065e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20665c99c7daSBarry Smith t[i] = sum; 2067ed480e8bSBarry Smith x[i] = sum*idiag[i]; 206817ab2063SBarry Smith } 20695c99c7daSBarry Smith xb = t; 2070efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20713a40ed3dSBarry Smith } else xb = b; 207217ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 207317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2074416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2075ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20762e5835c6SStefano Zampini v = aa + diag[i] + 1; 207717ab2063SBarry Smith sum = xb[i]; 2078e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20795c99c7daSBarry Smith if (xb == b) { 2080ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20815c99c7daSBarry Smith } else { 2082b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 208317ab2063SBarry Smith } 20845c99c7daSBarry Smith } 2085b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 208617ab2063SBarry Smith } 208717ab2063SBarry Smith its--; 208817ab2063SBarry Smith } 208917ab2063SBarry Smith while (its--) { 209017ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 209117ab2063SBarry Smith for (i=0; i<m; i++) { 2092b19a5dc2SMark Adams /* lower */ 2093b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2094ed480e8bSBarry Smith idx = a->j + a->i[i]; 20952e5835c6SStefano Zampini v = aa + a->i[i]; 209617ab2063SBarry Smith sum = b[i]; 2097e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2098b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2099b19a5dc2SMark Adams /* upper */ 2100b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2101b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21022e5835c6SStefano Zampini v = aa + diag[i] + 1; 2103b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2104b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 210517ab2063SBarry Smith } 2106b19a5dc2SMark Adams xb = t; 21079f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2108b19a5dc2SMark Adams } else xb = b; 210917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 211017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2111b19a5dc2SMark Adams sum = xb[i]; 2112b19a5dc2SMark Adams if (xb == b) { 2113b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2114416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2115ed480e8bSBarry Smith idx = a->j + a->i[i]; 21162e5835c6SStefano Zampini v = aa + a->i[i]; 2117e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2118ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2119b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2120b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2121b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21222e5835c6SStefano Zampini v = aa + diag[i] + 1; 2123b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2124b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 212517ab2063SBarry Smith } 2126b19a5dc2SMark Adams } 2127b19a5dc2SMark Adams if (xb == b) { 21289f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2129b19a5dc2SMark Adams } else { 2130b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2131b19a5dc2SMark Adams } 213217ab2063SBarry Smith } 213317ab2063SBarry Smith } 21342e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 21351ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 21363649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2137365a8a9eSBarry Smith PetscFunctionReturn(0); 213817ab2063SBarry Smith } 213917ab2063SBarry Smith 2140dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 214117ab2063SBarry Smith { 2142416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21434e220ebcSLois Curfman McInnes 21443a40ed3dSBarry Smith PetscFunctionBegin; 21454e220ebcSLois Curfman McInnes info->block_size = 1.0; 21463966268fSBarry Smith info->nz_allocated = a->maxnz; 21473966268fSBarry Smith info->nz_used = a->nz; 21483966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21493966268fSBarry Smith info->assemblies = A->num_ass; 21503966268fSBarry Smith info->mallocs = A->info.mallocs; 21517adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2152d5f3da31SBarry Smith if (A->factortype) { 21534e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21544e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21554e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21564e220ebcSLois Curfman McInnes } else { 21574e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21584e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21594e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21604e220ebcSLois Curfman McInnes } 21613a40ed3dSBarry Smith PetscFunctionReturn(0); 216217ab2063SBarry Smith } 216317ab2063SBarry Smith 21642b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 216517ab2063SBarry Smith { 2166416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2167c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21686849ba73SBarry Smith PetscErrorCode ierr; 216997b48c8fSBarry Smith const PetscScalar *xx; 21702e5835c6SStefano Zampini PetscScalar *bb,*aa; 2171c7da8527SEric Chamberland PetscInt d = 0; 217217ab2063SBarry Smith 21733a40ed3dSBarry Smith PetscFunctionBegin; 217497b48c8fSBarry Smith if (x && b) { 217597b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 217697b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 217797b48c8fSBarry Smith for (i=0; i<N; i++) { 217897b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2179447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 218097b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 218197b48c8fSBarry Smith } 218297b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 218397b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 218497b48c8fSBarry Smith } 218597b48c8fSBarry Smith 21862e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 2187a9817697SBarry Smith if (a->keepnonzeropattern) { 2188f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2189e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 21902e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2191f1e2ffcdSBarry Smith } 2192f4df32b1SMatthew Knepley if (diag != 0.0) { 2193c7da8527SEric Chamberland for (i=0; i<N; i++) { 2194c7da8527SEric Chamberland d = rows[i]; 2195447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2196c7da8527SEric Chamberland if (a->diag[d] >= a->i[d+1]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %D",d); 2197c7da8527SEric Chamberland } 2198f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2199447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 22002e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 2201f1e2ffcdSBarry Smith } 2202f1e2ffcdSBarry Smith } 2203f1e2ffcdSBarry Smith } else { 2204f4df32b1SMatthew Knepley if (diag != 0.0) { 220517ab2063SBarry Smith for (i=0; i<N; i++) { 2206e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22077ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2208447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2209447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2210447d62f5SStefano Zampini } else { 2211416022c9SBarry Smith a->ilen[rows[i]] = 1; 22122e5835c6SStefano Zampini aa[a->i[rows[i]]] = diag; 2213bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2214447d62f5SStefano Zampini } 2215447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2216f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 221717ab2063SBarry Smith } 221817ab2063SBarry Smith } 22193a40ed3dSBarry Smith } else { 222017ab2063SBarry Smith for (i=0; i<N; i++) { 2221e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2222416022c9SBarry Smith a->ilen[rows[i]] = 0; 222317ab2063SBarry Smith } 222417ab2063SBarry Smith } 2225e56f5c9eSBarry Smith A->nonzerostate++; 2226f1e2ffcdSBarry Smith } 22272e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22284099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22293a40ed3dSBarry Smith PetscFunctionReturn(0); 223017ab2063SBarry Smith } 223117ab2063SBarry Smith 22326e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 22336e169961SBarry Smith { 22346e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22356e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22366e169961SBarry Smith PetscErrorCode ierr; 22372b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22386e169961SBarry Smith const PetscScalar *xx; 22392e5835c6SStefano Zampini PetscScalar *bb,*aa; 22406e169961SBarry Smith 22416e169961SBarry Smith PetscFunctionBegin; 22422e5835c6SStefano Zampini if (!N) PetscFunctionReturn(0); 22432e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 22446e169961SBarry Smith if (x && b) { 22456e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22466e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22472b40b63fSBarry Smith vecs = PETSC_TRUE; 22486e169961SBarry Smith } 22491795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22506e169961SBarry Smith for (i=0; i<N; i++) { 22516e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22522e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22532205254eSKarl Rupp 22546e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22556e169961SBarry Smith } 22566e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22576e169961SBarry Smith if (!zeroed[i]) { 22586e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22594cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22602e5835c6SStefano Zampini if (vecs) bb[i] -= aa[j]*xx[a->j[j]]; 22612e5835c6SStefano Zampini aa[j] = 0.0; 22626e169961SBarry Smith } 22636e169961SBarry Smith } 22644cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22656e169961SBarry Smith } 22666e169961SBarry Smith if (x && b) { 22676e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22686e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22696e169961SBarry Smith } 22706e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22716e169961SBarry Smith if (diag != 0.0) { 22726e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22731d5a398dSstefano_zampini if (missing) { 22741d5a398dSstefano_zampini for (i=0; i<N; i++) { 22754cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22764cf107fdSStefano Zampini if (a->nonew && rows[i] >= d) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D (%D)",d,rows[i]); 22771d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 22781d5a398dSstefano_zampini } 22791d5a398dSstefano_zampini } else { 22806e169961SBarry Smith for (i=0; i<N; i++) { 22812e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 22826e169961SBarry Smith } 22836e169961SBarry Smith } 22841d5a398dSstefano_zampini } 22852e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22864099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22876e169961SBarry Smith PetscFunctionReturn(0); 22886e169961SBarry Smith } 22896e169961SBarry Smith 2290a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 229117ab2063SBarry Smith { 22922e5835c6SStefano Zampini PetscErrorCode ierr; 2293*fff043a9SJunchao Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2294*fff043a9SJunchao Zhang const PetscScalar *aa; 2295*fff043a9SJunchao Zhang PetscInt *itmp; 229617ab2063SBarry Smith 22973a40ed3dSBarry Smith PetscFunctionBegin; 22982e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 2299416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 23002e5835c6SStefano Zampini if (v) *v = (PetscScalar*)(aa + a->i[row]); 230117ab2063SBarry Smith if (idx) { 2302bfeeae90SHong Zhang itmp = a->j + a->i[row]; 230326fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2304f4259b30SLisandro Dalcin else *idx = NULL; 230517ab2063SBarry Smith } 23062e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 23073a40ed3dSBarry Smith PetscFunctionReturn(0); 230817ab2063SBarry Smith } 230917ab2063SBarry Smith 2310a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 231117ab2063SBarry Smith { 23123a40ed3dSBarry Smith PetscFunctionBegin; 2313cb4a9cd9SHong Zhang if (nz) *nz = 0; 23142e5835c6SStefano Zampini if (idx) *idx = NULL; 23152e5835c6SStefano Zampini if (v) *v = NULL; 23163a40ed3dSBarry Smith PetscFunctionReturn(0); 231717ab2063SBarry Smith } 231817ab2063SBarry Smith 2319dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 232017ab2063SBarry Smith { 2321416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23222e5835c6SStefano Zampini const MatScalar *v; 232336db0b34SBarry Smith PetscReal sum = 0.0; 23246849ba73SBarry Smith PetscErrorCode ierr; 232597f1f81fSBarry Smith PetscInt i,j; 232617ab2063SBarry Smith 23273a40ed3dSBarry Smith PetscFunctionBegin; 23282e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 232917ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2330570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2331570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 233273cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2333570b7f6dSBarry Smith #else 2334416022c9SBarry Smith for (i=0; i<a->nz; i++) { 233536db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 233617ab2063SBarry Smith } 23378f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2338570b7f6dSBarry Smith #endif 2339ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 23403a40ed3dSBarry Smith } else if (type == NORM_1) { 234136db0b34SBarry Smith PetscReal *tmp; 234297f1f81fSBarry Smith PetscInt *jj = a->j; 23431795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2344064f8208SBarry Smith *nrm = 0.0; 2345416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2346bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 234717ab2063SBarry Smith } 2348d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2349064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 235017ab2063SBarry Smith } 2351606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 235251f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23533a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2354064f8208SBarry Smith *nrm = 0.0; 2355d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 23562e5835c6SStefano Zampini const PetscScalar *v2 = v + a->i[j]; 235717ab2063SBarry Smith sum = 0.0; 2358416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 23592e5835c6SStefano Zampini sum += PetscAbsScalar(*v2); v2++; 236017ab2063SBarry Smith } 2361064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 236217ab2063SBarry Smith } 236351f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2364f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23652e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 23663a40ed3dSBarry Smith PetscFunctionReturn(0); 236717ab2063SBarry Smith } 236817ab2063SBarry Smith 23694e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 23704e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 23714e938277SHong Zhang { 23724e938277SHong Zhang PetscErrorCode ierr; 23734e938277SHong Zhang PetscInt i,j,anzj; 23744e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 23754e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 23764e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 23774e938277SHong Zhang 23784e938277SHong Zhang PetscFunctionBegin; 23794e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2380854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2381785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2382785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 23834e938277SHong Zhang 23844e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 23854e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 238626fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 23874e938277SHong Zhang /* Form ati for csr format of A^T. */ 238826fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 23894e938277SHong Zhang 23904e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2391580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 23924e938277SHong Zhang 23934e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 23944e938277SHong Zhang for (i=0;i<am;i++) { 23954e938277SHong Zhang anzj = ai[i+1] - ai[i]; 23964e938277SHong Zhang for (j=0;j<anzj;j++) { 23974e938277SHong Zhang atj[atfill[*aj]] = i; 23984e938277SHong Zhang atfill[*aj++] += 1; 23994e938277SHong Zhang } 24004e938277SHong Zhang } 24014e938277SHong Zhang 24024e938277SHong Zhang /* Clean up temporary space and complete requests. */ 24034e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2404ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 240533d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2406b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2407a2f3521dSMark F. Adams 24084e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 24094e938277SHong Zhang b->free_a = PETSC_FALSE; 24104e938277SHong Zhang b->free_ij = PETSC_TRUE; 24114e938277SHong Zhang b->nonew = 0; 24124e938277SHong Zhang PetscFunctionReturn(0); 24134e938277SHong Zhang } 24144e938277SHong Zhang 24157087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2416cd0d46ebSvictorle { 24173d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 241854f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 24192e5835c6SStefano Zampini const MatScalar *va,*vb; 24206849ba73SBarry Smith PetscErrorCode ierr; 242197f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2422cd0d46ebSvictorle 2423cd0d46ebSvictorle PetscFunctionBegin; 2424cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2425cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24265485867bSBarry Smith if (ma!=nb || na!=mb) { 24275485867bSBarry Smith *f = PETSC_FALSE; 24285485867bSBarry Smith PetscFunctionReturn(0); 24295485867bSBarry Smith } 24302e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&va);CHKERRQ(ierr); 24312e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(B,&vb);CHKERRQ(ierr); 2432cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2433cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2434785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2435785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2436cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2437cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2438cd0d46ebSvictorle 2439cd0d46ebSvictorle *f = PETSC_TRUE; 2440cd0d46ebSvictorle for (i=0; i<ma; i++) { 2441cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 244297f1f81fSBarry Smith PetscInt idc,idr; 24435485867bSBarry Smith PetscScalar vc,vr; 2444cd0d46ebSvictorle /* column/row index/value */ 24455485867bSBarry Smith idc = adx[aptr[i]]; 24465485867bSBarry Smith idr = bdx[bptr[idc]]; 24475485867bSBarry Smith vc = va[aptr[i]]; 24485485867bSBarry Smith vr = vb[bptr[idc]]; 24495485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24505485867bSBarry Smith *f = PETSC_FALSE; 24515485867bSBarry Smith goto done; 2452cd0d46ebSvictorle } else { 24535485867bSBarry Smith aptr[i]++; 24545485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2455cd0d46ebSvictorle } 2456cd0d46ebSvictorle } 2457cd0d46ebSvictorle } 2458cd0d46ebSvictorle done: 2459cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24603aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 24612e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&va);CHKERRQ(ierr); 24622e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(B,&vb);CHKERRQ(ierr); 2463cd0d46ebSvictorle PetscFunctionReturn(0); 2464cd0d46ebSvictorle } 2465cd0d46ebSvictorle 24667087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24671cbb95d3SBarry Smith { 24683d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 246954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 247054f21887SBarry Smith MatScalar *va,*vb; 24711cbb95d3SBarry Smith PetscErrorCode ierr; 24721cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 24731cbb95d3SBarry Smith 24741cbb95d3SBarry Smith PetscFunctionBegin; 24751cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 24761cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24771cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 24781cbb95d3SBarry Smith *f = PETSC_FALSE; 24791cbb95d3SBarry Smith PetscFunctionReturn(0); 24801cbb95d3SBarry Smith } 24811cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 24821cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 24831cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2484785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2485785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 24861cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 24871cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 24881cbb95d3SBarry Smith 24891cbb95d3SBarry Smith *f = PETSC_TRUE; 24901cbb95d3SBarry Smith for (i=0; i<ma; i++) { 24911cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 24921cbb95d3SBarry Smith PetscInt idc,idr; 24931cbb95d3SBarry Smith PetscScalar vc,vr; 24941cbb95d3SBarry Smith /* column/row index/value */ 24951cbb95d3SBarry Smith idc = adx[aptr[i]]; 24961cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 24971cbb95d3SBarry Smith vc = va[aptr[i]]; 24981cbb95d3SBarry Smith vr = vb[bptr[idc]]; 24991cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 25001cbb95d3SBarry Smith *f = PETSC_FALSE; 25011cbb95d3SBarry Smith goto done; 25021cbb95d3SBarry Smith } else { 25031cbb95d3SBarry Smith aptr[i]++; 25041cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 25051cbb95d3SBarry Smith } 25061cbb95d3SBarry Smith } 25071cbb95d3SBarry Smith } 25081cbb95d3SBarry Smith done: 25091cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 25101cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 25111cbb95d3SBarry Smith PetscFunctionReturn(0); 25121cbb95d3SBarry Smith } 25131cbb95d3SBarry Smith 2514ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25159e29f15eSvictorle { 2516dfbe8321SBarry Smith PetscErrorCode ierr; 25176e111a19SKarl Rupp 25189e29f15eSvictorle PetscFunctionBegin; 25195485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25209e29f15eSvictorle PetscFunctionReturn(0); 25219e29f15eSvictorle } 25229e29f15eSvictorle 2523ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25241cbb95d3SBarry Smith { 25251cbb95d3SBarry Smith PetscErrorCode ierr; 25266e111a19SKarl Rupp 25271cbb95d3SBarry Smith PetscFunctionBegin; 25281cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25291cbb95d3SBarry Smith PetscFunctionReturn(0); 25301cbb95d3SBarry Smith } 25311cbb95d3SBarry Smith 2532dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 253317ab2063SBarry Smith { 2534416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2535fff8e43fSBarry Smith const PetscScalar *l,*r; 2536fff8e43fSBarry Smith PetscScalar x; 253754f21887SBarry Smith MatScalar *v; 2538dfbe8321SBarry Smith PetscErrorCode ierr; 2539fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2540fff8e43fSBarry Smith const PetscInt *jj; 254117ab2063SBarry Smith 25423a40ed3dSBarry Smith PetscFunctionBegin; 254317ab2063SBarry Smith if (ll) { 25443ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 25453ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2546e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2547e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2548fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 25492e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 255017ab2063SBarry Smith for (i=0; i<m; i++) { 255117ab2063SBarry Smith x = l[i]; 2552416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25532205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 255417ab2063SBarry Smith } 2555fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2556efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 25572e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 255817ab2063SBarry Smith } 255917ab2063SBarry Smith if (rr) { 2560e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2561e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2562fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 25632e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 25642e5835c6SStefano Zampini jj = a->j; 25652205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 25662e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 2567fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2568efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 256917ab2063SBarry Smith } 2570acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 25713a40ed3dSBarry Smith PetscFunctionReturn(0); 257217ab2063SBarry Smith } 257317ab2063SBarry Smith 25747dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 257517ab2063SBarry Smith { 2576db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 25776849ba73SBarry Smith PetscErrorCode ierr; 2578d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 257997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 25805d0c19d7SBarry Smith const PetscInt *irow,*icol; 25812e5835c6SStefano Zampini const PetscScalar *aa; 25825d0c19d7SBarry Smith PetscInt nrows,ncols; 258397f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 258454f21887SBarry Smith MatScalar *a_new,*mat_a; 2585416022c9SBarry Smith Mat C; 2586cdc6f3adSToby Isaac PetscBool stride; 258717ab2063SBarry Smith 25883a40ed3dSBarry Smith PetscFunctionBegin; 258917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2590b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2591b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 259217ab2063SBarry Smith 2593251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2594ff718158SBarry Smith if (stride) { 2595ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2596ff718158SBarry Smith } else { 2597ff718158SBarry Smith first = 0; 2598ff718158SBarry Smith step = 0; 2599ff718158SBarry Smith } 2600fee21e36SBarry Smith if (stride && step == 1) { 260102834360SBarry Smith /* special case of contiguous rows */ 2602dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 260302834360SBarry Smith /* loop over new rows determining lens and starting points */ 260402834360SBarry Smith for (i=0; i<nrows; i++) { 2605bfeeae90SHong Zhang kstart = ai[irow[i]]; 2606a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2607a91a9bebSLisandro Dalcin starts[i] = kstart; 260802834360SBarry Smith for (k=kstart; k<kend; k++) { 2609bfeeae90SHong Zhang if (aj[k] >= first) { 261002834360SBarry Smith starts[i] = k; 261102834360SBarry Smith break; 261202834360SBarry Smith } 261302834360SBarry Smith } 2614a2744918SBarry Smith sum = 0; 261502834360SBarry Smith while (k < kend) { 2616bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2617a2744918SBarry Smith sum++; 261802834360SBarry Smith } 2619a2744918SBarry Smith lens[i] = sum; 262002834360SBarry Smith } 262102834360SBarry Smith /* create submatrix */ 2622cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 262397f1f81fSBarry Smith PetscInt n_cols,n_rows; 262408480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2625e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2626d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 262708480c60SBarry Smith C = *B; 26283a40ed3dSBarry Smith } else { 26293bef6203SJed Brown PetscInt rbs,cbs; 2630ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2631f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26323bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26333bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26343bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26357adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2636ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 263708480c60SBarry Smith } 2638db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2639db02288aSLois Curfman McInnes 264002834360SBarry Smith /* loop over rows inserting into submatrix */ 2641db02288aSLois Curfman McInnes a_new = c->a; 2642db02288aSLois Curfman McInnes j_new = c->j; 2643db02288aSLois Curfman McInnes i_new = c->i; 26442e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 264502834360SBarry Smith for (i=0; i<nrows; i++) { 2646a2744918SBarry Smith ii = starts[i]; 2647a2744918SBarry Smith lensi = lens[i]; 2648a2744918SBarry Smith for (k=0; k<lensi; k++) { 2649a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 265002834360SBarry Smith } 26512e5835c6SStefano Zampini ierr = PetscArraycpy(a_new,aa + starts[i],lensi);CHKERRQ(ierr); 2652a2744918SBarry Smith a_new += lensi; 2653a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2654a2744918SBarry Smith c->ilen[i] = lensi; 265502834360SBarry Smith } 26562e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 26570e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26583a40ed3dSBarry Smith } else { 265902834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 26601795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2661854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 26624dcab191SBarry Smith for (i=0; i<ncols; i++) { 2663d9ef940eSSatish Balay if (PetscUnlikelyDebug(icol[i] >= oldcols)) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D >= A->cmap->n %D",i,icol[i],oldcols); 26644dcab191SBarry Smith smap[icol[i]] = i+1; 26654dcab191SBarry Smith } 26664dcab191SBarry Smith 266702834360SBarry Smith /* determine lens of each row */ 266802834360SBarry Smith for (i=0; i<nrows; i++) { 2669bfeeae90SHong Zhang kstart = ai[irow[i]]; 267002834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 267102834360SBarry Smith lens[i] = 0; 267202834360SBarry Smith for (k=kstart; k<kend; k++) { 2673bfeeae90SHong Zhang if (smap[aj[k]]) { 267402834360SBarry Smith lens[i]++; 267502834360SBarry Smith } 267602834360SBarry Smith } 267702834360SBarry Smith } 267817ab2063SBarry Smith /* Create and fill new matrix */ 2679a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2680ace3abfcSBarry Smith PetscBool equal; 26810f5bd95cSBarry Smith 268299141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2683e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2684580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2685f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2686580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 268708480c60SBarry Smith C = *B; 26883a40ed3dSBarry Smith } else { 26893bef6203SJed Brown PetscInt rbs,cbs; 2690ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2691f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26923bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26933bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26943bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26957adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2696ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 269708480c60SBarry Smith } 26982e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 269999141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 270017ab2063SBarry Smith for (i=0; i<nrows; i++) { 270199141d43SSatish Balay row = irow[i]; 2702bfeeae90SHong Zhang kstart = ai[row]; 270399141d43SSatish Balay kend = kstart + a->ilen[row]; 2704bfeeae90SHong Zhang mat_i = c->i[i]; 270599141d43SSatish Balay mat_j = c->j + mat_i; 270699141d43SSatish Balay mat_a = c->a + mat_i; 270799141d43SSatish Balay mat_ilen = c->ilen + i; 270817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2709bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2710ed480e8bSBarry Smith *mat_j++ = tcol - 1; 27112e5835c6SStefano Zampini *mat_a++ = aa[k]; 271299141d43SSatish Balay (*mat_ilen)++; 271399141d43SSatish Balay 271417ab2063SBarry Smith } 271517ab2063SBarry Smith } 271617ab2063SBarry Smith } 27172e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 271802834360SBarry Smith /* Free work space */ 271902834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2720606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2721606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2722cdc6f3adSToby Isaac /* sort */ 2723cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2724cdc6f3adSToby Isaac PetscInt ilen; 2725cdc6f3adSToby Isaac 2726cdc6f3adSToby Isaac mat_i = c->i[i]; 2727cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2728cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2729cdc6f3adSToby Isaac ilen = c->ilen[i]; 2730390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2731cdc6f3adSToby Isaac } 273202834360SBarry Smith } 27338c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2734b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2735305c6ccfSStefano Zampini #endif 27366d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27376d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 273817ab2063SBarry Smith 273917ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2740416022c9SBarry Smith *B = C; 27413a40ed3dSBarry Smith PetscFunctionReturn(0); 274217ab2063SBarry Smith } 274317ab2063SBarry Smith 2744fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 274582d44351SHong Zhang { 274682d44351SHong Zhang PetscErrorCode ierr; 274782d44351SHong Zhang Mat B; 274882d44351SHong Zhang 274982d44351SHong Zhang PetscFunctionBegin; 2750c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 275182d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 275282d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 275333d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 275482d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 275582d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 275682d44351SHong Zhang *subMat = B; 2757c2d650bdSHong Zhang } else { 2758c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2759c2d650bdSHong Zhang } 276082d44351SHong Zhang PetscFunctionReturn(0); 276182d44351SHong Zhang } 276282d44351SHong Zhang 27639a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2764a871dcd8SBarry Smith { 276563b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2766dfbe8321SBarry Smith PetscErrorCode ierr; 276763b91edcSBarry Smith Mat outA; 2768ace3abfcSBarry Smith PetscBool row_identity,col_identity; 276963b91edcSBarry Smith 27703a40ed3dSBarry Smith PetscFunctionBegin; 2771e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 27721df811f5SHong Zhang 2773b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2774b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2775a871dcd8SBarry Smith 277663b91edcSBarry Smith outA = inA; 2777d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2778f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2779f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 27802205254eSKarl Rupp 2781c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 27826bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 27832205254eSKarl Rupp 2784c3122656SLisandro Dalcin a->row = row; 27852205254eSKarl Rupp 2786c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 27876bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 27882205254eSKarl Rupp 2789c3122656SLisandro Dalcin a->col = col; 279063b91edcSBarry Smith 279136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 27926bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 27934c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 27943bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2795f0ec6fceSSatish Balay 279694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2797854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 27983bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 279994a9d846SBarry Smith } 280063b91edcSBarry Smith 2801f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2802137fb511SHong Zhang if (row_identity && col_identity) { 2803ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2804137fb511SHong Zhang } else { 2805719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2806137fb511SHong Zhang } 28073a40ed3dSBarry Smith PetscFunctionReturn(0); 2808a871dcd8SBarry Smith } 2809a871dcd8SBarry Smith 2810f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2811f0b747eeSBarry Smith { 2812f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2813dfa0f9e5SStefano Zampini PetscScalar *v; 2814efee365bSSatish Balay PetscErrorCode ierr; 2815c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 28163a40ed3dSBarry Smith 28173a40ed3dSBarry Smith PetscFunctionBegin; 2818dfa0f9e5SStefano Zampini ierr = MatSeqAIJGetArray(inA,&v);CHKERRQ(ierr); 2819c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 2820dfa0f9e5SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one)); 2821efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2822dfa0f9e5SStefano Zampini ierr = MatSeqAIJRestoreArray(inA,&v);CHKERRQ(ierr); 2823acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 28243a40ed3dSBarry Smith PetscFunctionReturn(0); 2825f0b747eeSBarry Smith } 2826f0b747eeSBarry Smith 2827f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 282816b64355SHong Zhang { 282916b64355SHong Zhang PetscErrorCode ierr; 283016b64355SHong Zhang PetscInt i; 283116b64355SHong Zhang 283216b64355SHong Zhang PetscFunctionBegin; 283316b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 283416b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 283516b64355SHong Zhang 283616b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 283716b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 283816b64355SHong Zhang } 283916b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 284016b64355SHong Zhang 284116b64355SHong Zhang if (submatj->rbuf1) { 284216b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 284316b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 284416b64355SHong Zhang } 284516b64355SHong Zhang 284616b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 284716b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 284816b64355SHong Zhang } 284916b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 285016b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 285116b64355SHong Zhang } 285216b64355SHong Zhang 285316b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 285416b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 285516b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 285616b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 285716b64355SHong Zhang #else 285816b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 285916b64355SHong Zhang #endif 286016b64355SHong Zhang 286116b64355SHong Zhang if (!submatj->allcolumns) { 286216b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 286316b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 286416b64355SHong Zhang #else 286516b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 286616b64355SHong Zhang #endif 286716b64355SHong Zhang } 286816b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 286916b64355SHong Zhang 287016b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 287116b64355SHong Zhang PetscFunctionReturn(0); 287216b64355SHong Zhang } 287316b64355SHong Zhang 28740fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 287516b64355SHong Zhang { 287616b64355SHong Zhang PetscErrorCode ierr; 287716b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 28785c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 287916b64355SHong Zhang 288016b64355SHong Zhang PetscFunctionBegin; 288134136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2882f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 288316b64355SHong Zhang PetscFunctionReturn(0); 288416b64355SHong Zhang } 288516b64355SHong Zhang 28862d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 28872d033e1fSHong Zhang { 28882d033e1fSHong Zhang PetscErrorCode ierr; 28892d033e1fSHong Zhang PetscInt i; 28900fb991dcSHong Zhang Mat C; 28910fb991dcSHong Zhang Mat_SeqAIJ *c; 28920fb991dcSHong Zhang Mat_SubSppt *submatj; 28932d033e1fSHong Zhang 28942d033e1fSHong Zhang PetscFunctionBegin; 28952d033e1fSHong Zhang for (i=0; i<n; i++) { 28960fb991dcSHong Zhang C = (*mat)[i]; 28970fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 28980fb991dcSHong Zhang submatj = c->submatis1; 28992d033e1fSHong Zhang if (submatj) { 2900682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 290134136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2902f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 290334136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 29042d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 29052d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 29062d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2907682e4c99SStefano Zampini } 29082d033e1fSHong Zhang } else { 29092d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 29102d033e1fSHong Zhang } 29112d033e1fSHong Zhang } 291286e85357SHong Zhang 291363a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 291463a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 291563a75b2aSHong Zhang 29162d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 29172d033e1fSHong Zhang PetscFunctionReturn(0); 29182d033e1fSHong Zhang } 29192d033e1fSHong Zhang 29207dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2921cddf8d76SBarry Smith { 2922dfbe8321SBarry Smith PetscErrorCode ierr; 292397f1f81fSBarry Smith PetscInt i; 2924cddf8d76SBarry Smith 29253a40ed3dSBarry Smith PetscFunctionBegin; 2926cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2927df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2928cddf8d76SBarry Smith } 2929cddf8d76SBarry Smith 2930cddf8d76SBarry Smith for (i=0; i<n; i++) { 29317dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2932cddf8d76SBarry Smith } 29333a40ed3dSBarry Smith PetscFunctionReturn(0); 2934cddf8d76SBarry Smith } 2935cddf8d76SBarry Smith 293697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 29374dcbc457SBarry Smith { 2938e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29396849ba73SBarry Smith PetscErrorCode ierr; 29405d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 29415d0c19d7SBarry Smith const PetscInt *idx; 294297f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2943f1af5d2fSBarry Smith PetscBT table; 2944bbd702dbSSatish Balay 29453a40ed3dSBarry Smith PetscFunctionBegin; 2946d0f46423SBarry Smith m = A->rmap->n; 2947e4d965acSSatish Balay ai = a->i; 2948bfeeae90SHong Zhang aj = a->j; 29498a047759SSatish Balay 2950e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 295106763907SSatish Balay 2952854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 295353b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 295406763907SSatish Balay 2955e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2956b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2957e4d965acSSatish Balay isz = 0; 29586831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2959e4d965acSSatish Balay 2960e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29614dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2962b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2963e4d965acSSatish Balay 2964dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2965e4d965acSSatish Balay for (j=0; j<n; ++j) { 29662205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 29674dcbc457SBarry Smith } 296806763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 29696bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2970e4d965acSSatish Balay 297104a348a9SBarry Smith k = 0; 297204a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 297304a348a9SBarry Smith n = isz; 297406763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2975e4d965acSSatish Balay row = nidx[k]; 2976e4d965acSSatish Balay start = ai[row]; 2977e4d965acSSatish Balay end = ai[row+1]; 297804a348a9SBarry Smith for (l = start; l<end; l++) { 2979efb16452SHong Zhang val = aj[l]; 29802205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2981e4d965acSSatish Balay } 2982e4d965acSSatish Balay } 2983e4d965acSSatish Balay } 298470b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2985e4d965acSSatish Balay } 298694bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2987606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 29883a40ed3dSBarry Smith PetscFunctionReturn(0); 29894dcbc457SBarry Smith } 299017ab2063SBarry Smith 29910513a670SBarry Smith /* -------------------------------------------------------------- */ 2992dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 29930513a670SBarry Smith { 29940513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29956849ba73SBarry Smith PetscErrorCode ierr; 29963b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 29975d0c19d7SBarry Smith const PetscInt *row,*col; 29985d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 299956cd22aeSBarry Smith IS icolp,irowp; 30000298fd71SBarry Smith PetscInt *cwork = NULL; 30010298fd71SBarry Smith PetscScalar *vwork = NULL; 30020513a670SBarry Smith 30033a40ed3dSBarry Smith PetscFunctionBegin; 30044c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 300556cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 30064c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 300756cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 30080513a670SBarry Smith 30090513a670SBarry Smith /* determine lengths of permuted rows */ 3010854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 30112205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 3012ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 3013f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 301433d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 30157adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 3016ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 3017606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 30180513a670SBarry Smith 3019785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 30200513a670SBarry Smith for (i=0; i<m; i++) { 302132ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30222205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 3023cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 302432ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30250513a670SBarry Smith } 3026606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 30272205254eSKarl Rupp 30283c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 30292205254eSKarl Rupp 30308c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3031b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 30329fe5e383SStefano Zampini #endif 30330513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30340513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 303556cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 303656cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 30376bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 30386bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 30396768869dSprj- if (rowp == colp) { 3040dc29a518SPierre Jolivet ierr = MatPropagateSymmetryOptions(A,*B);CHKERRQ(ierr); 30416768869dSprj- } 30423a40ed3dSBarry Smith PetscFunctionReturn(0); 30430513a670SBarry Smith } 30440513a670SBarry Smith 3045dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3046cb5b572fSBarry Smith { 3047dfbe8321SBarry Smith PetscErrorCode ierr; 3048cb5b572fSBarry Smith 3049cb5b572fSBarry Smith PetscFunctionBegin; 305033f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 305133f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3052be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3053be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 30542e5835c6SStefano Zampini const PetscScalar *aa; 3055be6bf707SBarry Smith 30562e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 30574d805d7cSStefano Zampini if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different %D != %D",a->i[A->rmap->n],b->i[B->rmap->n]); 30582e5835c6SStefano Zampini ierr = PetscArraycpy(b->a,aa,a->i[A->rmap->n]);CHKERRQ(ierr); 3059cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 30602e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 3061cb5b572fSBarry Smith } else { 3062cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3063cb5b572fSBarry Smith } 3064cb5b572fSBarry Smith PetscFunctionReturn(0); 3065cb5b572fSBarry Smith } 3066cb5b572fSBarry Smith 30674994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3068273d9f13SBarry Smith { 3069dfbe8321SBarry Smith PetscErrorCode ierr; 3070273d9f13SBarry Smith 3071273d9f13SBarry Smith PetscFunctionBegin; 3072f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3073273d9f13SBarry Smith PetscFunctionReturn(0); 3074273d9f13SBarry Smith } 3075273d9f13SBarry Smith 3076f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 30776c0721eeSBarry Smith { 30786c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30796e111a19SKarl Rupp 30806c0721eeSBarry Smith PetscFunctionBegin; 30816c0721eeSBarry Smith *array = a->a; 30826c0721eeSBarry Smith PetscFunctionReturn(0); 30836c0721eeSBarry Smith } 30846c0721eeSBarry Smith 3085f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 30866c0721eeSBarry Smith { 30876c0721eeSBarry Smith PetscFunctionBegin; 3088f38c1e66SStefano Zampini *array = NULL; 30896c0721eeSBarry Smith PetscFunctionReturn(0); 30906c0721eeSBarry Smith } 3091273d9f13SBarry Smith 30928229c054SShri Abhyankar /* 30938229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 30948229c054SShri Abhyankar have different nonzero structure. 30958229c054SShri Abhyankar */ 3096b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3097ec7775f6SShri Abhyankar { 3098b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3099ec7775f6SShri Abhyankar 3100ec7775f6SShri Abhyankar PetscFunctionBegin; 3101ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3102ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3103b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3104b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3105b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 31068af7cee1SJed Brown nnz[i] = 0; 31078af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3108b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3109b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 31108af7cee1SJed Brown nnz[i]++; 31118af7cee1SJed Brown } 31128af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3113ec7775f6SShri Abhyankar } 3114ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3115ec7775f6SShri Abhyankar } 3116ec7775f6SShri Abhyankar 3117b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3118b264fe52SHong Zhang { 3119b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3120b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3121b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3122b264fe52SHong Zhang PetscErrorCode ierr; 3123b264fe52SHong Zhang 3124b264fe52SHong Zhang PetscFunctionBegin; 3125b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3126b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3127b264fe52SHong Zhang PetscFunctionReturn(0); 3128b264fe52SHong Zhang } 3129b264fe52SHong Zhang 3130f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3131ac90fabeSBarry Smith { 3132dfbe8321SBarry Smith PetscErrorCode ierr; 3133ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3134ac90fabeSBarry Smith 3135ac90fabeSBarry Smith PetscFunctionBegin; 313641f5e1b1SStefano Zampini if (str == UNKNOWN_NONZERO_PATTERN && x->nz == y->nz) { 313781fa06acSBarry Smith PetscBool e; 313881fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 313981fa06acSBarry Smith if (e) { 314081fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 314181fa06acSBarry Smith if (e) { 314281fa06acSBarry Smith str = SAME_NONZERO_PATTERN; 314381fa06acSBarry Smith } 314481fa06acSBarry Smith } 314581fa06acSBarry Smith } 3146ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 31472e5835c6SStefano Zampini const PetscScalar *xa; 31482e5835c6SStefano Zampini PetscScalar *ya,alpha = a; 314981fa06acSBarry Smith PetscBLASInt one = 1,bnz; 315081fa06acSBarry Smith 315181fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31522e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&ya);CHKERRQ(ierr); 31532e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(X,&xa);CHKERRQ(ierr); 31542e5835c6SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one)); 31552e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(X,&xa);CHKERRQ(ierr); 31562e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&ya);CHKERRQ(ierr); 315741f5e1b1SStefano Zampini ierr = PetscLogFlops(2.0*bnz);CHKERRQ(ierr); 3158acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3159a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 3160ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3161ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3162ac90fabeSBarry Smith } else { 31638229c054SShri Abhyankar Mat B; 31648229c054SShri Abhyankar PetscInt *nnz; 3165785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3166ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3167bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 316881fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 31692e5835c6SStefano Zampini ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 31708229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3171ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3172ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 317328be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 31748229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3175ac90fabeSBarry Smith } 3176ac90fabeSBarry Smith PetscFunctionReturn(0); 3177ac90fabeSBarry Smith } 3178ac90fabeSBarry Smith 31792726fb6dSPierre Jolivet PETSC_INTERN PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3180354c94deSBarry Smith { 3181354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3182354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3183354c94deSBarry Smith PetscInt i,nz; 3184354c94deSBarry Smith PetscScalar *a; 3185ce496241SStefano Zampini PetscErrorCode ierr; 3186354c94deSBarry Smith 3187354c94deSBarry Smith PetscFunctionBegin; 3188354c94deSBarry Smith nz = aij->nz; 3189ce496241SStefano Zampini ierr = MatSeqAIJGetArray(mat,&a);CHKERRQ(ierr); 31902205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3191ce496241SStefano Zampini ierr = MatSeqAIJRestoreArray(mat,&a);CHKERRQ(ierr); 3192354c94deSBarry Smith #else 3193354c94deSBarry Smith PetscFunctionBegin; 3194354c94deSBarry Smith #endif 3195354c94deSBarry Smith PetscFunctionReturn(0); 3196354c94deSBarry Smith } 3197354c94deSBarry Smith 3198985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3199e34fafa9SBarry Smith { 3200e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3201e34fafa9SBarry Smith PetscErrorCode ierr; 3202d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3203e34fafa9SBarry Smith PetscReal atmp; 3204985db425SBarry Smith PetscScalar *x; 3205ce496241SStefano Zampini const MatScalar *aa,*av; 3206e34fafa9SBarry Smith 3207e34fafa9SBarry Smith PetscFunctionBegin; 3208e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3209ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3210ce496241SStefano Zampini aa = av; 3211e34fafa9SBarry Smith ai = a->i; 3212e34fafa9SBarry Smith aj = a->j; 3213e34fafa9SBarry Smith 3214985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3215475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3216e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3217e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3218e34fafa9SBarry Smith for (i=0; i<m; i++) { 3219e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3220e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3221985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3222985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3223985db425SBarry Smith aa++; aj++; 3224985db425SBarry Smith } 3225985db425SBarry Smith } 3226475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3227ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3228985db425SBarry Smith PetscFunctionReturn(0); 3229985db425SBarry Smith } 3230985db425SBarry Smith 3231985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3232985db425SBarry Smith { 3233985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3234985db425SBarry Smith PetscErrorCode ierr; 3235d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3236985db425SBarry Smith PetscScalar *x; 3237ce496241SStefano Zampini const MatScalar *aa,*av; 3238985db425SBarry Smith 3239985db425SBarry Smith PetscFunctionBegin; 3240e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3241ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3242ce496241SStefano Zampini aa = av; 3243985db425SBarry Smith ai = a->i; 3244985db425SBarry Smith aj = a->j; 3245985db425SBarry Smith 3246985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3247fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3248985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3249e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3250985db425SBarry Smith for (i=0; i<m; i++) { 3251985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3252d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3253985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3254985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3255985db425SBarry Smith x[i] = 0.0; 3256985db425SBarry Smith if (idx) { 3257985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3258985db425SBarry Smith if (aj[j] > j) { 3259985db425SBarry Smith idx[i] = j; 3260985db425SBarry Smith break; 3261985db425SBarry Smith } 3262985db425SBarry Smith } 32631a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 32641a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3265985db425SBarry Smith } 3266985db425SBarry Smith } 3267985db425SBarry Smith for (j=0; j<ncols; j++) { 3268985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3269985db425SBarry Smith aa++; aj++; 3270985db425SBarry Smith } 3271985db425SBarry Smith } 3272fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3273ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3274985db425SBarry Smith PetscFunctionReturn(0); 3275985db425SBarry Smith } 3276985db425SBarry Smith 3277c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3278c87e5d42SMatthew Knepley { 3279c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3280c87e5d42SMatthew Knepley PetscErrorCode ierr; 3281c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3282ce496241SStefano Zampini PetscScalar *x; 3283ce496241SStefano Zampini const MatScalar *aa,*av; 3284c87e5d42SMatthew Knepley 3285c87e5d42SMatthew Knepley PetscFunctionBegin; 3286ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3287ce496241SStefano Zampini aa = av; 3288c87e5d42SMatthew Knepley ai = a->i; 3289c87e5d42SMatthew Knepley aj = a->j; 3290c87e5d42SMatthew Knepley 3291c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3292f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3293c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3294f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3295c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3296c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3297f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3298f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3299f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3300f07e67edSHong Zhang x[i] = 0.0; 3301f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3302289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3303f07e67edSHong Zhang if (aj[j] > j) { 3304f07e67edSHong Zhang idx[i] = j; 33052205254eSKarl Rupp break; 33062205254eSKarl Rupp } 3307289a08f5SMatthew Knepley } 3308f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3309f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3310f07e67edSHong Zhang } 3311289a08f5SMatthew Knepley } 3312c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3313f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3314c87e5d42SMatthew Knepley aa++; aj++; 3315c87e5d42SMatthew Knepley } 3316c87e5d42SMatthew Knepley } 3317f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3318ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3319c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3320c87e5d42SMatthew Knepley } 3321c87e5d42SMatthew Knepley 3322985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3323985db425SBarry Smith { 3324985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3325985db425SBarry Smith PetscErrorCode ierr; 3326d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3327d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3328985db425SBarry Smith PetscScalar *x; 3329ce496241SStefano Zampini const MatScalar *aa,*av; 3330985db425SBarry Smith 3331985db425SBarry Smith PetscFunctionBegin; 3332e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3333ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3334ce496241SStefano Zampini aa = av; 3335985db425SBarry Smith ai = a->i; 3336985db425SBarry Smith aj = a->j; 3337985db425SBarry Smith 3338985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3339fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3340985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3341f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3342985db425SBarry Smith for (i=0; i<m; i++) { 3343985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3344d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3345985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3346985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3347985db425SBarry Smith x[i] = 0.0; 3348985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3349985db425SBarry Smith for (j=0; j<ncols; j++) { 3350985db425SBarry Smith if (aj[j] > j) { 3351985db425SBarry Smith idx[i] = j; 3352985db425SBarry Smith break; 3353985db425SBarry Smith } 3354985db425SBarry Smith } 3355fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3356fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3357985db425SBarry Smith } 3358985db425SBarry Smith } 3359985db425SBarry Smith for (j=0; j<ncols; j++) { 3360985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3361985db425SBarry Smith aa++; aj++; 3362e34fafa9SBarry Smith } 3363e34fafa9SBarry Smith } 3364fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3365ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3366e34fafa9SBarry Smith PetscFunctionReturn(0); 3367e34fafa9SBarry Smith } 3368bbead8a2SBarry Smith 3369713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3370bbead8a2SBarry Smith { 3371bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3372bbead8a2SBarry Smith PetscErrorCode ierr; 337333d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3374bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 33750da83c2eSBarry Smith const PetscReal shift = 0.0; 33761a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3377bbead8a2SBarry Smith 3378bbead8a2SBarry Smith PetscFunctionBegin; 3379a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 33804a0d0026SBarry Smith if (a->ibdiagvalid) { 33814a0d0026SBarry Smith if (values) *values = a->ibdiag; 33824a0d0026SBarry Smith PetscFunctionReturn(0); 33834a0d0026SBarry Smith } 3384bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3385bbead8a2SBarry Smith if (!a->ibdiag) { 3386785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 33873bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3388bbead8a2SBarry Smith } 3389bbead8a2SBarry Smith diag = a->ibdiag; 3390bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3391bbead8a2SBarry Smith /* factor and invert each block */ 3392bbead8a2SBarry Smith switch (bs) { 3393bbead8a2SBarry Smith case 1: 3394bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3395bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3396ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3397ec1892c8SHong Zhang if (allowzeropivot) { 33987b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33997b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 34007b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 34017b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 34027b6c816cSBarry Smith } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot, row %D pivot %g tolerance %g",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON); 3403ec1892c8SHong Zhang } 3404bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3405bbead8a2SBarry Smith } 3406bbead8a2SBarry Smith break; 3407bbead8a2SBarry Smith case 2: 3408bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3409bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3410bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3411a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34127b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 341396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3414bbead8a2SBarry Smith diag += 4; 3415bbead8a2SBarry Smith } 3416bbead8a2SBarry Smith break; 3417bbead8a2SBarry Smith case 3: 3418bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3419bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3420bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3421a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34227b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 342396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3424bbead8a2SBarry Smith diag += 9; 3425bbead8a2SBarry Smith } 3426bbead8a2SBarry Smith break; 3427bbead8a2SBarry Smith case 4: 3428bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3429bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3430bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3431a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34327b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 343396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3434bbead8a2SBarry Smith diag += 16; 3435bbead8a2SBarry Smith } 3436bbead8a2SBarry Smith break; 3437bbead8a2SBarry Smith case 5: 3438bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3439bbead8a2SBarry 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; 3440bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3441a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34427b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 344396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3444bbead8a2SBarry Smith diag += 25; 3445bbead8a2SBarry Smith } 3446bbead8a2SBarry Smith break; 3447bbead8a2SBarry Smith case 6: 3448bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3449bbead8a2SBarry 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; 3450bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3451a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34527b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 345396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3454bbead8a2SBarry Smith diag += 36; 3455bbead8a2SBarry Smith } 3456bbead8a2SBarry Smith break; 3457bbead8a2SBarry Smith case 7: 3458bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3459bbead8a2SBarry 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; 3460bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3461a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34627b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 346396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3464bbead8a2SBarry Smith diag += 49; 3465bbead8a2SBarry Smith } 3466bbead8a2SBarry Smith break; 3467bbead8a2SBarry Smith default: 3468dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3469bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3470bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3471bbead8a2SBarry Smith IJ[j] = bs*i + j; 3472bbead8a2SBarry Smith } 3473bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 34745f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34757b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 347696b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3477bbead8a2SBarry Smith diag += bs2; 3478bbead8a2SBarry Smith } 3479bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3480bbead8a2SBarry Smith } 3481bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3482bbead8a2SBarry Smith PetscFunctionReturn(0); 3483bbead8a2SBarry Smith } 3484bbead8a2SBarry Smith 348573a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 348673a71a0fSBarry Smith { 348773a71a0fSBarry Smith PetscErrorCode ierr; 348873a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3489*fff043a9SJunchao Zhang PetscScalar a,*aa; 349073a71a0fSBarry Smith PetscInt m,n,i,j,col; 349173a71a0fSBarry Smith 349273a71a0fSBarry Smith PetscFunctionBegin; 349373a71a0fSBarry Smith if (!x->assembled) { 349473a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 349573a71a0fSBarry Smith for (i=0; i<m; i++) { 349673a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 349773a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 349873a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 349973a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 350073a71a0fSBarry Smith } 350173a71a0fSBarry Smith } 3502e2ce353bSJunchao Zhang } else { 3503*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayWrite(x,&aa);CHKERRQ(ierr); 3504*fff043a9SJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aa+i);CHKERRQ(ierr);} 3505*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayWrite(x,&aa);CHKERRQ(ierr); 3506e2ce353bSJunchao Zhang } 350773a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 350873a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 350973a71a0fSBarry Smith PetscFunctionReturn(0); 351073a71a0fSBarry Smith } 351173a71a0fSBarry Smith 3512679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3513679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3514679944adSJunchao Zhang { 3515679944adSJunchao Zhang PetscErrorCode ierr; 3516679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3517679944adSJunchao Zhang PetscScalar a; 3518679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3519679944adSJunchao Zhang 3520679944adSJunchao Zhang PetscFunctionBegin; 3521679944adSJunchao Zhang nskip = high - low; 3522679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3523679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3524679944adSJunchao Zhang for (i=0; i<m; i++) { 3525679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3526679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3527679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3528679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3529679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3530679944adSJunchao Zhang } 3531e2ce353bSJunchao Zhang } 3532679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3533679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3534679944adSJunchao Zhang PetscFunctionReturn(0); 3535679944adSJunchao Zhang } 3536679944adSJunchao Zhang 3537682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 35380a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3539cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3540cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3541cb5b572fSBarry Smith MatMult_SeqAIJ, 354297304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 35437c922b88SBarry Smith MatMultTranspose_SeqAIJ, 35447c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3545f4259b30SLisandro Dalcin NULL, 3546f4259b30SLisandro Dalcin NULL, 3547f4259b30SLisandro Dalcin NULL, 3548f4259b30SLisandro Dalcin /* 10*/ NULL, 3549cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3550f4259b30SLisandro Dalcin NULL, 355141f059aeSBarry Smith MatSOR_SeqAIJ, 355291e9d3e2SHong Zhang MatTranspose_SeqAIJ, 355397304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3554cb5b572fSBarry Smith MatEqual_SeqAIJ, 3555cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3556cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3557cb5b572fSBarry Smith MatNorm_SeqAIJ, 3558f4259b30SLisandro Dalcin /* 20*/ NULL, 3559cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3560cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3561cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3562d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3563f4259b30SLisandro Dalcin NULL, 3564f4259b30SLisandro Dalcin NULL, 3565f4259b30SLisandro Dalcin NULL, 3566f4259b30SLisandro Dalcin NULL, 35674994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3568f4259b30SLisandro Dalcin NULL, 3569f4259b30SLisandro Dalcin NULL, 3570f4259b30SLisandro Dalcin NULL, 3571f4259b30SLisandro Dalcin NULL, 3572d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3573f4259b30SLisandro Dalcin NULL, 3574f4259b30SLisandro Dalcin NULL, 3575cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3576f4259b30SLisandro Dalcin NULL, 3577d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 35787dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3579cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3580cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3581cb5b572fSBarry Smith MatCopy_SeqAIJ, 3582d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3583cb5b572fSBarry Smith MatScale_SeqAIJ, 35847d68702bSBarry Smith MatShift_SeqAIJ, 358579299369SBarry Smith MatDiagonalSet_SeqAIJ, 35866e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 358773a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 35883b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 35893b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 35903b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3591a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 359293dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3593f4259b30SLisandro Dalcin NULL, 3594f4259b30SLisandro Dalcin NULL, 3595cda55fadSBarry Smith MatPermute_SeqAIJ, 3596f4259b30SLisandro Dalcin NULL, 3597f4259b30SLisandro Dalcin /* 59*/ NULL, 3598b9b97703SBarry Smith MatDestroy_SeqAIJ, 3599b9b97703SBarry Smith MatView_SeqAIJ, 3600f4259b30SLisandro Dalcin NULL, 3601f4259b30SLisandro Dalcin NULL, 3602f4259b30SLisandro Dalcin /* 64*/ NULL, 3603321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3604f4259b30SLisandro Dalcin NULL, 3605f4259b30SLisandro Dalcin NULL, 3606f4259b30SLisandro Dalcin NULL, 3607d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3608c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3609f4259b30SLisandro Dalcin NULL, 3610f4259b30SLisandro Dalcin NULL, 3611f4259b30SLisandro Dalcin NULL, 3612f4259b30SLisandro Dalcin /* 74*/ NULL, 36133acb8795SBarry Smith MatFDColoringApply_AIJ, 3614f4259b30SLisandro Dalcin NULL, 3615f4259b30SLisandro Dalcin NULL, 3616f4259b30SLisandro Dalcin NULL, 36176ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3618f4259b30SLisandro Dalcin NULL, 3619f4259b30SLisandro Dalcin NULL, 3620f4259b30SLisandro Dalcin NULL, 3621bc011b1eSHong Zhang MatLoad_SeqAIJ, 3622d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 36231cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3624f4259b30SLisandro Dalcin NULL, 3625f4259b30SLisandro Dalcin NULL, 3626f4259b30SLisandro Dalcin NULL, 3627f4259b30SLisandro Dalcin /* 89*/ NULL, 3628f4259b30SLisandro Dalcin NULL, 362926be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3630f4259b30SLisandro Dalcin NULL, 3631f4259b30SLisandro Dalcin NULL, 36328fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3633f4259b30SLisandro Dalcin NULL, 3634f4259b30SLisandro Dalcin NULL, 36356fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3636f4259b30SLisandro Dalcin NULL, 36374222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3638f4259b30SLisandro Dalcin NULL, 3639f4259b30SLisandro Dalcin NULL, 364087d4246cSBarry Smith MatConjugate_SeqAIJ, 3641f4259b30SLisandro Dalcin NULL, 3642d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 364399cafbc1SBarry Smith MatRealPart_SeqAIJ, 3644f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3645f4259b30SLisandro Dalcin NULL, 3646f4259b30SLisandro Dalcin NULL, 3647cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3648f4259b30SLisandro Dalcin NULL, 36492af78befSBarry Smith MatGetRowMin_SeqAIJ, 3650f4259b30SLisandro Dalcin NULL, 3651599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3652f4259b30SLisandro Dalcin /*114*/ NULL, 3653f4259b30SLisandro Dalcin NULL, 3654f4259b30SLisandro Dalcin NULL, 3655f4259b30SLisandro Dalcin NULL, 3656f4259b30SLisandro Dalcin NULL, 3657f4259b30SLisandro Dalcin /*119*/ NULL, 3658f4259b30SLisandro Dalcin NULL, 3659f4259b30SLisandro Dalcin NULL, 3660f4259b30SLisandro Dalcin NULL, 3661b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 36620716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3663a873a8cdSSam Reynolds MatGetColumnReductions_SeqAIJ, 366437868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 36650da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3666f4259b30SLisandro Dalcin NULL, 3667f4259b30SLisandro Dalcin /*129*/ NULL, 3668f4259b30SLisandro Dalcin NULL, 3669f4259b30SLisandro Dalcin NULL, 367075648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3671b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3672b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 36732b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3674f4259b30SLisandro Dalcin NULL, 3675f4259b30SLisandro Dalcin NULL, 36763964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3677f4259b30SLisandro Dalcin /*139*/NULL, 3678f4259b30SLisandro Dalcin NULL, 3679f4259b30SLisandro Dalcin NULL, 36803a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 36819c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 36824222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 36834222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3684f4259b30SLisandro Dalcin NULL, 3685f4259b30SLisandro Dalcin NULL 36869e29f15eSvictorle }; 368717ab2063SBarry Smith 36887087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3689bef8e0ddSBarry Smith { 3690bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 369197f1f81fSBarry Smith PetscInt i,nz,n; 3692bef8e0ddSBarry Smith 3693bef8e0ddSBarry Smith PetscFunctionBegin; 3694bef8e0ddSBarry Smith nz = aij->maxnz; 3695d0f46423SBarry Smith n = mat->rmap->n; 3696bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3697bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3698bef8e0ddSBarry Smith } 3699bef8e0ddSBarry Smith aij->nz = nz; 3700bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3701bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3702bef8e0ddSBarry Smith } 3703bef8e0ddSBarry Smith PetscFunctionReturn(0); 3704bef8e0ddSBarry Smith } 3705bef8e0ddSBarry Smith 3706a3bb6f32SFande Kong /* 3707ddea5d60SJunchao Zhang * Given a sparse matrix with global column indices, compact it by using a local column space. 3708ddea5d60SJunchao Zhang * The result matrix helps saving memory in other algorithms, such as MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3709ddea5d60SJunchao Zhang */ 3710a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3711a3bb6f32SFande Kong { 3712a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3713a3bb6f32SFande Kong PetscTable gid1_lid1; 3714a3bb6f32SFande Kong PetscTablePosition tpos; 371525b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 371625b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3717a3bb6f32SFande Kong PetscErrorCode ierr; 3718a3bb6f32SFande Kong 3719a3bb6f32SFande Kong PetscFunctionBegin; 3720a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3721a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3722a3bb6f32SFande Kong /* use a table */ 3723a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3724a3bb6f32SFande Kong ec = 0; 372525b670f0SStefano Zampini for (i=0; i<nz; i++) { 372625b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 3727a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3728a3bb6f32SFande Kong if (!data) { 3729a3bb6f32SFande Kong /* one based table */ 3730a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3731a3bb6f32SFande Kong } 3732a3bb6f32SFande Kong } 3733a3bb6f32SFande Kong /* form array of columns we need */ 3734b3c64f9dSJunchao Zhang ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr); 3735a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3736a3bb6f32SFande Kong while (tpos) { 3737a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3738a3bb6f32SFande Kong gid--; 3739a3bb6f32SFande Kong lid--; 3740a3bb6f32SFande Kong garray[lid] = gid; 3741a3bb6f32SFande Kong } 3742a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3743a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3744a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3745a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3746a3bb6f32SFande Kong } 3747a3bb6f32SFande Kong /* compact out the extra columns in B */ 374825b670f0SStefano Zampini for (i=0; i<nz; i++) { 374925b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 3750a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3751a3bb6f32SFande Kong lid--; 375225b670f0SStefano Zampini jj[i] = lid; 3753a3bb6f32SFande Kong } 3754ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3755a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 375625b670f0SStefano Zampini ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3757a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3758a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3759a3bb6f32SFande Kong PetscFunctionReturn(0); 3760a3bb6f32SFande Kong } 3761a3bb6f32SFande Kong 3762bef8e0ddSBarry Smith /*@ 3763bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3764bef8e0ddSBarry Smith in the matrix. 3765bef8e0ddSBarry Smith 3766bef8e0ddSBarry Smith Input Parameters: 3767bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3768bef8e0ddSBarry Smith - indices - the column indices 3769bef8e0ddSBarry Smith 377015091d37SBarry Smith Level: advanced 377115091d37SBarry Smith 3772bef8e0ddSBarry Smith Notes: 3773bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3774bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3775bef8e0ddSBarry Smith of the MatSetValues() operation. 3776bef8e0ddSBarry Smith 3777bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3778d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3779bef8e0ddSBarry Smith 3780bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3781bef8e0ddSBarry Smith 3782b9617806SBarry Smith The indices should start with zero, not one. 3783b9617806SBarry Smith 3784bef8e0ddSBarry Smith @*/ 37857087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3786bef8e0ddSBarry Smith { 37874ac538c5SBarry Smith PetscErrorCode ierr; 3788bef8e0ddSBarry Smith 3789bef8e0ddSBarry Smith PetscFunctionBegin; 37900700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 37914482741eSBarry Smith PetscValidPointer(indices,2); 37924ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3793bef8e0ddSBarry Smith PetscFunctionReturn(0); 3794bef8e0ddSBarry Smith } 3795bef8e0ddSBarry Smith 3796be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3797be6bf707SBarry Smith 37987087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3799be6bf707SBarry Smith { 3800be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38016849ba73SBarry Smith PetscErrorCode ierr; 3802d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3803be6bf707SBarry Smith 3804be6bf707SBarry Smith PetscFunctionBegin; 3805169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3806be6bf707SBarry Smith 3807be6bf707SBarry Smith /* allocate space for values if not already there */ 3808be6bf707SBarry Smith if (!aij->saved_values) { 3809854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 38103bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3811be6bf707SBarry Smith } 3812be6bf707SBarry Smith 3813be6bf707SBarry Smith /* copy values over */ 3814580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3815be6bf707SBarry Smith PetscFunctionReturn(0); 3816be6bf707SBarry Smith } 3817be6bf707SBarry Smith 3818be6bf707SBarry Smith /*@ 3819be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3820be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3821be6bf707SBarry Smith nonlinear portion. 3822be6bf707SBarry Smith 3823be6bf707SBarry Smith Collect on Mat 3824be6bf707SBarry Smith 3825be6bf707SBarry Smith Input Parameters: 38260e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3827be6bf707SBarry Smith 382815091d37SBarry Smith Level: advanced 382915091d37SBarry Smith 3830be6bf707SBarry Smith Common Usage, with SNESSolve(): 3831be6bf707SBarry Smith $ Create Jacobian matrix 3832be6bf707SBarry Smith $ Set linear terms into matrix 3833be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3834be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3835be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3836512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3837be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3838be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3839be6bf707SBarry Smith $ In your Jacobian routine 3840be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3841be6bf707SBarry Smith $ Set nonlinear terms in matrix 3842be6bf707SBarry Smith 3843be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3844be6bf707SBarry Smith $ // build linear portion of Jacobian 3845512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3846be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3847be6bf707SBarry Smith $ loop over nonlinear iterations 3848be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3849be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3850be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3851be6bf707SBarry Smith $ Solve linear system with Jacobian 3852be6bf707SBarry Smith $ endloop 3853be6bf707SBarry Smith 3854be6bf707SBarry Smith Notes: 3855be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3856512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3857be6bf707SBarry Smith calling this routine. 3858be6bf707SBarry Smith 38590c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 38600c468ba9SBarry Smith and does not allocated additional space. 38610c468ba9SBarry Smith 3862be6bf707SBarry Smith .seealso: MatRetrieveValues() 3863be6bf707SBarry Smith 3864be6bf707SBarry Smith @*/ 38657087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3866be6bf707SBarry Smith { 38674ac538c5SBarry Smith PetscErrorCode ierr; 3868be6bf707SBarry Smith 3869be6bf707SBarry Smith PetscFunctionBegin; 38700700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3871e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3872e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38734ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3874be6bf707SBarry Smith PetscFunctionReturn(0); 3875be6bf707SBarry Smith } 3876be6bf707SBarry Smith 38777087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3878be6bf707SBarry Smith { 3879be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38806849ba73SBarry Smith PetscErrorCode ierr; 3881d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3882be6bf707SBarry Smith 3883be6bf707SBarry Smith PetscFunctionBegin; 3884169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3885f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3886be6bf707SBarry Smith /* copy values over */ 3887580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3888be6bf707SBarry Smith PetscFunctionReturn(0); 3889be6bf707SBarry Smith } 3890be6bf707SBarry Smith 3891be6bf707SBarry Smith /*@ 3892be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3893be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3894be6bf707SBarry Smith nonlinear portion. 3895be6bf707SBarry Smith 3896be6bf707SBarry Smith Collect on Mat 3897be6bf707SBarry Smith 3898be6bf707SBarry Smith Input Parameters: 3899386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3900be6bf707SBarry Smith 390115091d37SBarry Smith Level: advanced 390215091d37SBarry Smith 3903be6bf707SBarry Smith .seealso: MatStoreValues() 3904be6bf707SBarry Smith 3905be6bf707SBarry Smith @*/ 39067087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3907be6bf707SBarry Smith { 39084ac538c5SBarry Smith PetscErrorCode ierr; 3909be6bf707SBarry Smith 3910be6bf707SBarry Smith PetscFunctionBegin; 39110700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3912e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3913e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39144ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3915be6bf707SBarry Smith PetscFunctionReturn(0); 3916be6bf707SBarry Smith } 3917be6bf707SBarry Smith 3918be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 391917ab2063SBarry Smith /*@C 3920682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 39210d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 39226e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 392351c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 39242bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 392517ab2063SBarry Smith 3926d083f849SBarry Smith Collective 3927db81eaa0SLois Curfman McInnes 392817ab2063SBarry Smith Input Parameters: 3929db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 393017ab2063SBarry Smith . m - number of rows 393117ab2063SBarry Smith . n - number of columns 393217ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 393351c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39340298fd71SBarry Smith (possibly different for each row) or NULL 393517ab2063SBarry Smith 393617ab2063SBarry Smith Output Parameter: 3937416022c9SBarry Smith . A - the matrix 393817ab2063SBarry Smith 3939175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3940f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3941175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3942175b88e8SBarry Smith 3943b259b22eSLois Curfman McInnes Notes: 394449a6f317SBarry Smith If nnz is given then nz is ignored 394549a6f317SBarry Smith 394617ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 394717ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39480002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 394944cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 395017ab2063SBarry Smith 395117ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39520298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39533d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39546da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 395517ab2063SBarry Smith 3956682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 39574fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3958682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 39596c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 39606c7ebb05SLois Curfman McInnes 39616c7ebb05SLois Curfman McInnes Options Database Keys: 3962698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 39639db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 396417ab2063SBarry Smith 3965027ccd11SLois Curfman McInnes Level: intermediate 3966027ccd11SLois Curfman McInnes 396769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 396836db0b34SBarry Smith 396917ab2063SBarry Smith @*/ 39707087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 397117ab2063SBarry Smith { 3972dfbe8321SBarry Smith PetscErrorCode ierr; 39736945ee14SBarry Smith 39743a40ed3dSBarry Smith PetscFunctionBegin; 3975f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3976117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3977c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3978d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3979273d9f13SBarry Smith PetscFunctionReturn(0); 3980273d9f13SBarry Smith } 3981273d9f13SBarry Smith 3982273d9f13SBarry Smith /*@C 3983273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3984273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3985273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3986273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3987273d9f13SBarry Smith 3988d083f849SBarry Smith Collective 3989273d9f13SBarry Smith 3990273d9f13SBarry Smith Input Parameters: 39911c4f3114SJed Brown + B - The matrix 3992273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3993273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39940298fd71SBarry Smith (possibly different for each row) or NULL 3995273d9f13SBarry Smith 3996273d9f13SBarry Smith Notes: 399749a6f317SBarry Smith If nnz is given then nz is ignored 399849a6f317SBarry Smith 3999273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 4000273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 4001273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 4002273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 4003273d9f13SBarry Smith 4004273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 40050298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 4006273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 4007273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 4008273d9f13SBarry Smith 4009aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 4010aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 4011aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 4012aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 4013aa95bbe8SBarry Smith 4014a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 4015a96a251dSBarry Smith entries or columns indices 4016a96a251dSBarry Smith 4017273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 4018273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 4019273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 4020273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 4021273d9f13SBarry Smith 4022273d9f13SBarry Smith Options Database Keys: 4023698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 402447b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 4025273d9f13SBarry Smith 4026273d9f13SBarry Smith Level: intermediate 4027273d9f13SBarry Smith 402819b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 402919b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 4030273d9f13SBarry Smith 4031273d9f13SBarry Smith @*/ 40327087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 4033273d9f13SBarry Smith { 40344ac538c5SBarry Smith PetscErrorCode ierr; 4035a23d5eceSKris Buschelman 4036a23d5eceSKris Buschelman PetscFunctionBegin; 40376ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40386ba663aaSJed Brown PetscValidType(B,1); 40394ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 4040a23d5eceSKris Buschelman PetscFunctionReturn(0); 4041a23d5eceSKris Buschelman } 4042a23d5eceSKris Buschelman 40437087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 4044a23d5eceSKris Buschelman { 4045273d9f13SBarry Smith Mat_SeqAIJ *b; 40462576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40476849ba73SBarry Smith PetscErrorCode ierr; 404897f1f81fSBarry Smith PetscInt i; 4049273d9f13SBarry Smith 4050273d9f13SBarry Smith PetscFunctionBegin; 40512576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4052a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4053c461c341SBarry Smith skipallocation = PETSC_TRUE; 4054c461c341SBarry Smith nz = 0; 4055c461c341SBarry Smith } 405626283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 405726283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4058899cda47SBarry Smith 4059435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 406060e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4061cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4062d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 406360e0710aSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %D value %D",i,nnz[i]); 406460e0710aSBarry Smith if (nnz[i] > B->cmap->n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %D value %d rowlength %D",i,nnz[i],B->cmap->n); 4065b73539f3SBarry Smith } 4066b73539f3SBarry Smith } 4067b73539f3SBarry Smith 4068273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 40692205254eSKarl Rupp 4070273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4071273d9f13SBarry Smith 4072ab93d7beSBarry Smith if (!skipallocation) { 40732ee49352SLisandro Dalcin if (!b->imax) { 4074071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4075071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4076071fcb05SBarry Smith } 4077071fcb05SBarry Smith if (!b->ilen) { 4078071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4079071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4080071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4081071fcb05SBarry Smith } else { 4082071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 40832ee49352SLisandro Dalcin } 4084846b4da1SFande Kong if (!b->ipre) { 4085846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4086846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4087846b4da1SFande Kong } 4088273d9f13SBarry Smith if (!nnz) { 4089435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4090c62bd62aSJed Brown else if (nz < 0) nz = 1; 40915d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4092d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4093d0f46423SBarry Smith nz = nz*B->rmap->n; 4094273d9f13SBarry Smith } else { 4095c73702f5SBarry Smith PetscInt64 nz64 = 0; 4096c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4097c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4098273d9f13SBarry Smith } 4099ab93d7beSBarry Smith 4100273d9f13SBarry Smith /* allocate the matrix space */ 410153dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 41022ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4103396832f4SHong Zhang if (B->structure_only) { 41045848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 41055848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4106396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4107396832f4SHong Zhang } else { 4108dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 41093bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4110396832f4SHong Zhang } 4111bfeeae90SHong Zhang b->i[0] = 0; 4112d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 41135da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 41145da197adSKris Buschelman } 4115396832f4SHong Zhang if (B->structure_only) { 4116396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4117396832f4SHong Zhang b->free_a = PETSC_FALSE; 4118396832f4SHong Zhang } else { 4119273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4120e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4121396832f4SHong Zhang } 4122e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4123c461c341SBarry Smith } else { 4124e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4125e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4126c461c341SBarry Smith } 4127273d9f13SBarry Smith 4128846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4129846b4da1SFande Kong /* reserve user-requested sparsity */ 4130580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4131846b4da1SFande Kong } 4132846b4da1SFande Kong 4133273d9f13SBarry Smith b->nz = 0; 4134273d9f13SBarry Smith b->maxnz = nz; 4135273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 41362205254eSKarl Rupp if (realalloc) { 41372205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 41382205254eSKarl Rupp } 4139cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4140cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4141273d9f13SBarry Smith PetscFunctionReturn(0); 4142273d9f13SBarry Smith } 4143273d9f13SBarry Smith 4144846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4145846b4da1SFande Kong { 4146846b4da1SFande Kong Mat_SeqAIJ *a; 4147a5bbaf83SFande Kong PetscInt i; 4148846b4da1SFande Kong PetscErrorCode ierr; 4149846b4da1SFande Kong 4150846b4da1SFande Kong PetscFunctionBegin; 4151846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 415214d0e64fSAlex Lindsay 415314d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 415414d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 415514d0e64fSAlex Lindsay 4156846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 41572c814fdeSFande Kong /* if no saved info, we error out */ 4158fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 41592c814fdeSFande Kong 4160fb4dc15dSAlex Lindsay if (!a->i || !a->j || !a->a || !a->imax || !a->ilen) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Memory info is incomplete, and can not reset preallocation \n"); 41612c814fdeSFande Kong 4162580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4163580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4164846b4da1SFande Kong a->i[0] = 0; 4165846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4166846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4167846b4da1SFande Kong } 4168846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4169846b4da1SFande Kong a->nz = 0; 4170846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4171846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4172846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4173846b4da1SFande Kong A->assembled = PETSC_FALSE; 4174846b4da1SFande Kong PetscFunctionReturn(0); 4175846b4da1SFande Kong } 4176846b4da1SFande Kong 417758d36128SBarry Smith /*@ 4178a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4179a1661176SMatthew Knepley 4180a1661176SMatthew Knepley Input Parameters: 4181a1661176SMatthew Knepley + B - the matrix 4182a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4183a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4184a1661176SMatthew Knepley - v - optional values in the matrix 4185a1661176SMatthew Knepley 4186a1661176SMatthew Knepley Level: developer 4187a1661176SMatthew Knepley 41886a9b8d82SBarry Smith Notes: 418958d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 419058d36128SBarry Smith 41916a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 41926a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 41936a9b8d82SBarry Smith 41946a9b8d82SBarry Smith Developer Notes: 41956a9b8d82SBarry 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 41966a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 41976a9b8d82SBarry Smith 41986a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 41996a9b8d82SBarry Smith 42006a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4201a1661176SMatthew Knepley @*/ 4202a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4203a1661176SMatthew Knepley { 4204a1661176SMatthew Knepley PetscErrorCode ierr; 4205a1661176SMatthew Knepley 4206a1661176SMatthew Knepley PetscFunctionBegin; 42070700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 42086ba663aaSJed Brown PetscValidType(B,1); 42094ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4210a1661176SMatthew Knepley PetscFunctionReturn(0); 4211a1661176SMatthew Knepley } 4212a1661176SMatthew Knepley 42137087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4214a1661176SMatthew Knepley { 4215a1661176SMatthew Knepley PetscInt i; 4216a1661176SMatthew Knepley PetscInt m,n; 4217a1661176SMatthew Knepley PetscInt nz; 42186a9b8d82SBarry Smith PetscInt *nnz; 4219a1661176SMatthew Knepley PetscErrorCode ierr; 4220a1661176SMatthew Knepley 4221a1661176SMatthew Knepley PetscFunctionBegin; 422265e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4223779a8d59SSatish Balay 4224779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4225779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4226779a8d59SSatish Balay 4227779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4228854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4229a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4230b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 423165e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4232a1661176SMatthew Knepley nnz[i] = nz; 4233a1661176SMatthew Knepley } 4234a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4235a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4236a1661176SMatthew Knepley 4237a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4238071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4239a1661176SMatthew Knepley } 4240a1661176SMatthew Knepley 4241a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4242a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4243a1661176SMatthew Knepley 42447827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4245a1661176SMatthew Knepley PetscFunctionReturn(0); 4246a1661176SMatthew Knepley } 4247a1661176SMatthew Knepley 4248ad7e164aSPierre Jolivet /*@ 4249ad7e164aSPierre Jolivet MatSeqAIJKron - Computes C, the Kronecker product of A and B. 4250ad7e164aSPierre Jolivet 4251ad7e164aSPierre Jolivet Input Parameters: 4252ad7e164aSPierre Jolivet + A - left-hand side matrix 4253ad7e164aSPierre Jolivet . B - right-hand side matrix 4254ad7e164aSPierre Jolivet - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 4255ad7e164aSPierre Jolivet 4256ad7e164aSPierre Jolivet Output Parameter: 4257ad7e164aSPierre Jolivet . C - Kronecker product of A and B 4258ad7e164aSPierre Jolivet 4259ad7e164aSPierre Jolivet Level: intermediate 4260ad7e164aSPierre Jolivet 4261ad7e164aSPierre Jolivet Notes: 4262ad7e164aSPierre 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(). 4263ad7e164aSPierre Jolivet 4264ad7e164aSPierre Jolivet .seealso: MatCreateSeqAIJ(), MATSEQAIJ, MATKAIJ, MatReuse 4265ad7e164aSPierre Jolivet @*/ 4266ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron(Mat A,Mat B,MatReuse reuse,Mat *C) 4267ad7e164aSPierre Jolivet { 4268ad7e164aSPierre Jolivet PetscErrorCode ierr; 4269ad7e164aSPierre Jolivet 4270ad7e164aSPierre Jolivet PetscFunctionBegin; 4271ad7e164aSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4272ad7e164aSPierre Jolivet PetscValidType(A,1); 4273ad7e164aSPierre Jolivet PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4274ad7e164aSPierre Jolivet PetscValidType(B,2); 4275ad7e164aSPierre Jolivet PetscValidPointer(C,4); 4276ad7e164aSPierre Jolivet if (reuse == MAT_REUSE_MATRIX) { 4277ad7e164aSPierre Jolivet PetscValidHeaderSpecific(*C,MAT_CLASSID,4); 4278ad7e164aSPierre Jolivet PetscValidType(*C,4); 4279ad7e164aSPierre Jolivet } 4280ad7e164aSPierre Jolivet ierr = PetscTryMethod(A,"MatSeqAIJKron_C",(Mat,Mat,MatReuse,Mat*),(A,B,reuse,C));CHKERRQ(ierr); 4281ad7e164aSPierre Jolivet PetscFunctionReturn(0); 4282ad7e164aSPierre Jolivet } 4283ad7e164aSPierre Jolivet 4284ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron_SeqAIJ(Mat A,Mat B,MatReuse reuse,Mat *C) 4285ad7e164aSPierre Jolivet { 4286*fff043a9SJunchao Zhang PetscErrorCode ierr; 4287ad7e164aSPierre Jolivet Mat newmat; 4288ad7e164aSPierre Jolivet Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4289ad7e164aSPierre Jolivet Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 4290ad7e164aSPierre Jolivet PetscScalar *v; 4291*fff043a9SJunchao Zhang const PetscScalar *aa,*ba; 4292ad7e164aSPierre 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; 4293ad7e164aSPierre Jolivet PetscBool flg; 4294ad7e164aSPierre Jolivet 4295ad7e164aSPierre Jolivet PetscFunctionBegin; 4296ad7e164aSPierre Jolivet if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4297ad7e164aSPierre Jolivet if (!A->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4298ad7e164aSPierre Jolivet if (B->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4299ad7e164aSPierre Jolivet if (!B->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4300ad7e164aSPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr); 4301ad7e164aSPierre Jolivet if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatType %s",((PetscObject)B)->type_name); 4302ad7e164aSPierre Jolivet if (reuse != MAT_INITIAL_MATRIX && reuse != MAT_REUSE_MATRIX) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatReuse %d",(int)reuse); 4303ad7e164aSPierre Jolivet if (reuse == MAT_INITIAL_MATRIX) { 4304ad7e164aSPierre Jolivet ierr = PetscMalloc2(am*bm+1,&i,a->i[am]*b->i[bm],&j);CHKERRQ(ierr); 4305ad7e164aSPierre Jolivet ierr = MatCreate(PETSC_COMM_SELF,&newmat);CHKERRQ(ierr); 4306ad7e164aSPierre Jolivet ierr = MatSetSizes(newmat,am*bm,an*bn,am*bm,an*bn);CHKERRQ(ierr); 4307ad7e164aSPierre Jolivet ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 4308ad7e164aSPierre Jolivet i[0] = 0; 4309ad7e164aSPierre Jolivet for (m = 0; m < am; ++m) { 4310ad7e164aSPierre Jolivet for (p = 0; p < bm; ++p) { 4311ad7e164aSPierre Jolivet i[m*bm + p + 1] = i[m*bm + p] + (a->i[m+1] - a->i[m]) * (b->i[p+1] - b->i[p]); 4312ad7e164aSPierre Jolivet for (n = a->i[m]; n < a->i[m+1]; ++n) { 4313ad7e164aSPierre Jolivet for (q = b->i[p]; q < b->i[p+1]; ++q) { 4314ad7e164aSPierre Jolivet j[nnz++] = a->j[n]*bn + b->j[q]; 4315ad7e164aSPierre Jolivet } 4316ad7e164aSPierre Jolivet } 4317ad7e164aSPierre Jolivet } 4318ad7e164aSPierre Jolivet } 4319ad7e164aSPierre Jolivet ierr = MatSeqAIJSetPreallocationCSR(newmat,i,j,NULL);CHKERRQ(ierr); 4320ad7e164aSPierre Jolivet *C = newmat; 4321ad7e164aSPierre Jolivet ierr = PetscFree2(i,j);CHKERRQ(ierr); 4322ad7e164aSPierre Jolivet nnz = 0; 4323ad7e164aSPierre Jolivet } 4324ad7e164aSPierre Jolivet ierr = MatSeqAIJGetArray(*C,&v);CHKERRQ(ierr); 4325*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 4326*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(B,&ba);CHKERRQ(ierr); 4327ad7e164aSPierre Jolivet for (m = 0; m < am; ++m) { 4328ad7e164aSPierre Jolivet for (p = 0; p < bm; ++p) { 4329ad7e164aSPierre Jolivet for (n = a->i[m]; n < a->i[m+1]; ++n) { 4330ad7e164aSPierre Jolivet for (q = b->i[p]; q < b->i[p+1]; ++q) { 4331*fff043a9SJunchao Zhang v[nnz++] = aa[n] * ba[q]; 4332ad7e164aSPierre Jolivet } 4333ad7e164aSPierre Jolivet } 4334ad7e164aSPierre Jolivet } 4335ad7e164aSPierre Jolivet } 4336ad7e164aSPierre Jolivet ierr = MatSeqAIJRestoreArray(*C,&v);CHKERRQ(ierr); 4337*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 4338*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(B,&ba);CHKERRQ(ierr); 4339ad7e164aSPierre Jolivet PetscFunctionReturn(0); 4340ad7e164aSPierre Jolivet } 4341ad7e164aSPierre Jolivet 4342c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4343af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4344170fe5c8SBarry Smith 4345170fe5c8SBarry Smith /* 4346170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4347170fe5c8SBarry Smith 4348170fe5c8SBarry Smith n p p 43492da392ccSBarry Smith [ ] [ ] [ ] 43502da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 43512da392ccSBarry Smith [ ] [ ] [ ] 4352170fe5c8SBarry Smith 4353170fe5c8SBarry Smith */ 4354170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4355170fe5c8SBarry Smith { 4356170fe5c8SBarry Smith PetscErrorCode ierr; 4357170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4358170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4359170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 436086214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4361170fe5c8SBarry Smith const PetscInt *ii,*idx; 4362170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4363170fe5c8SBarry Smith PetscScalar *c,*c_q; 436486214ceeSStefano Zampini PetscInt clda = sub_c->lda; 436586214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4366170fe5c8SBarry Smith 4367170fe5c8SBarry Smith PetscFunctionBegin; 4368d0f46423SBarry Smith m = A->rmap->n; 4369d0f46423SBarry Smith n = A->cmap->n; 4370d0f46423SBarry Smith p = B->cmap->n; 4371170fe5c8SBarry Smith a = sub_a->v; 4372170fe5c8SBarry Smith b = sub_b->a; 4373170fe5c8SBarry Smith c = sub_c->v; 437486214ceeSStefano Zampini if (clda == m) { 4375580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 437686214ceeSStefano Zampini } else { 437786214ceeSStefano Zampini for (j=0;j<p;j++) 437886214ceeSStefano Zampini for (i=0;i<m;i++) 437986214ceeSStefano Zampini c[j*clda + i] = 0.0; 438086214ceeSStefano Zampini } 4381170fe5c8SBarry Smith ii = sub_b->i; 4382170fe5c8SBarry Smith idx = sub_b->j; 4383170fe5c8SBarry Smith for (i=0; i<n; i++) { 4384170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4385170fe5c8SBarry Smith while (q-->0) { 438686214ceeSStefano Zampini c_q = c + clda*(*idx); 438786214ceeSStefano Zampini a_q = a + alda*i; 4388854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4389170fe5c8SBarry Smith idx++; 4390170fe5c8SBarry Smith b++; 4391170fe5c8SBarry Smith } 4392170fe5c8SBarry Smith } 4393170fe5c8SBarry Smith PetscFunctionReturn(0); 4394170fe5c8SBarry Smith } 4395170fe5c8SBarry Smith 43964222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4397170fe5c8SBarry Smith { 4398170fe5c8SBarry Smith PetscErrorCode ierr; 4399d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 440086214ceeSStefano Zampini PetscBool cisdense; 4401170fe5c8SBarry Smith 4402170fe5c8SBarry Smith PetscFunctionBegin; 440360e0710aSBarry Smith if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %D != B->rmap->n %D\n",A->cmap->n,B->rmap->n); 44044222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 44054222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 440686214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 440786214ceeSStefano Zampini if (!cisdense) { 440886214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 440986214ceeSStefano Zampini } 441086214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4411d73949e8SHong Zhang 44124222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4413170fe5c8SBarry Smith PetscFunctionReturn(0); 4414170fe5c8SBarry Smith } 4415170fe5c8SBarry Smith 4416170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 44170bad9183SKris Buschelman /*MC 4418fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 44190bad9183SKris Buschelman based on compressed sparse row format. 44200bad9183SKris Buschelman 44210bad9183SKris Buschelman Options Database Keys: 44220bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 44230bad9183SKris Buschelman 44240bad9183SKris Buschelman Level: beginner 44250bad9183SKris Buschelman 44260cd7f59aSBarry Smith Notes: 44270cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 44280cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 44290cd7f59aSBarry Smith in the matrix 44300cd7f59aSBarry Smith 44310cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 44320cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 44330cd7f59aSBarry Smith 44340cd7f59aSBarry Smith Developer Notes: 44350cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 44360cd7f59aSBarry Smith 4437f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 44380bad9183SKris Buschelman M*/ 44390bad9183SKris Buschelman 4440ccd284c7SBarry Smith /*MC 4441ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4442ccd284c7SBarry Smith 4443ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4444ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 44450cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4446ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4447ccd284c7SBarry Smith the above preallocation routines for simplicity. 4448ccd284c7SBarry Smith 4449ccd284c7SBarry Smith Options Database Keys: 4450ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4451ccd284c7SBarry Smith 445295452b02SPatrick Sanan Developer Notes: 4453ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4454ccd284c7SBarry Smith enough exist. 4455ccd284c7SBarry Smith 4456ccd284c7SBarry Smith Level: beginner 4457ccd284c7SBarry Smith 4458ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4459ccd284c7SBarry Smith M*/ 4460ccd284c7SBarry Smith 4461ccd284c7SBarry Smith /*MC 4462ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4463ccd284c7SBarry Smith 4464ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4465ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4466ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4467ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4468ccd284c7SBarry Smith the above preallocation routines for simplicity. 4469ccd284c7SBarry Smith 4470ccd284c7SBarry Smith Options Database Keys: 4471ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4472ccd284c7SBarry Smith 4473ccd284c7SBarry Smith Level: beginner 4474ccd284c7SBarry Smith 4475ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4476ccd284c7SBarry Smith M*/ 4477ccd284c7SBarry Smith 44787906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 44797906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 44807906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 44817906f579SHong Zhang #endif 4482d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4483d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4484d24d4204SJose E. Roman #endif 44857906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 44867906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 44877906f579SHong Zhang #endif 44887906f579SHong Zhang 4489d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4490c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 44914222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 44927906f579SHong Zhang 44938c778c55SBarry Smith /*@C 44948f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 44958c778c55SBarry Smith 44968c778c55SBarry Smith Not Collective 44978c778c55SBarry Smith 44988c778c55SBarry Smith Input Parameter: 4499579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 45008c778c55SBarry Smith 45018c778c55SBarry Smith Output Parameter: 45028c778c55SBarry Smith . array - pointer to the data 45038c778c55SBarry Smith 45048c778c55SBarry Smith Level: intermediate 45058c778c55SBarry Smith 4506774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 45078c778c55SBarry Smith @*/ 45088c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 45098c778c55SBarry Smith { 45108c778c55SBarry Smith PetscErrorCode ierr; 4511d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 45128c778c55SBarry Smith 45138c778c55SBarry Smith PetscFunctionBegin; 4514d67d9f35SJunchao Zhang if (aij->ops->getarray) { 4515d67d9f35SJunchao Zhang ierr = (*aij->ops->getarray)(A,array);CHKERRQ(ierr); 4516d67d9f35SJunchao Zhang } else { 4517d67d9f35SJunchao Zhang *array = aij->a; 4518d67d9f35SJunchao Zhang } 4519d67d9f35SJunchao Zhang PetscFunctionReturn(0); 4520d67d9f35SJunchao Zhang } 4521d67d9f35SJunchao Zhang 4522d67d9f35SJunchao Zhang /*@C 4523d67d9f35SJunchao Zhang MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 4524d67d9f35SJunchao Zhang 4525d67d9f35SJunchao Zhang Not Collective 4526d67d9f35SJunchao Zhang 4527d67d9f35SJunchao Zhang Input Parameters: 4528d67d9f35SJunchao Zhang + mat - a MATSEQAIJ matrix 4529d67d9f35SJunchao Zhang - array - pointer to the data 4530d67d9f35SJunchao Zhang 4531d67d9f35SJunchao Zhang Level: intermediate 4532d67d9f35SJunchao Zhang 4533d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 4534d67d9f35SJunchao Zhang @*/ 4535d67d9f35SJunchao Zhang PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 4536d67d9f35SJunchao Zhang { 4537d67d9f35SJunchao Zhang PetscErrorCode ierr; 4538d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 4539d67d9f35SJunchao Zhang 4540d67d9f35SJunchao Zhang PetscFunctionBegin; 4541d67d9f35SJunchao Zhang if (aij->ops->restorearray) { 4542d67d9f35SJunchao Zhang ierr = (*aij->ops->restorearray)(A,array);CHKERRQ(ierr); 4543d67d9f35SJunchao Zhang } else { 4544d67d9f35SJunchao Zhang *array = NULL; 4545d67d9f35SJunchao Zhang } 45468c778c55SBarry Smith PetscFunctionReturn(0); 45478c778c55SBarry Smith } 45488c778c55SBarry Smith 454921e72a00SBarry Smith /*@C 45508f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 45518f1ea47aSStefano Zampini 45528f1ea47aSStefano Zampini Not Collective 45538f1ea47aSStefano Zampini 45548f1ea47aSStefano Zampini Input Parameter: 45558f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 45568f1ea47aSStefano Zampini 45578f1ea47aSStefano Zampini Output Parameter: 45588f1ea47aSStefano Zampini . array - pointer to the data 45598f1ea47aSStefano Zampini 45608f1ea47aSStefano Zampini Level: intermediate 45618f1ea47aSStefano Zampini 45628f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 45638f1ea47aSStefano Zampini @*/ 45648f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 45658f1ea47aSStefano Zampini { 45668f1ea47aSStefano Zampini PetscErrorCode ierr; 4567d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 45688f1ea47aSStefano Zampini 45698f1ea47aSStefano Zampini PetscFunctionBegin; 4570d67d9f35SJunchao Zhang if (aij->ops->getarrayread) { 4571d67d9f35SJunchao Zhang ierr = (*aij->ops->getarrayread)(A,array);CHKERRQ(ierr); 4572d67d9f35SJunchao Zhang } else { 4573d67d9f35SJunchao Zhang *array = aij->a; 4574d67d9f35SJunchao Zhang } 45758f1ea47aSStefano Zampini PetscFunctionReturn(0); 45768f1ea47aSStefano Zampini } 45778f1ea47aSStefano Zampini 45788f1ea47aSStefano Zampini /*@C 45798f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 45808f1ea47aSStefano Zampini 45818f1ea47aSStefano Zampini Not Collective 45828f1ea47aSStefano Zampini 45838f1ea47aSStefano Zampini Input Parameter: 45848f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 45858f1ea47aSStefano Zampini 45868f1ea47aSStefano Zampini Output Parameter: 45878f1ea47aSStefano Zampini . array - pointer to the data 45888f1ea47aSStefano Zampini 45898f1ea47aSStefano Zampini Level: intermediate 45908f1ea47aSStefano Zampini 45918f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 45928f1ea47aSStefano Zampini @*/ 45938f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 45948f1ea47aSStefano Zampini { 45958f1ea47aSStefano Zampini PetscErrorCode ierr; 4596d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 45978f1ea47aSStefano Zampini 45988f1ea47aSStefano Zampini PetscFunctionBegin; 4599d67d9f35SJunchao Zhang if (aij->ops->restorearrayread) { 4600d67d9f35SJunchao Zhang ierr = (*aij->ops->restorearrayread)(A,array);CHKERRQ(ierr); 4601d67d9f35SJunchao Zhang } else { 4602d67d9f35SJunchao Zhang *array = NULL; 4603d67d9f35SJunchao Zhang } 4604d67d9f35SJunchao Zhang PetscFunctionReturn(0); 4605d67d9f35SJunchao Zhang } 4606d67d9f35SJunchao Zhang 4607d67d9f35SJunchao Zhang /*@C 4608d67d9f35SJunchao Zhang MatSeqAIJGetArrayWrite - gives write-only access to the array where the data for a MATSEQAIJ matrix is stored 4609d67d9f35SJunchao Zhang 4610d67d9f35SJunchao Zhang Not Collective 4611d67d9f35SJunchao Zhang 4612d67d9f35SJunchao Zhang Input Parameter: 4613d67d9f35SJunchao Zhang . mat - a MATSEQAIJ matrix 4614d67d9f35SJunchao Zhang 4615d67d9f35SJunchao Zhang Output Parameter: 4616d67d9f35SJunchao Zhang . array - pointer to the data 4617d67d9f35SJunchao Zhang 4618d67d9f35SJunchao Zhang Level: intermediate 4619d67d9f35SJunchao Zhang 4620d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 4621d67d9f35SJunchao Zhang @*/ 4622d67d9f35SJunchao Zhang PetscErrorCode MatSeqAIJGetArrayWrite(Mat A,PetscScalar **array) 4623d67d9f35SJunchao Zhang { 4624d67d9f35SJunchao Zhang PetscErrorCode ierr; 4625d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 4626d67d9f35SJunchao Zhang 4627d67d9f35SJunchao Zhang PetscFunctionBegin; 4628d67d9f35SJunchao Zhang if (aij->ops->getarraywrite) { 4629d67d9f35SJunchao Zhang ierr = (*aij->ops->getarraywrite)(A,array);CHKERRQ(ierr); 4630d67d9f35SJunchao Zhang } else { 4631d67d9f35SJunchao Zhang *array = aij->a; 4632d67d9f35SJunchao Zhang } 4633d67d9f35SJunchao Zhang PetscFunctionReturn(0); 4634d67d9f35SJunchao Zhang } 4635d67d9f35SJunchao Zhang 4636d67d9f35SJunchao Zhang /*@C 4637d67d9f35SJunchao Zhang MatSeqAIJRestoreArrayWrite - restore the read-only access array obtained from MatSeqAIJGetArrayRead 4638d67d9f35SJunchao Zhang 4639d67d9f35SJunchao Zhang Not Collective 4640d67d9f35SJunchao Zhang 4641d67d9f35SJunchao Zhang Input Parameter: 4642d67d9f35SJunchao Zhang . mat - a MATSEQAIJ matrix 4643d67d9f35SJunchao Zhang 4644d67d9f35SJunchao Zhang Output Parameter: 4645d67d9f35SJunchao Zhang . array - pointer to the data 4646d67d9f35SJunchao Zhang 4647d67d9f35SJunchao Zhang Level: intermediate 4648d67d9f35SJunchao Zhang 4649d67d9f35SJunchao Zhang .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 4650d67d9f35SJunchao Zhang @*/ 4651d67d9f35SJunchao Zhang PetscErrorCode MatSeqAIJRestoreArrayWrite(Mat A,PetscScalar **array) 4652d67d9f35SJunchao Zhang { 4653d67d9f35SJunchao Zhang PetscErrorCode ierr; 4654d67d9f35SJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 4655d67d9f35SJunchao Zhang 4656d67d9f35SJunchao Zhang PetscFunctionBegin; 4657d67d9f35SJunchao Zhang if (aij->ops->restorearraywrite) { 4658d67d9f35SJunchao Zhang ierr = (*aij->ops->restorearraywrite)(A,array);CHKERRQ(ierr); 4659d67d9f35SJunchao Zhang } else { 4660d67d9f35SJunchao Zhang *array = NULL; 4661d67d9f35SJunchao Zhang } 46628f1ea47aSStefano Zampini PetscFunctionReturn(0); 46638f1ea47aSStefano Zampini } 46648f1ea47aSStefano Zampini 46658f1ea47aSStefano Zampini /*@C 466621e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 466721e72a00SBarry Smith 466821e72a00SBarry Smith Not Collective 466921e72a00SBarry Smith 467021e72a00SBarry Smith Input Parameter: 4671579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 467221e72a00SBarry Smith 467321e72a00SBarry Smith Output Parameter: 467421e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 467521e72a00SBarry Smith 467621e72a00SBarry Smith Level: intermediate 467721e72a00SBarry Smith 467821e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 467921e72a00SBarry Smith @*/ 468021e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 468121e72a00SBarry Smith { 468221e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 468321e72a00SBarry Smith 468421e72a00SBarry Smith PetscFunctionBegin; 468521e72a00SBarry Smith *nz = aij->rmax; 468621e72a00SBarry Smith PetscFunctionReturn(0); 468721e72a00SBarry Smith } 468821e72a00SBarry Smith 468934b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 46905063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat,MatType,MatReuse,Mat*); 469102fe1965SBarry Smith #endif 46923d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 46935063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat,MatType,MatReuse,Mat*); 46943d0639e7SStefano Zampini #endif 469502fe1965SBarry Smith 46968cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4697273d9f13SBarry Smith { 4698273d9f13SBarry Smith Mat_SeqAIJ *b; 4699dfbe8321SBarry Smith PetscErrorCode ierr; 470038baddfdSBarry Smith PetscMPIInt size; 4701273d9f13SBarry Smith 4702273d9f13SBarry Smith PetscFunctionBegin; 4703ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr); 4704e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4705273d9f13SBarry Smith 4706b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 47072205254eSKarl Rupp 4708b0a32e0cSBarry Smith B->data = (void*)b; 47092205254eSKarl Rupp 4710549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4711071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 47122205254eSKarl Rupp 4713f4259b30SLisandro Dalcin b->row = NULL; 4714f4259b30SLisandro Dalcin b->col = NULL; 4715f4259b30SLisandro Dalcin b->icol = NULL; 4716b810aeb4SBarry Smith b->reallocs = 0; 471736db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4718f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4719416022c9SBarry Smith b->nonew = 0; 4720f4259b30SLisandro Dalcin b->diag = NULL; 4721f4259b30SLisandro Dalcin b->solve_work = NULL; 4722f4259b30SLisandro Dalcin B->spptr = NULL; 4723f4259b30SLisandro Dalcin b->saved_values = NULL; 4724f4259b30SLisandro Dalcin b->idiag = NULL; 4725f4259b30SLisandro Dalcin b->mdiag = NULL; 4726f4259b30SLisandro Dalcin b->ssor_work = NULL; 472771f1c65dSBarry Smith b->omega = 1.0; 472871f1c65dSBarry Smith b->fshift = 0.0; 472971f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4730bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4731a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 473217ab2063SBarry Smith 473335d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 47348c778c55SBarry Smith 4735b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4736bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4737bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4738b3866ffcSBarry Smith #endif 473917f1a0eaSHong Zhang 4740bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4741bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4742bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4743bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4744bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4745bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 47464dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 47479779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 47484a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4749191b95cbSRichard Tran Mills #endif 475034b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 475102fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 47524222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4753fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 475402fe1965SBarry Smith #endif 47553d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 47563d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 47573d0639e7SStefano Zampini #endif 4758bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4759af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4760af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4761af8000cdSHong Zhang #endif 4762d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4763d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4764d24d4204SJose E. Roman #endif 476563c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 476663c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 47674222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 476863c07aadSStefano Zampini #endif 4769b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4770d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4771c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4772bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4773bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4774bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4775846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4776bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4777bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 47784222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 47794222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 47804222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4781ad7e164aSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJKron_C",MatSeqAIJKron_SeqAIJ);CHKERRQ(ierr); 47824108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 478317667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 47844099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 47853a40ed3dSBarry Smith PetscFunctionReturn(0); 478617ab2063SBarry Smith } 478717ab2063SBarry Smith 4788b24902e0SBarry Smith /* 4789b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4790b24902e0SBarry Smith */ 4791ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 479217ab2063SBarry Smith { 47932a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 47946849ba73SBarry Smith PetscErrorCode ierr; 4795071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 479617ab2063SBarry Smith 47973a40ed3dSBarry Smith PetscFunctionBegin; 4798ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4799273d9f13SBarry Smith 4800d5f3da31SBarry Smith C->factortype = A->factortype; 4801f4259b30SLisandro Dalcin c->row = NULL; 4802f4259b30SLisandro Dalcin c->col = NULL; 4803f4259b30SLisandro Dalcin c->icol = NULL; 48046ad4291fSHong Zhang c->reallocs = 0; 480517ab2063SBarry Smith 48066ad4291fSHong Zhang C->assembled = PETSC_TRUE; 480717ab2063SBarry Smith 4808aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4809aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4810eec197d1SBarry Smith 4811071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4812071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4813071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4814071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 48153bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 481617ab2063SBarry Smith 481717ab2063SBarry Smith /* allocate the matrix space */ 4818f77e22a1SHong Zhang if (mallocmatspace) { 4819dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 48203bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 48212205254eSKarl Rupp 4822f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 48232205254eSKarl Rupp 4824580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 482517ab2063SBarry Smith if (m > 0) { 4826580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4827be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 48282e5835c6SStefano Zampini const PetscScalar *aa; 48292e5835c6SStefano Zampini 48302e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 48312e5835c6SStefano Zampini ierr = PetscArraycpy(c->a,aa,a->i[m]);CHKERRQ(ierr); 48322e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 4833be6bf707SBarry Smith } else { 4834580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 483517ab2063SBarry Smith } 483608480c60SBarry Smith } 4837f77e22a1SHong Zhang } 483817ab2063SBarry Smith 48396ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4840416022c9SBarry Smith c->roworiented = a->roworiented; 4841416022c9SBarry Smith c->nonew = a->nonew; 4842416022c9SBarry Smith if (a->diag) { 4843854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4844071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 48453bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4846071fcb05SBarry Smith } else c->diag = NULL; 48472205254eSKarl Rupp 4848f4259b30SLisandro Dalcin c->solve_work = NULL; 4849f4259b30SLisandro Dalcin c->saved_values = NULL; 4850f4259b30SLisandro Dalcin c->idiag = NULL; 4851f4259b30SLisandro Dalcin c->ssor_work = NULL; 4852a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4853e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4854e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 48556ad4291fSHong Zhang 4856893ad86cSHong Zhang c->rmax = a->rmax; 4857416022c9SBarry Smith c->nz = a->nz; 48588ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4859273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4860754ec7b1SSatish Balay 48616ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 48626ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4863cd6b891eSBarry Smith if (a->compressedrow.use) { 48646ad4291fSHong Zhang i = a->compressedrow.nrows; 4865dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4866580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4867580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 486827ea64f8SHong Zhang } else { 486927ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 48700298fd71SBarry Smith c->compressedrow.i = NULL; 48710298fd71SBarry Smith c->compressedrow.rindex = NULL; 48726ad4291fSHong Zhang } 4873ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4874e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 48754846f1f5SKris Buschelman 48762205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4877140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 48783a40ed3dSBarry Smith PetscFunctionReturn(0); 487917ab2063SBarry Smith } 488017ab2063SBarry Smith 4881b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4882b24902e0SBarry Smith { 4883b24902e0SBarry Smith PetscErrorCode ierr; 4884b24902e0SBarry Smith 4885b24902e0SBarry Smith PetscFunctionBegin; 4886ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 48874b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4888cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 488933d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4890cfd3f464SBarry Smith } 4891a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4892f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4893b24902e0SBarry Smith PetscFunctionReturn(0); 4894b24902e0SBarry Smith } 4895b24902e0SBarry Smith 4896112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4897fbdbba38SShri Abhyankar { 489852f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 489952f91c60SVaclav Hapla PetscErrorCode ierr; 490052f91c60SVaclav Hapla 490152f91c60SVaclav Hapla PetscFunctionBegin; 490252f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 490352f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4904c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4905c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 490652f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 490752f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 490852f91c60SVaclav Hapla if (isbinary) { 490952f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 491052f91c60SVaclav Hapla } else if (ishdf5) { 491152f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 491252f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 491352f91c60SVaclav Hapla #else 491452f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 491552f91c60SVaclav Hapla #endif 491652f91c60SVaclav Hapla } else { 491752f91c60SVaclav Hapla SETERRQ2(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name); 491852f91c60SVaclav Hapla } 491952f91c60SVaclav Hapla PetscFunctionReturn(0); 492052f91c60SVaclav Hapla } 492152f91c60SVaclav Hapla 49223ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 492352f91c60SVaclav Hapla { 49243ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4925fbdbba38SShri Abhyankar PetscErrorCode ierr; 49263ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4927fbdbba38SShri Abhyankar 4928fbdbba38SShri Abhyankar PetscFunctionBegin; 49293ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4930bbead8a2SBarry Smith 49313ea6fe3dSLisandro Dalcin /* read in matrix header */ 49323ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 49333ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4934fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 49353ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 49363ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4937bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4938fbdbba38SShri Abhyankar 49393ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 49403ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 49413ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 49423ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 49433ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 49443ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 49453ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 49463ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 49473ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 49483ea6fe3dSLisandro Dalcin 49493ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 49503ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 49513ea6fe3dSLisandro Dalcin if (M != rows || N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%D, %D) than the input matrix (%D, %D)",M,N,rows,cols); 49523ea6fe3dSLisandro Dalcin 4953fbdbba38SShri Abhyankar /* read in row lengths */ 49543ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 49553ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 49563ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 49573ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 49583ea6fe3dSLisandro Dalcin if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Inconsistent matrix data in file: nonzeros = %D, sum-row-lengths = %D\n",nz,sum); 49593ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 49603ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 49613ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 496260e0710aSBarry Smith if (M != rows || N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%D, %D) than the input matrix (%D, %D)",M,N,rows,cols); 49633ea6fe3dSLisandro Dalcin /* store row lengths */ 49643ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 49653ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4966fbdbba38SShri Abhyankar 49673ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 49683ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 49693ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 49703ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 49713ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 49723ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4973fbdbba38SShri Abhyankar 49743ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49753ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4976fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4977fbdbba38SShri Abhyankar } 4978fbdbba38SShri Abhyankar 4979ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 49807264ac53SSatish Balay { 49817264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4982dfbe8321SBarry Smith PetscErrorCode ierr; 4983*fff043a9SJunchao Zhang const PetscScalar *aa,*ba; 4984eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4985eeffb40dSHong Zhang PetscInt k; 4986eeffb40dSHong Zhang #endif 49877264ac53SSatish Balay 49883a40ed3dSBarry Smith PetscFunctionBegin; 4989bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4990d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4991ca44d042SBarry Smith *flg = PETSC_FALSE; 4992ca44d042SBarry Smith PetscFunctionReturn(0); 4993bcd2baecSBarry Smith } 49947264ac53SSatish Balay 49957264ac53SSatish Balay /* if the a->i are the same */ 4996580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4997abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 49987264ac53SSatish Balay 49997264ac53SSatish Balay /* if a->j are the same */ 5000580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 5001abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 5002bcd2baecSBarry Smith 5003*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 5004*fff043a9SJunchao Zhang ierr = MatSeqAIJGetArrayRead(B,&ba);CHKERRQ(ierr); 5005bcd2baecSBarry Smith /* if a->a are the same */ 5006eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 5007eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 5008*fff043a9SJunchao Zhang if (PetscRealPart(aa[k]) != PetscRealPart(ba[k]) || PetscImaginaryPart(aa[k]) != PetscImaginaryPart(ba[k])) { 5009eeffb40dSHong Zhang *flg = PETSC_FALSE; 50103a40ed3dSBarry Smith PetscFunctionReturn(0); 5011eeffb40dSHong Zhang } 5012eeffb40dSHong Zhang } 5013eeffb40dSHong Zhang #else 5014*fff043a9SJunchao Zhang ierr = PetscArraycmp(aa,ba,a->nz,flg);CHKERRQ(ierr); 5015eeffb40dSHong Zhang #endif 5016*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 5017*fff043a9SJunchao Zhang ierr = MatSeqAIJRestoreArrayRead(B,&ba);CHKERRQ(ierr); 5018eeffb40dSHong Zhang PetscFunctionReturn(0); 50197264ac53SSatish Balay } 502036db0b34SBarry Smith 502105869f15SSatish Balay /*@ 502236db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 502336db0b34SBarry Smith provided by the user. 502436db0b34SBarry Smith 5025d083f849SBarry Smith Collective 502636db0b34SBarry Smith 502736db0b34SBarry Smith Input Parameters: 502836db0b34SBarry Smith + comm - must be an MPI communicator of size 1 502936db0b34SBarry Smith . m - number of rows 503036db0b34SBarry Smith . n - number of columns 5031483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 503236db0b34SBarry Smith . j - column indices 503336db0b34SBarry Smith - a - matrix values 503436db0b34SBarry Smith 503536db0b34SBarry Smith Output Parameter: 503636db0b34SBarry Smith . mat - the matrix 503736db0b34SBarry Smith 503836db0b34SBarry Smith Level: intermediate 503936db0b34SBarry Smith 504036db0b34SBarry Smith Notes: 50410551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 5042292fb18eSBarry Smith once the matrix is destroyed and not before 504336db0b34SBarry Smith 504436db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 504536db0b34SBarry Smith 5046bfeeae90SHong Zhang The i and j indices are 0 based 504736db0b34SBarry Smith 5048a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 5049a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 50508eef79e4SBarry Smith as shown 5051a4552177SSatish Balay 50528eef79e4SBarry Smith $ 1 0 0 50538eef79e4SBarry Smith $ 2 0 3 50548eef79e4SBarry Smith $ 4 5 6 50558eef79e4SBarry Smith $ 50568eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 50578eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 50588eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 5059a4552177SSatish Balay 506069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 506136db0b34SBarry Smith 506236db0b34SBarry Smith @*/ 5063c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 506436db0b34SBarry Smith { 5065dfbe8321SBarry Smith PetscErrorCode ierr; 5066cbcfb4deSHong Zhang PetscInt ii; 506736db0b34SBarry Smith Mat_SeqAIJ *aij; 5068cbcfb4deSHong Zhang PetscInt jj; 506936db0b34SBarry Smith 507036db0b34SBarry Smith PetscFunctionBegin; 507141096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 5072f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 5073f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 5074a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 5075ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 5076f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 5077ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 5078071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 5079071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 5080ab93d7beSBarry Smith 508136db0b34SBarry Smith aij->i = i; 508236db0b34SBarry Smith aij->j = j; 508336db0b34SBarry Smith aij->a = a; 508436db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 508536db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 5086e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 5087e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 508836db0b34SBarry Smith 508936db0b34SBarry Smith for (ii=0; ii<m; ii++) { 509036db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 509176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 509260e0710aSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %D length = %D",ii,i[ii+1] - i[ii]); 50939985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 5094a061629eSStefano Zampini if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual column %D) in row %D is not sorted",jj-i[ii],j[jj],ii); 5095a061629eSStefano Zampini if (j[jj] == j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual column %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii); 50969985e31cSBarry Smith } 509736db0b34SBarry Smith } 509876bd3646SJed Brown } 509976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 510036db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 510160e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 510260e0710aSBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %D index = %D",ii,j[ii]); 510336db0b34SBarry Smith } 510476bd3646SJed Brown } 510536db0b34SBarry Smith 5106b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5107b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 510836db0b34SBarry Smith PetscFunctionReturn(0); 510936db0b34SBarry Smith } 511080ef6e79SMatthew G Knepley /*@C 5111d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 51128a0b0e6bSVictor Minden provided by the user. 51138a0b0e6bSVictor Minden 5114d083f849SBarry Smith Collective 51158a0b0e6bSVictor Minden 51168a0b0e6bSVictor Minden Input Parameters: 51178a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 51188a0b0e6bSVictor Minden . m - number of rows 51198a0b0e6bSVictor Minden . n - number of columns 51208a0b0e6bSVictor Minden . i - row indices 51218a0b0e6bSVictor Minden . j - column indices 51221230e6d1SVictor Minden . a - matrix values 51231230e6d1SVictor Minden . nz - number of nonzeros 51241230e6d1SVictor Minden - idx - 0 or 1 based 51258a0b0e6bSVictor Minden 51268a0b0e6bSVictor Minden Output Parameter: 51278a0b0e6bSVictor Minden . mat - the matrix 51288a0b0e6bSVictor Minden 51298a0b0e6bSVictor Minden Level: intermediate 51308a0b0e6bSVictor Minden 51318a0b0e6bSVictor Minden Notes: 51329e99939fSJunchao 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, 51339e99939fSJunchao Zhang the input data expected is as shown 51349e99939fSJunchao Zhang .vb 51358a0b0e6bSVictor Minden 1 0 0 51368a0b0e6bSVictor Minden 2 0 3 51378a0b0e6bSVictor Minden 4 5 6 51388a0b0e6bSVictor Minden 51398a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 51408a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 51418a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 51429e99939fSJunchao Zhang .ve 51438a0b0e6bSVictor Minden 514469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 51458a0b0e6bSVictor Minden 51468a0b0e6bSVictor Minden @*/ 5147c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 51488a0b0e6bSVictor Minden { 51498a0b0e6bSVictor Minden PetscErrorCode ierr; 5150d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 51518a0b0e6bSVictor Minden 51528a0b0e6bSVictor Minden PetscFunctionBegin; 51531795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 51541230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 5155c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 51561230e6d1SVictor Minden } 51578a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 51588a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 51598a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 51601230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 51611230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 51621230e6d1SVictor Minden if (idx) { 51631230e6d1SVictor Minden row = i[ii] - 1; 51641230e6d1SVictor Minden col = j[ii] - 1; 51651230e6d1SVictor Minden } else { 51661230e6d1SVictor Minden row = i[ii]; 51671230e6d1SVictor Minden col = j[ii]; 51688a0b0e6bSVictor Minden } 51691230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 51708a0b0e6bSVictor Minden } 51718a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 51728a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5173d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 51748a0b0e6bSVictor Minden PetscFunctionReturn(0); 51758a0b0e6bSVictor Minden } 517636db0b34SBarry Smith 5177acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 5178acf2f550SJed Brown { 5179acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5180acf2f550SJed Brown PetscErrorCode ierr; 5181acf2f550SJed Brown 5182acf2f550SJed Brown PetscFunctionBegin; 5183acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5184acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 51852205254eSKarl Rupp 5186acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 5187acf2f550SJed Brown PetscFunctionReturn(0); 5188acf2f550SJed Brown } 5189acf2f550SJed Brown 51909c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 51919c8f2541SHong Zhang { 51929c8f2541SHong Zhang PetscErrorCode ierr; 51938761c3d6SHong Zhang PetscMPIInt size; 51949c8f2541SHong Zhang 51959c8f2541SHong Zhang PetscFunctionBegin; 5196ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 51977bbdc51dSHong Zhang if (size == 1) { 51987bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 51997bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 52007bbdc51dSHong Zhang } else { 52018761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 52027bbdc51dSHong Zhang } 52038761c3d6SHong Zhang } else { 52049c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 52058761c3d6SHong Zhang } 52069c8f2541SHong Zhang PetscFunctionReturn(0); 52079c8f2541SHong Zhang } 52089c8f2541SHong Zhang 520981824310SBarry Smith /* 521053dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 521153dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 521253dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 521353dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 521453dd7562SDmitry Karpeev */ 521553dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 521653dd7562SDmitry Karpeev { 521753dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 521853dd7562SDmitry Karpeev PetscErrorCode ierr; 521953dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 522053dd7562SDmitry Karpeev PetscBool seqaij; 522153dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 522253dd7562SDmitry Karpeev PetscScalar v; 522353dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 522453dd7562SDmitry Karpeev 522553dd7562SDmitry Karpeev PetscFunctionBegin; 522653dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 522753dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 52284099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 522953dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 523053dd7562SDmitry Karpeev if (rowemb) { 523153dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 523253dd7562SDmitry Karpeev if (m != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Row IS of size %D is incompatible with matrix row size %D",m,B->rmap->n); 523353dd7562SDmitry Karpeev } else { 52346c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 523553dd7562SDmitry Karpeev } 523653dd7562SDmitry Karpeev if (colemb) { 523753dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 523853dd7562SDmitry Karpeev if (n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Diag col IS of size %D is incompatible with input matrix col size %D",n,B->cmap->n); 523953dd7562SDmitry Karpeev } else { 524053dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 524153dd7562SDmitry Karpeev } 524253dd7562SDmitry Karpeev 524353dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 524453dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 524553dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 524653dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 524753dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 524853dd7562SDmitry Karpeev } 524953dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 525053dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 525153dd7562SDmitry Karpeev } 525253dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 525353dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 525453dd7562SDmitry Karpeev } 525553dd7562SDmitry Karpeev count = 0; 525653dd7562SDmitry Karpeev rowindices = NULL; 525753dd7562SDmitry Karpeev colindices = NULL; 525853dd7562SDmitry Karpeev if (rowemb) { 525953dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 526053dd7562SDmitry Karpeev } 526153dd7562SDmitry Karpeev if (colemb) { 526253dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 526353dd7562SDmitry Karpeev } 526453dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 526553dd7562SDmitry Karpeev PetscInt row; 526653dd7562SDmitry Karpeev row = i; 526753dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 526853dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 526953dd7562SDmitry Karpeev PetscInt col; 527053dd7562SDmitry Karpeev col = Baij->j[count]; 527153dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 527253dd7562SDmitry Karpeev v = Baij->a[count]; 527353dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 527453dd7562SDmitry Karpeev ++count; 527553dd7562SDmitry Karpeev } 527653dd7562SDmitry Karpeev } 527753dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 527853dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 527953dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 528053dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 528153dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 528253dd7562SDmitry Karpeev PetscFunctionReturn(0); 528353dd7562SDmitry Karpeev } 528453dd7562SDmitry Karpeev 52854099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 52864099cc6bSBarry Smith 52874099cc6bSBarry Smith /*@C 52884099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 52894099cc6bSBarry Smith 52904099cc6bSBarry Smith Collective on Mat 52914099cc6bSBarry Smith 52924099cc6bSBarry Smith Input Parameters: 52934099cc6bSBarry Smith + mat - the matrix object 52944099cc6bSBarry Smith - matype - matrix type 52954099cc6bSBarry Smith 52964099cc6bSBarry Smith Options Database Key: 52974099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 52984099cc6bSBarry Smith 52994099cc6bSBarry Smith Level: intermediate 53004099cc6bSBarry Smith 53014099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 53024099cc6bSBarry Smith @*/ 53034099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 53044099cc6bSBarry Smith { 5305fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 53064099cc6bSBarry Smith PetscBool sametype; 53074099cc6bSBarry Smith 53084099cc6bSBarry Smith PetscFunctionBegin; 53094099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 53104099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 53114099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 53124099cc6bSBarry Smith 53134099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 53144099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 53154099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 53164099cc6bSBarry Smith PetscFunctionReturn(0); 53174099cc6bSBarry Smith } 53184099cc6bSBarry Smith 53194099cc6bSBarry Smith /*@C 53204099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 53214099cc6bSBarry Smith 53224099cc6bSBarry Smith Not Collective 53234099cc6bSBarry Smith 53244099cc6bSBarry Smith Input Parameters: 53254099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 53264099cc6bSBarry Smith - function - routine to convert to subtype 53274099cc6bSBarry Smith 53284099cc6bSBarry Smith Notes: 53294099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 53304099cc6bSBarry Smith 53314099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 53324099cc6bSBarry Smith $ -mat_seqaij_type my_mat 53334099cc6bSBarry Smith 53344099cc6bSBarry Smith Level: advanced 53354099cc6bSBarry Smith 53364099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 53374099cc6bSBarry Smith 53384099cc6bSBarry Smith Level: advanced 53394099cc6bSBarry Smith @*/ 5340388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 53414099cc6bSBarry Smith { 53424099cc6bSBarry Smith PetscErrorCode ierr; 53434099cc6bSBarry Smith 53444099cc6bSBarry Smith PetscFunctionBegin; 53459cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 53464099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 53474099cc6bSBarry Smith PetscFunctionReturn(0); 53484099cc6bSBarry Smith } 53494099cc6bSBarry Smith 53504099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 53514099cc6bSBarry Smith 53524099cc6bSBarry Smith /*@C 53534099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 53544099cc6bSBarry Smith 53554099cc6bSBarry Smith Not Collective 53564099cc6bSBarry Smith 53574099cc6bSBarry Smith Level: advanced 53584099cc6bSBarry Smith 53594099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 53604099cc6bSBarry Smith @*/ 53614099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 53624099cc6bSBarry Smith { 53634099cc6bSBarry Smith PetscErrorCode ierr; 53644099cc6bSBarry Smith 53654099cc6bSBarry Smith PetscFunctionBegin; 53664099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 53674099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 53684099cc6bSBarry Smith 53694099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 53704099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 53714dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 53729779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 53736b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5374485f9817SRichard Tran Mills #endif 53755063d097SStefano Zampini #if defined(PETSC_HAVE_CUDA) 53765063d097SStefano Zampini ierr = MatSeqAIJRegister(MATSEQAIJCUSPARSE, MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 53775063d097SStefano Zampini #endif 53785063d097SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 53795063d097SStefano Zampini ierr = MatSeqAIJRegister(MATSEQAIJKOKKOS, MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 53805063d097SStefano Zampini #endif 53814099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 53824099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 53834099cc6bSBarry Smith #endif 53844099cc6bSBarry Smith PetscFunctionReturn(0); 53854099cc6bSBarry Smith } 538653dd7562SDmitry Karpeev 538753dd7562SDmitry Karpeev /* 538881824310SBarry Smith Special version for direct calls from Fortran 538981824310SBarry Smith */ 5390af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 539181824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 539281824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 539381824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 539481824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 539581824310SBarry Smith #endif 539681824310SBarry Smith 539781824310SBarry Smith /* Change these macros so can be used in void function */ 539881824310SBarry Smith #undef CHKERRQ 53992e58f0efSBarry Smith #define CHKERRQ(err) CHKERRABORT(PetscObjectComm((PetscObject)A),err) 540081824310SBarry Smith #undef SETERRQ2 54012e58f0efSBarry Smith #define SETERRQ2(comm,err,b,c,d) CHKERRABORT(comm,err) 54024994cf47SJed Brown #undef SETERRQ3 54032e58f0efSBarry Smith #define SETERRQ3(comm,err,b,c,d,e) CHKERRABORT(comm,err) 540481824310SBarry Smith 540519caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 540681824310SBarry Smith { 540781824310SBarry Smith Mat A = *AA; 540881824310SBarry Smith PetscInt m = *mm, n = *nn; 540981824310SBarry Smith InsertMode is = *isis; 541081824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 541181824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 541281824310SBarry Smith PetscInt *imax,*ai,*ailen; 541381824310SBarry Smith PetscErrorCode ierr; 541481824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 541554f21887SBarry Smith MatScalar *ap,value,*aa; 5416ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5417ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 541881824310SBarry Smith 541981824310SBarry Smith PetscFunctionBegin; 54204994cf47SJed Brown MatCheckPreallocated(A,1); 542181824310SBarry Smith imax = a->imax; 542281824310SBarry Smith ai = a->i; 542381824310SBarry Smith ailen = a->ilen; 542481824310SBarry Smith aj = a->j; 542581824310SBarry Smith aa = a->a; 542681824310SBarry Smith 542781824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 542881824310SBarry Smith row = im[k]; 542981824310SBarry Smith if (row < 0) continue; 5430cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 543181824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 543281824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 543381824310SBarry Smith low = 0; 543481824310SBarry Smith high = nrow; 543581824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 543681824310SBarry Smith if (in[l] < 0) continue; 5437cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 543881824310SBarry Smith col = in[l]; 54392205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 54402205254eSKarl Rupp else value = v[k + l*m]; 54412205254eSKarl Rupp 544281824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 544381824310SBarry Smith 54442205254eSKarl Rupp if (col <= lastcol) low = 0; 54452205254eSKarl Rupp else high = nrow; 544681824310SBarry Smith lastcol = col; 544781824310SBarry Smith while (high-low > 5) { 544881824310SBarry Smith t = (low+high)/2; 544981824310SBarry Smith if (rp[t] > col) high = t; 545081824310SBarry Smith else low = t; 545181824310SBarry Smith } 545281824310SBarry Smith for (i=low; i<high; i++) { 545381824310SBarry Smith if (rp[i] > col) break; 545481824310SBarry Smith if (rp[i] == col) { 545581824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 545681824310SBarry Smith else ap[i] = value; 545781824310SBarry Smith goto noinsert; 545881824310SBarry Smith } 545981824310SBarry Smith } 546081824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 546181824310SBarry Smith if (nonew == 1) goto noinsert; 5462ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5463fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 546481824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 546581824310SBarry Smith /* shift up all the later entries in this row */ 546681824310SBarry Smith for (ii=N; ii>=i; ii--) { 546781824310SBarry Smith rp[ii+1] = rp[ii]; 546881824310SBarry Smith ap[ii+1] = ap[ii]; 546981824310SBarry Smith } 547081824310SBarry Smith rp[i] = col; 547181824310SBarry Smith ap[i] = value; 5472e56f5c9eSBarry Smith A->nonzerostate++; 547381824310SBarry Smith noinsert:; 547481824310SBarry Smith low = i + 1; 547581824310SBarry Smith } 547681824310SBarry Smith ailen[row] = nrow; 547781824310SBarry Smith } 547881824310SBarry Smith PetscFunctionReturnVoid(); 547981824310SBarry Smith } 5480