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; 956ce1633cSBarry Smith const MatScalar *aa = a->a; 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; 1026ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1036ce1633cSBarry Smith diag = a->diag; 1046ce1633cSBarry Smith for (i=0; i<m; i++) { 105b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1066ce1633cSBarry Smith cnt++; 1076ce1633cSBarry Smith } 1086ce1633cSBarry Smith } 109785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1106ce1633cSBarry Smith cnt = 0; 1116ce1633cSBarry Smith for (i=0; i<m; i++) { 112b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1136ce1633cSBarry Smith rows[cnt++] = i; 1146ce1633cSBarry Smith } 1156ce1633cSBarry Smith } 116f1f41ecbSJed Brown *nrows = cnt; 117f1f41ecbSJed Brown *zrows = rows; 118f1f41ecbSJed Brown PetscFunctionReturn(0); 119f1f41ecbSJed Brown } 120f1f41ecbSJed Brown 121f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 122f1f41ecbSJed Brown { 123f1f41ecbSJed Brown PetscInt nrows,*rows; 124f1f41ecbSJed Brown PetscErrorCode ierr; 125f1f41ecbSJed Brown 126f1f41ecbSJed Brown PetscFunctionBegin; 1270298fd71SBarry Smith *zrows = NULL; 128f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 129ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1306ce1633cSBarry Smith PetscFunctionReturn(0); 1316ce1633cSBarry Smith } 1326ce1633cSBarry Smith 133b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 134b3a44c85SBarry Smith { 135b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 136b3a44c85SBarry Smith const MatScalar *aa; 137b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 138b3a44c85SBarry Smith const PetscInt *ii; 139b3a44c85SBarry Smith PetscInt n,i,j,*rows; 140b3a44c85SBarry Smith PetscErrorCode ierr; 141b3a44c85SBarry Smith 142b3a44c85SBarry Smith PetscFunctionBegin; 1432e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 144f4259b30SLisandro Dalcin *keptrows = NULL; 145b3a44c85SBarry Smith ii = a->i; 146b3a44c85SBarry Smith for (i=0; i<m; i++) { 147b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 148b3a44c85SBarry Smith if (!n) { 149b3a44c85SBarry Smith cnt++; 150b3a44c85SBarry Smith goto ok1; 151b3a44c85SBarry Smith } 1522e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 153b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 154b3a44c85SBarry Smith } 155b3a44c85SBarry Smith cnt++; 156b3a44c85SBarry Smith ok1:; 157b3a44c85SBarry Smith } 1582e5835c6SStefano Zampini if (!cnt) { 1592e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 1602e5835c6SStefano Zampini PetscFunctionReturn(0); 1612e5835c6SStefano Zampini } 162854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 163b3a44c85SBarry Smith cnt = 0; 164b3a44c85SBarry Smith for (i=0; i<m; i++) { 165b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 166b3a44c85SBarry Smith if (!n) continue; 1672e5835c6SStefano Zampini for (j=ii[i]; j<ii[i+1]; j++) { 168b3a44c85SBarry Smith if (aa[j] != 0.0) { 169b3a44c85SBarry Smith rows[cnt++] = i; 170b3a44c85SBarry Smith break; 171b3a44c85SBarry Smith } 172b3a44c85SBarry Smith } 173b3a44c85SBarry Smith } 1742e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 175b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 176b3a44c85SBarry Smith PetscFunctionReturn(0); 177b3a44c85SBarry Smith } 178b3a44c85SBarry Smith 1797087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 18079299369SBarry Smith { 18179299369SBarry Smith PetscErrorCode ierr; 18279299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 18399e65526SBarry Smith PetscInt i,m = Y->rmap->n; 18499e65526SBarry Smith const PetscInt *diag; 1852e5835c6SStefano Zampini MatScalar *aa; 18699e65526SBarry Smith const PetscScalar *v; 187ace3abfcSBarry Smith PetscBool missing; 1888c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 189837a59e1SRichard Tran Mills PetscBool inserted = PETSC_FALSE; 190837a59e1SRichard Tran Mills #endif 19179299369SBarry Smith 19279299369SBarry Smith PetscFunctionBegin; 19309f38230SBarry Smith if (Y->assembled) { 1940298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 19509f38230SBarry Smith if (!missing) { 19679299369SBarry Smith diag = aij->diag; 19799e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 1982e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&aa);CHKERRQ(ierr); 19979299369SBarry Smith if (is == INSERT_VALUES) { 2008c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 201837a59e1SRichard Tran Mills inserted = PETSC_TRUE; 202837a59e1SRichard Tran Mills #endif 20379299369SBarry Smith for (i=0; i<m; i++) { 20479299369SBarry Smith aa[diag[i]] = v[i]; 20579299369SBarry Smith } 20679299369SBarry Smith } else { 20779299369SBarry Smith for (i=0; i<m; i++) { 2088c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 209837a59e1SRichard Tran Mills if (v[i] != 0.0) inserted = PETSC_TRUE; 210837a59e1SRichard Tran Mills #endif 21179299369SBarry Smith aa[diag[i]] += v[i]; 21279299369SBarry Smith } 21379299369SBarry Smith } 2142e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&aa);CHKERRQ(ierr); 2158c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 216837a59e1SRichard Tran Mills if (inserted) Y->offloadmask = PETSC_OFFLOAD_CPU; 217837a59e1SRichard Tran Mills #endif 21899e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 21979299369SBarry Smith PetscFunctionReturn(0); 22079299369SBarry Smith } 221acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 22209f38230SBarry Smith } 22309f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 22409f38230SBarry Smith PetscFunctionReturn(0); 22509f38230SBarry Smith } 22679299369SBarry Smith 2271a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 22817ab2063SBarry Smith { 229416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 230dfbe8321SBarry Smith PetscErrorCode ierr; 23197f1f81fSBarry Smith PetscInt i,ishift; 23217ab2063SBarry Smith 2333a40ed3dSBarry Smith PetscFunctionBegin; 234d0f46423SBarry Smith *m = A->rmap->n; 2353a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 236bfeeae90SHong Zhang ishift = 0; 23753e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2382462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 239bfeeae90SHong Zhang } else if (oshift == 1) { 2401a83f524SJed Brown PetscInt *tia; 241d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2423b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 243854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2441a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2451a83f524SJed Brown *ia = tia; 246ecc77c7aSBarry Smith if (ja) { 2471a83f524SJed Brown PetscInt *tja; 248854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2491a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2501a83f524SJed Brown *ja = tja; 251ecc77c7aSBarry Smith } 2526945ee14SBarry Smith } else { 253ecc77c7aSBarry Smith *ia = a->i; 254ecc77c7aSBarry Smith if (ja) *ja = a->j; 255a2ce50c7SBarry Smith } 2563a40ed3dSBarry Smith PetscFunctionReturn(0); 257a2744918SBarry Smith } 258a2744918SBarry Smith 2591a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2606945ee14SBarry Smith { 261dfbe8321SBarry Smith PetscErrorCode ierr; 2626945ee14SBarry Smith 2633a40ed3dSBarry Smith PetscFunctionBegin; 2643a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 265bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 266606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 267ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 268bcd2baecSBarry Smith } 2693a40ed3dSBarry Smith PetscFunctionReturn(0); 27017ab2063SBarry Smith } 27117ab2063SBarry Smith 2721a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2733b2fbd54SBarry Smith { 2743b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 275dfbe8321SBarry Smith PetscErrorCode ierr; 276d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 27797f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2783b2fbd54SBarry Smith 2793a40ed3dSBarry Smith PetscFunctionBegin; 280899cda47SBarry Smith *nn = n; 2813a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2823b2fbd54SBarry Smith if (symmetric) { 2832462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2843b2fbd54SBarry Smith } else { 285b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 286854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 287b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2883b2fbd54SBarry Smith jj = a->j; 2893b2fbd54SBarry Smith for (i=0; i<nz; i++) { 290bfeeae90SHong Zhang collengths[jj[i]]++; 2913b2fbd54SBarry Smith } 2923b2fbd54SBarry Smith cia[0] = oshift; 2933b2fbd54SBarry Smith for (i=0; i<n; i++) { 2943b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2953b2fbd54SBarry Smith } 296580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2973b2fbd54SBarry Smith jj = a->j; 298a93ec695SBarry Smith for (row=0; row<m; row++) { 299a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 300a93ec695SBarry Smith for (i=0; i<mr; i++) { 301bfeeae90SHong Zhang col = *jj++; 3022205254eSKarl Rupp 3033b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 3043b2fbd54SBarry Smith } 3053b2fbd54SBarry Smith } 306606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 3073b2fbd54SBarry Smith *ia = cia; *ja = cja; 3083b2fbd54SBarry Smith } 3093a40ed3dSBarry Smith PetscFunctionReturn(0); 3103b2fbd54SBarry Smith } 3113b2fbd54SBarry Smith 3121a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 3133b2fbd54SBarry Smith { 314dfbe8321SBarry Smith PetscErrorCode ierr; 315606d414cSSatish Balay 3163a40ed3dSBarry Smith PetscFunctionBegin; 3173a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 3183b2fbd54SBarry Smith 319606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 320606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3213a40ed3dSBarry Smith PetscFunctionReturn(0); 3223b2fbd54SBarry Smith } 3233b2fbd54SBarry Smith 3247cee066cSHong Zhang /* 3257cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3267cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 327040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3287cee066cSHong Zhang */ 3297cee066cSHong 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) 3307cee066cSHong Zhang { 3317cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3327cee066cSHong Zhang PetscErrorCode ierr; 3337cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 334071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3357cee066cSHong Zhang PetscInt *cspidx; 336071fcb05SBarry Smith const PetscInt *jj; 3377cee066cSHong Zhang 3387cee066cSHong Zhang PetscFunctionBegin; 3397cee066cSHong Zhang *nn = n; 3407cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 341625f6d37SHong Zhang 342b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 343854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 344b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 345b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3467cee066cSHong Zhang jj = a->j; 3477cee066cSHong Zhang for (i=0; i<nz; i++) { 3487cee066cSHong Zhang collengths[jj[i]]++; 3497cee066cSHong Zhang } 3507cee066cSHong Zhang cia[0] = oshift; 3517cee066cSHong Zhang for (i=0; i<n; i++) { 3527cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3537cee066cSHong Zhang } 354580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3557cee066cSHong Zhang jj = a->j; 3567cee066cSHong Zhang for (row=0; row<m; row++) { 3577cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3587cee066cSHong Zhang for (i=0; i<mr; i++) { 3597cee066cSHong Zhang col = *jj++; 360071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 361071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 362071fcb05SBarry Smith cja[tmp] = row + oshift; 3637cee066cSHong Zhang } 3647cee066cSHong Zhang } 3657cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 366071fcb05SBarry Smith *ia = cia; 367071fcb05SBarry Smith *ja = cja; 3687cee066cSHong Zhang *spidx = cspidx; 3697cee066cSHong Zhang PetscFunctionReturn(0); 3707cee066cSHong Zhang } 3717cee066cSHong Zhang 3727cee066cSHong 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) 3737cee066cSHong Zhang { 3747cee066cSHong Zhang PetscErrorCode ierr; 3757cee066cSHong Zhang 3767cee066cSHong Zhang PetscFunctionBegin; 3775243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3787cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3797cee066cSHong Zhang PetscFunctionReturn(0); 3807cee066cSHong Zhang } 3817cee066cSHong Zhang 38287d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 38387d4246cSBarry Smith { 38487d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 38587d4246cSBarry Smith PetscInt *ai = a->i; 38687d4246cSBarry Smith PetscErrorCode ierr; 38787d4246cSBarry Smith 38887d4246cSBarry Smith PetscFunctionBegin; 389580bdb30SBarry Smith ierr = PetscArraycpy(a->a+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 3908c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 391c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && ai[row+1]-ai[row]) A->offloadmask = PETSC_OFFLOAD_CPU; 392e2cf4d64SStefano Zampini #endif 39387d4246cSBarry Smith PetscFunctionReturn(0); 39487d4246cSBarry Smith } 39587d4246cSBarry Smith 396bd04181cSBarry Smith /* 397bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 398bd04181cSBarry Smith 399bd04181cSBarry Smith - a single row of values is set with each call 400bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 401bd04181cSBarry Smith - the values are always added to the matrix, not set 402bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 403bd04181cSBarry Smith 4041f763a69SBarry Smith This does NOT assume the global column indices are sorted 405bd04181cSBarry Smith 4061f763a69SBarry Smith */ 407bd04181cSBarry Smith 408af0996ceSBarry Smith #include <petsc/private/isimpl.h> 409189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 410189e4007SBarry Smith { 411189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4121f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 4131f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 4141f763a69SBarry Smith PetscInt lastcol = -1; 415189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 416189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 417189e4007SBarry Smith 418f38dd0b8SBarry Smith row = ridx[im[0]]; 4191f763a69SBarry Smith rp = aj + ai[row]; 4201f763a69SBarry Smith ap = aa + ai[row]; 4211f763a69SBarry Smith nrow = ailen[row]; 422189e4007SBarry Smith low = 0; 423189e4007SBarry Smith high = nrow; 424189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 425189e4007SBarry Smith col = cidx[in[l]]; 426f38dd0b8SBarry Smith value = v[l]; 427189e4007SBarry Smith 428189e4007SBarry Smith if (col <= lastcol) low = 0; 429189e4007SBarry Smith else high = nrow; 430189e4007SBarry Smith lastcol = col; 431189e4007SBarry Smith while (high-low > 5) { 432189e4007SBarry Smith t = (low+high)/2; 433189e4007SBarry Smith if (rp[t] > col) high = t; 434189e4007SBarry Smith else low = t; 435189e4007SBarry Smith } 436189e4007SBarry Smith for (i=low; i<high; i++) { 437189e4007SBarry Smith if (rp[i] == col) { 4381f763a69SBarry Smith ap[i] += value; 439189e4007SBarry Smith low = i + 1; 4401f763a69SBarry Smith break; 441189e4007SBarry Smith } 442189e4007SBarry Smith } 443189e4007SBarry Smith } 4448c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 445c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 446e2cf4d64SStefano Zampini #endif 447f38dd0b8SBarry Smith return 0; 448189e4007SBarry Smith } 449189e4007SBarry Smith 45097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 45117ab2063SBarry Smith { 452416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 453e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 45497f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4556849ba73SBarry Smith PetscErrorCode ierr; 456e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 457ce496241SStefano Zampini MatScalar *ap=NULL,value=0.0,*aa; 458ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 459ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 4608c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 461e2cf4d64SStefano Zampini PetscBool inserted = PETSC_FALSE; 462e2cf4d64SStefano Zampini #endif 46317ab2063SBarry Smith 4643a40ed3dSBarry Smith PetscFunctionBegin; 465ce496241SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 466ce496241SStefano Zampini if (A->offloadmask == PETSC_OFFLOAD_GPU) { 467ce496241SStefano Zampini const PetscScalar *dummy; 468ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&dummy);CHKERRQ(ierr); 469ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&dummy);CHKERRQ(ierr); 470ce496241SStefano Zampini } 471ce496241SStefano Zampini #endif 472ce496241SStefano Zampini aa = a->a; 47317ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 474416022c9SBarry Smith row = im[k]; 4755ef9f2a5SBarry Smith if (row < 0) continue; 476cf9c20a2SJed 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); 477720833daSHong Zhang rp = aj + ai[row]; 478876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 47917ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 480416022c9SBarry Smith low = 0; 481c71e6ed7SBarry Smith high = nrow; 48217ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4835ef9f2a5SBarry Smith if (in[l] < 0) continue; 484cf9c20a2SJed 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); 485bfeeae90SHong Zhang col = in[l]; 486071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 487071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 48836db0b34SBarry Smith 4892205254eSKarl Rupp if (col <= lastcol) low = 0; 4902205254eSKarl Rupp else high = nrow; 491e2ee6c50SBarry Smith lastcol = col; 492416022c9SBarry Smith while (high-low > 5) { 493416022c9SBarry Smith t = (low+high)/2; 494416022c9SBarry Smith if (rp[t] > col) high = t; 495416022c9SBarry Smith else low = t; 49617ab2063SBarry Smith } 497416022c9SBarry Smith for (i=low; i<high; i++) { 49817ab2063SBarry Smith if (rp[i] > col) break; 49917ab2063SBarry Smith if (rp[i] == col) { 500876c6284SHong Zhang if (!A->structure_only) { 5010c0d7e18SFande Kong if (is == ADD_VALUES) { 5020c0d7e18SFande Kong ap[i] += value; 5030c0d7e18SFande Kong (void)PetscLogFlops(1.0); 5040c0d7e18SFande Kong } 50517ab2063SBarry Smith else ap[i] = value; 5068c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 507e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 508e2cf4d64SStefano Zampini #endif 509720833daSHong Zhang } 510e44c0bd4SBarry Smith low = i + 1; 51117ab2063SBarry Smith goto noinsert; 51217ab2063SBarry Smith } 51317ab2063SBarry Smith } 514dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 515c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 516e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 517720833daSHong Zhang if (A->structure_only) { 518876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 519720833daSHong Zhang } else { 520fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 521720833daSHong Zhang } 522c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 523416022c9SBarry Smith /* shift up all the later entries in this row */ 524580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 52517ab2063SBarry Smith rp[i] = col; 526580bdb30SBarry Smith if (!A->structure_only) { 527580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 528580bdb30SBarry Smith ap[i] = value; 529580bdb30SBarry Smith } 530416022c9SBarry Smith low = i + 1; 531e56f5c9eSBarry Smith A->nonzerostate++; 5328c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 533e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 534e2cf4d64SStefano Zampini #endif 535e44c0bd4SBarry Smith noinsert:; 53617ab2063SBarry Smith } 53717ab2063SBarry Smith ailen[row] = nrow; 53817ab2063SBarry Smith } 5398c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 540c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 541e2cf4d64SStefano Zampini #endif 5423a40ed3dSBarry Smith PetscFunctionReturn(0); 54317ab2063SBarry Smith } 54417ab2063SBarry Smith 54519b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 54619b08ed1SBarry Smith { 54719b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 54819b08ed1SBarry Smith PetscInt *rp,k,row; 54919b08ed1SBarry Smith PetscInt *ai = a->i; 55019b08ed1SBarry Smith PetscErrorCode ierr; 55119b08ed1SBarry Smith PetscInt *aj = a->j; 55219b08ed1SBarry Smith MatScalar *aa = a->a,*ap; 55319b08ed1SBarry Smith 55419b08ed1SBarry Smith PetscFunctionBegin; 55519b08ed1SBarry Smith if (A->was_assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 55619b08ed1SBarry 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); 55719b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 55819b08ed1SBarry Smith row = im[k]; 55919b08ed1SBarry Smith rp = aj + ai[row]; 56019b08ed1SBarry Smith ap = aa + ai[row]; 56119b08ed1SBarry Smith 56219b08ed1SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 56319b08ed1SBarry Smith if (!A->structure_only) { 56419b08ed1SBarry Smith if (v) { 56519b08ed1SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 56619b08ed1SBarry Smith v += n; 56719b08ed1SBarry Smith } else { 56819b08ed1SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 56919b08ed1SBarry Smith } 57019b08ed1SBarry Smith } 57119b08ed1SBarry Smith a->ilen[row] = n; 57219b08ed1SBarry Smith a->imax[row] = n; 57319b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 57419b08ed1SBarry Smith a->nz += n; 57519b08ed1SBarry Smith } 5768c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 57719b08ed1SBarry Smith if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 57819b08ed1SBarry Smith #endif 57919b08ed1SBarry Smith PetscFunctionReturn(0); 58019b08ed1SBarry Smith } 58119b08ed1SBarry Smith 58219b08ed1SBarry Smith /*@ 58319b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 58419b08ed1SBarry Smith 58519b08ed1SBarry Smith Input Parameters: 58619b08ed1SBarry Smith + A - the SeqAIJ matrix 58719b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 58819b08ed1SBarry Smith 58919b08ed1SBarry Smith Level: advanced 59019b08ed1SBarry Smith 59119b08ed1SBarry Smith Notes: 59219b08ed1SBarry 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. 59319b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 59419b08ed1SBarry Smith as always with multiple matrix assemblies. 59519b08ed1SBarry Smith 59619b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 59719b08ed1SBarry Smith @*/ 59819b08ed1SBarry Smith 59919b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 60019b08ed1SBarry Smith { 60119b08ed1SBarry Smith PetscErrorCode ierr; 60219b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 60319b08ed1SBarry Smith 60419b08ed1SBarry Smith PetscFunctionBegin; 60519b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 60619b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 60719b08ed1SBarry Smith a->maxnz = nztotal; 60819b08ed1SBarry Smith if (!a->imax) { 60919b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr); 61019b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 61119b08ed1SBarry Smith } 61219b08ed1SBarry Smith if (!a->ilen) { 61319b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr); 61419b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 61519b08ed1SBarry Smith } else { 61619b08ed1SBarry Smith ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 61719b08ed1SBarry Smith } 61819b08ed1SBarry Smith 61919b08ed1SBarry Smith /* allocate the matrix space */ 62019b08ed1SBarry Smith if (A->structure_only) { 62119b08ed1SBarry Smith ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr); 62219b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr); 62319b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr); 62419b08ed1SBarry Smith } else { 62519b08ed1SBarry Smith ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr); 62619b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 62719b08ed1SBarry Smith } 62819b08ed1SBarry Smith a->i[0] = 0; 62919b08ed1SBarry Smith if (A->structure_only) { 63019b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 63119b08ed1SBarry Smith a->free_a = PETSC_FALSE; 63219b08ed1SBarry Smith } else { 63319b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 63419b08ed1SBarry Smith a->free_a = PETSC_TRUE; 63519b08ed1SBarry Smith } 63619b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 63719b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 63819b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 63919b08ed1SBarry Smith PetscFunctionReturn(0); 64019b08ed1SBarry Smith } 64119b08ed1SBarry Smith 642071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 643071fcb05SBarry Smith { 644071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 645071fcb05SBarry Smith PetscInt *rp,k,row; 646071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 647071fcb05SBarry Smith PetscErrorCode ierr; 648071fcb05SBarry Smith PetscInt *aj = a->j; 649071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 650071fcb05SBarry Smith 651071fcb05SBarry Smith PetscFunctionBegin; 652071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 653071fcb05SBarry Smith row = im[k]; 65419b08ed1SBarry 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); 655071fcb05SBarry Smith rp = aj + ai[row]; 656071fcb05SBarry Smith ap = aa + ai[row]; 657071fcb05SBarry Smith if (!A->was_assembled) { 658071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 659071fcb05SBarry Smith } 660071fcb05SBarry Smith if (!A->structure_only) { 661071fcb05SBarry Smith if (v) { 662071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 663071fcb05SBarry Smith v += n; 664071fcb05SBarry Smith } else { 665071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 666071fcb05SBarry Smith } 667071fcb05SBarry Smith } 668071fcb05SBarry Smith ailen[row] = n; 669071fcb05SBarry Smith a->nz += n; 670071fcb05SBarry Smith } 6718c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 672c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 673e2cf4d64SStefano Zampini #endif 674071fcb05SBarry Smith PetscFunctionReturn(0); 675071fcb05SBarry Smith } 676071fcb05SBarry Smith 677a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6787eb43aa7SLois Curfman McInnes { 6797eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 68097f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 68197f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 68254f21887SBarry Smith MatScalar *ap,*aa = a->a; 6837eb43aa7SLois Curfman McInnes 6843a40ed3dSBarry Smith PetscFunctionBegin; 6857eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6867eb43aa7SLois Curfman McInnes row = im[k]; 687e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 688e32f2f54SBarry 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); 689bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6907eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6917eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 692e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 693e32f2f54SBarry 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); 694bfeeae90SHong Zhang col = in[l]; 6957eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6967eb43aa7SLois Curfman McInnes while (high-low > 5) { 6977eb43aa7SLois Curfman McInnes t = (low+high)/2; 6987eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6997eb43aa7SLois Curfman McInnes else low = t; 7007eb43aa7SLois Curfman McInnes } 7017eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 7027eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 7037eb43aa7SLois Curfman McInnes if (rp[i] == col) { 704b49de8d1SLois Curfman McInnes *v++ = ap[i]; 7057eb43aa7SLois Curfman McInnes goto finished; 7067eb43aa7SLois Curfman McInnes } 7077eb43aa7SLois Curfman McInnes } 70897e567efSBarry Smith *v++ = 0.0; 7097eb43aa7SLois Curfman McInnes finished:; 7107eb43aa7SLois Curfman McInnes } 7117eb43aa7SLois Curfman McInnes } 7123a40ed3dSBarry Smith PetscFunctionReturn(0); 7137eb43aa7SLois Curfman McInnes } 7147eb43aa7SLois Curfman McInnes 7153ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 71617ab2063SBarry Smith { 7173ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 718c898d852SStefano Zampini const PetscScalar *av; 7193ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 7203ea6fe3dSLisandro Dalcin PetscInt *rowlens; 7216849ba73SBarry Smith PetscErrorCode ierr; 72217ab2063SBarry Smith 7233a40ed3dSBarry Smith PetscFunctionBegin; 7243ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7252205254eSKarl Rupp 7263ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7273ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7283ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7293ea6fe3dSLisandro Dalcin nz = A->nz; 730416022c9SBarry Smith 7313ea6fe3dSLisandro Dalcin /* write matrix header */ 7323ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7333ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7343ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 735416022c9SBarry Smith 7363ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7373ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7383ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7393ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7403ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7413ea6fe3dSLisandro Dalcin /* store column indices */ 7423ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 743416022c9SBarry Smith /* store nonzero values */ 744c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr); 745c898d852SStefano Zampini ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr); 746c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr); 747b37d52dbSMark F. Adams 7483ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7493ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7503a40ed3dSBarry Smith PetscFunctionReturn(0); 75117ab2063SBarry Smith } 752416022c9SBarry Smith 7537dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7547dc0baabSHong Zhang { 7557dc0baabSHong Zhang PetscErrorCode ierr; 7567dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7577dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7587dc0baabSHong Zhang 7597dc0baabSHong Zhang PetscFunctionBegin; 7607dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7617dc0baabSHong Zhang for (i=0; i<m; i++) { 7627dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7637dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7647dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7657dc0baabSHong Zhang } 7667dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7677dc0baabSHong Zhang } 7687dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7697dc0baabSHong Zhang PetscFunctionReturn(0); 7707dc0baabSHong Zhang } 7717dc0baabSHong Zhang 77209573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 773cd155464SBarry Smith 774dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 775416022c9SBarry Smith { 776416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 777c898d852SStefano Zampini const PetscScalar *av; 778dfbe8321SBarry Smith PetscErrorCode ierr; 77960e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 780e060cb09SBarry Smith const char *name; 781f3ef73ceSBarry Smith PetscViewerFormat format; 78217ab2063SBarry Smith 7833a40ed3dSBarry Smith PetscFunctionBegin; 7847dc0baabSHong Zhang if (A->structure_only) { 7857dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7867dc0baabSHong Zhang PetscFunctionReturn(0); 7877dc0baabSHong Zhang } 78843e49210SHong Zhang 789b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 7902e5835c6SStefano Zampini if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) PetscFunctionReturn(0); 7912e5835c6SStefano Zampini 792c898d852SStefano Zampini /* trigger copy to CPU if needed */ 793c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 794c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 79571c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 79697f1f81fSBarry Smith PetscInt nofinalvalue = 0; 79760e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 798c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 799d00d2cf4SBarry Smith nofinalvalue = 1; 800d00d2cf4SBarry Smith } 801d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 802d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 80377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 804fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 805fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 806fbfe6fa7SJed Brown #else 80777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 808fbfe6fa7SJed Brown #endif 809b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 81017ab2063SBarry Smith 81117ab2063SBarry Smith for (i=0; i<m; i++) { 81260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 813aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 814a9bf72d8SJed 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); 81517ab2063SBarry Smith #else 81660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 81717ab2063SBarry Smith #endif 81817ab2063SBarry Smith } 81917ab2063SBarry Smith } 820d00d2cf4SBarry Smith if (nofinalvalue) { 821c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 822c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 823c337ccceSJed Brown #else 824d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 825c337ccceSJed Brown #endif 826d00d2cf4SBarry Smith } 827317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 828fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 829d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 830fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 831d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 83244cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 83377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 83460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 835aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 83636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 83760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 83836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 83960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 84036db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 84160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8426831982aSBarry Smith } 84344cd7ae7SLois Curfman McInnes #else 84460e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 84544cd7ae7SLois Curfman McInnes #endif 84644cd7ae7SLois Curfman McInnes } 847b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 84844cd7ae7SLois Curfman McInnes } 849d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 850fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 85197f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 852d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 853854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 854496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 855496be53dSLois Curfman McInnes sptr[i] = nzd+1; 85660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 857496be53dSLois Curfman McInnes if (a->j[j] >= i) { 858aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 85936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 860496be53dSLois Curfman McInnes #else 861496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 862496be53dSLois Curfman McInnes #endif 863496be53dSLois Curfman McInnes } 864496be53dSLois Curfman McInnes } 865496be53dSLois Curfman McInnes } 8662e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 86777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8682e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8692205254eSKarl Rupp if (i+4<m) { 8702205254eSKarl 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); 8712205254eSKarl Rupp } else if (i+3<m) { 8722205254eSKarl 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); 8732205254eSKarl Rupp } else if (i+2<m) { 8742205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8752205254eSKarl Rupp } else if (i+1<m) { 8762205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8772205254eSKarl Rupp } else if (i<m) { 8782205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8792205254eSKarl Rupp } else { 8802205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8812205254eSKarl Rupp } 882496be53dSLois Curfman McInnes } 883b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 884606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 885496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 88660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 88777431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 888496be53dSLois Curfman McInnes } 889b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 890496be53dSLois Curfman McInnes } 891b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 892496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 89360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 894496be53dSLois Curfman McInnes if (a->j[j] >= i) { 895aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 89636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 89760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8986831982aSBarry Smith } 899496be53dSLois Curfman McInnes #else 90060e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 901496be53dSLois Curfman McInnes #endif 902496be53dSLois Curfman McInnes } 903496be53dSLois Curfman McInnes } 904b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 905496be53dSLois Curfman McInnes } 906d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 907fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 90897f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 90987828ca2SBarry Smith PetscScalar value; 91068f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 91168f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 91268f1ed48SBarry Smith 91368f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 91468f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 91568f1ed48SBarry Smith realonly = PETSC_FALSE; 91668f1ed48SBarry Smith break; 91768f1ed48SBarry Smith } 91868f1ed48SBarry Smith } 91968f1ed48SBarry Smith #endif 92002594712SBarry Smith 921d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 92202594712SBarry Smith for (i=0; i<m; i++) { 92302594712SBarry Smith jcnt = 0; 924d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 925e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 92602594712SBarry Smith value = a->a[cnt++]; 927e24b481bSBarry Smith jcnt++; 92802594712SBarry Smith } else { 92902594712SBarry Smith value = 0.0; 93002594712SBarry Smith } 931aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 93268f1ed48SBarry Smith if (realonly) { 93360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 93468f1ed48SBarry Smith } else { 93560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 93668f1ed48SBarry Smith } 93702594712SBarry Smith #else 93860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 93902594712SBarry Smith #endif 94002594712SBarry Smith } 941b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 94202594712SBarry Smith } 943d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9443c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 945150b93efSMatthew G. Knepley PetscInt fshift=1; 946d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9473c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 94819303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9493c215bfdSMatthew Knepley #else 95019303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9513c215bfdSMatthew Knepley #endif 952d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9533c215bfdSMatthew Knepley for (i=0; i<m; i++) { 95460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9553c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 956a9a0e077SKarl 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); 9573c215bfdSMatthew Knepley #else 958150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9593c215bfdSMatthew Knepley #endif 9603c215bfdSMatthew Knepley } 9613c215bfdSMatthew Knepley } 962d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9633a40ed3dSBarry Smith } else { 964d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 965d5f3da31SBarry Smith if (A->factortype) { 96616cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 96716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 96816cd7e1dSShri Abhyankar /* L part */ 96960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 97016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 97260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 97316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9746712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 97516cd7e1dSShri Abhyankar } else { 97660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 97716cd7e1dSShri Abhyankar } 97816cd7e1dSShri Abhyankar #else 97960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 98016cd7e1dSShri Abhyankar #endif 98116cd7e1dSShri Abhyankar } 98216cd7e1dSShri Abhyankar /* diagonal */ 98316cd7e1dSShri Abhyankar j = a->diag[i]; 98416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 98516cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 98660e0710aSBarry 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); 98716cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9886712e2f1SBarry 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); 98916cd7e1dSShri Abhyankar } else { 99060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 99116cd7e1dSShri Abhyankar } 99216cd7e1dSShri Abhyankar #else 99360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 99416cd7e1dSShri Abhyankar #endif 99516cd7e1dSShri Abhyankar 99616cd7e1dSShri Abhyankar /* U part */ 99760e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 99816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 99916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 100060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 100116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 100222ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 100316cd7e1dSShri Abhyankar } else { 100460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 100516cd7e1dSShri Abhyankar } 100616cd7e1dSShri Abhyankar #else 100760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 100816cd7e1dSShri Abhyankar #endif 100916cd7e1dSShri Abhyankar } 101016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 101116cd7e1dSShri Abhyankar } 101216cd7e1dSShri Abhyankar } else { 101317ab2063SBarry Smith for (i=0; i<m; i++) { 101477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 101560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 1016aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 101736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 101860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 101936db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 102060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 10213a40ed3dSBarry Smith } else { 102260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 102317ab2063SBarry Smith } 102417ab2063SBarry Smith #else 102560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 102617ab2063SBarry Smith #endif 102717ab2063SBarry Smith } 1028b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 102917ab2063SBarry Smith } 103016cd7e1dSShri Abhyankar } 1031d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 103217ab2063SBarry Smith } 1033b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10343a40ed3dSBarry Smith PetscFunctionReturn(0); 1035416022c9SBarry Smith } 1036416022c9SBarry Smith 10379804daf3SBarry Smith #include <petscdraw.h> 1038dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1039416022c9SBarry Smith { 1040480ef9eaSBarry Smith Mat A = (Mat) Aa; 1041416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1042dfbe8321SBarry Smith PetscErrorCode ierr; 1043383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1044383922c3SLisandro Dalcin int color; 1045b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1046b0a32e0cSBarry Smith PetscViewer viewer; 1047f3ef73ceSBarry Smith PetscViewerFormat format; 1048cddf8d76SBarry Smith 10493a40ed3dSBarry Smith PetscFunctionBegin; 1050480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1051b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1052b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1053383922c3SLisandro Dalcin 1054416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10550513a670SBarry Smith 1056fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1057383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10580513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1059b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1060416022c9SBarry Smith for (i=0; i<m; i++) { 1061cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1062bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1063bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 106436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 1065b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1066cddf8d76SBarry Smith } 1067cddf8d76SBarry Smith } 1068b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1069cddf8d76SBarry Smith for (i=0; i<m; i++) { 1070cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1071bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1072bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1073cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 1074b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1075cddf8d76SBarry Smith } 1076cddf8d76SBarry Smith } 1077b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1078cddf8d76SBarry Smith for (i=0; i<m; i++) { 1079cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1080bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1081bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 108236db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 1083b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1084416022c9SBarry Smith } 1085416022c9SBarry Smith } 1086383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10870513a670SBarry Smith } else { 10880513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10890513a670SBarry Smith /* first determine max of all nonzero values */ 1090b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1091383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1092b0a32e0cSBarry Smith PetscDraw popup; 10930513a670SBarry Smith 10940513a670SBarry Smith for (i=0; i<nz; i++) { 10950513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 10960513a670SBarry Smith } 1097383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1098b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 109945f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1100383922c3SLisandro Dalcin 1101383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 11020513a670SBarry Smith for (i=0; i<m; i++) { 1103383922c3SLisandro Dalcin y_l = m - i - 1.0; 1104383922c3SLisandro Dalcin y_r = y_l + 1.0; 1105bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1106383922c3SLisandro Dalcin x_l = a->j[j]; 1107383922c3SLisandro Dalcin x_r = x_l + 1.0; 1108b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 1109b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 11100513a670SBarry Smith count++; 11110513a670SBarry Smith } 11120513a670SBarry Smith } 1113383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 11140513a670SBarry Smith } 1115480ef9eaSBarry Smith PetscFunctionReturn(0); 1116480ef9eaSBarry Smith } 1117cddf8d76SBarry Smith 11189804daf3SBarry Smith #include <petscdraw.h> 1119dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1120480ef9eaSBarry Smith { 1121dfbe8321SBarry Smith PetscErrorCode ierr; 1122b0a32e0cSBarry Smith PetscDraw draw; 112336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1124ace3abfcSBarry Smith PetscBool isnull; 1125480ef9eaSBarry Smith 1126480ef9eaSBarry Smith PetscFunctionBegin; 1127b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1128b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1129480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1130480ef9eaSBarry Smith 1131d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1132480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1133b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1134832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1135b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11360298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1137832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11383a40ed3dSBarry Smith PetscFunctionReturn(0); 1139416022c9SBarry Smith } 1140416022c9SBarry Smith 1141dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1142416022c9SBarry Smith { 1143dfbe8321SBarry Smith PetscErrorCode ierr; 1144ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1145416022c9SBarry Smith 11463a40ed3dSBarry Smith PetscFunctionBegin; 1147251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1148251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1149251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1150c45a1595SBarry Smith if (iascii) { 11513a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11520f5bd95cSBarry Smith } else if (isbinary) { 11533a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11540f5bd95cSBarry Smith } else if (isdraw) { 11553a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 115611aeaf0aSBarry Smith } 11574108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11583a40ed3dSBarry Smith PetscFunctionReturn(0); 115917ab2063SBarry Smith } 116019bcc07fSBarry Smith 1161dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 116217ab2063SBarry Smith { 1163416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11646849ba73SBarry Smith PetscErrorCode ierr; 1165580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1166d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 116754f21887SBarry Smith MatScalar *aa = a->a,*ap; 11683447b6efSHong Zhang PetscReal ratio = 0.6; 116917ab2063SBarry Smith 11703a40ed3dSBarry Smith PetscFunctionBegin; 11713a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1172071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1173b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1174b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 1175b215bc84SStefano Zampini ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1176b215bc84SStefano Zampini PetscFunctionReturn(0); 1177b215bc84SStefano Zampini } 117817ab2063SBarry Smith 117943ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 118017ab2063SBarry Smith for (i=1; i<m; i++) { 1181416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 118217ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 118394a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 118417ab2063SBarry Smith if (fshift) { 1185bfeeae90SHong Zhang ip = aj + ai[i]; 1186bfeeae90SHong Zhang ap = aa + ai[i]; 118717ab2063SBarry Smith N = ailen[i]; 1188580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1189580bdb30SBarry Smith if (!A->structure_only) { 1190580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 119117ab2063SBarry Smith } 119217ab2063SBarry Smith } 119317ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 119417ab2063SBarry Smith } 119517ab2063SBarry Smith if (m) { 119617ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 119717ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 119817ab2063SBarry Smith } 11997b083b7cSBarry Smith 120017ab2063SBarry Smith /* reset ilen and imax for each row */ 12017b083b7cSBarry Smith a->nonzerorowcnt = 0; 1202396832f4SHong Zhang if (A->structure_only) { 1203071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1204071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1205396832f4SHong Zhang } else { /* !A->structure_only */ 120617ab2063SBarry Smith for (i=0; i<m; i++) { 120717ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 12087b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 120917ab2063SBarry Smith } 1210396832f4SHong Zhang } 1211bfeeae90SHong Zhang a->nz = ai[m]; 121265e19b50SBarry 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); 121317ab2063SBarry Smith 121409f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1215d0f46423SBarry 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); 1216ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1217ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 12182205254eSKarl Rupp 12198e58a170SBarry Smith A->info.mallocs += a->reallocs; 1220dd5f02e7SSatish Balay a->reallocs = 0; 12216712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 122236db0b34SBarry Smith a->rmax = rmax; 12234e220ebcSLois Curfman McInnes 1224396832f4SHong Zhang if (!A->structure_only) { 122511e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1226396832f4SHong Zhang } 12274108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 12283a40ed3dSBarry Smith PetscFunctionReturn(0); 122917ab2063SBarry Smith } 123017ab2063SBarry Smith 123199cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 123299cafbc1SBarry Smith { 123399cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 123499cafbc1SBarry Smith PetscInt i,nz = a->nz; 12352e5835c6SStefano Zampini MatScalar *aa; 1236acf2f550SJed Brown PetscErrorCode ierr; 123799cafbc1SBarry Smith 123899cafbc1SBarry Smith PetscFunctionBegin; 12392e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 124099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 12412e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1242acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12438c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1244c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1245e2cf4d64SStefano Zampini #endif 124699cafbc1SBarry Smith PetscFunctionReturn(0); 124799cafbc1SBarry Smith } 124899cafbc1SBarry Smith 124999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 125099cafbc1SBarry Smith { 125199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 125299cafbc1SBarry Smith PetscInt i,nz = a->nz; 12532e5835c6SStefano Zampini MatScalar *aa; 1254acf2f550SJed Brown PetscErrorCode ierr; 125599cafbc1SBarry Smith 125699cafbc1SBarry Smith PetscFunctionBegin; 12572e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 125899cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 12592e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 1260acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12618c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1262c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1263e2cf4d64SStefano Zampini #endif 126499cafbc1SBarry Smith PetscFunctionReturn(0); 126599cafbc1SBarry Smith } 126699cafbc1SBarry Smith 1267dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 126817ab2063SBarry Smith { 1269416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1270dfbe8321SBarry Smith PetscErrorCode ierr; 12713a40ed3dSBarry Smith 12723a40ed3dSBarry Smith PetscFunctionBegin; 1273580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1274acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12758c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1276c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1277e2cf4d64SStefano Zampini #endif 12783a40ed3dSBarry Smith PetscFunctionReturn(0); 127917ab2063SBarry Smith } 1280416022c9SBarry Smith 1281dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 128217ab2063SBarry Smith { 1283416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1284dfbe8321SBarry Smith PetscErrorCode ierr; 1285d5d45c9bSBarry Smith 12863a40ed3dSBarry Smith PetscFunctionBegin; 1287aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1288d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 128917ab2063SBarry Smith #endif 1290e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12916bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12926bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 129305b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1294d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1295071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1296071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1297846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 129871f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 129905b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 13006bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 130105b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1302cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1303a30b2313SHong Zhang 13044108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1305bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1306901853e0SKris Buschelman 13076718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 13086718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 13096718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 13106718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 13116718818eSStefano Zampini due to different matrix sizes */ 13126718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 13136718818eSStefano Zampini 1314f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1315bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1316bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1317bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1318bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1319bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1320bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 13214222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 13224222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1323e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1324fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 13254222ddf1SHong Zhang #endif 13263d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 13273d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 13283d0639e7SStefano Zampini #endif 13294222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1330af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1331af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1332af8000cdSHong Zhang #endif 1333d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1334d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1335d24d4204SJose E. Roman #endif 133663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 133763c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13384222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 133963c07aadSStefano Zampini #endif 1340b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1341c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1342c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1343bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1344bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1345846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1346bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1347bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13484222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13494222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13504222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 1351ad7e164aSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJKron_C",NULL);CHKERRQ(ierr); 13523a40ed3dSBarry Smith PetscFunctionReturn(0); 135317ab2063SBarry Smith } 135417ab2063SBarry Smith 1355ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 135617ab2063SBarry Smith { 1357416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13584846f1f5SKris Buschelman PetscErrorCode ierr; 13593a40ed3dSBarry Smith 13603a40ed3dSBarry Smith PetscFunctionBegin; 1361a65d3064SKris Buschelman switch (op) { 1362a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13634e0d8c25SBarry Smith a->roworiented = flg; 1364a65d3064SKris Buschelman break; 1365a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1366a9817697SBarry Smith a->keepnonzeropattern = flg; 1367a65d3064SKris Buschelman break; 1368512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1369512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1370a65d3064SKris Buschelman break; 1371a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13724e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1373a65d3064SKris Buschelman break; 1374a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13754e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1376a65d3064SKris Buschelman break; 137728b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 137828b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 137928b2fa4aSMatthew Knepley break; 1380a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13814e0d8c25SBarry Smith a->ignorezeroentries = flg; 13820df259c2SBarry Smith break; 13833d472b54SHong Zhang case MAT_SPD: 1384b1646e73SJed Brown case MAT_SYMMETRIC: 1385b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1386b1646e73SJed Brown case MAT_HERMITIAN: 1387b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1388957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13895021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13905021d80fSJed Brown break; 13918c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1392a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1393a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1394290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1395a65d3064SKris Buschelman break; 1396b87ac2d8SJed Brown case MAT_USE_INODES: 1397b215bc84SStefano Zampini ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr); 1398b87ac2d8SJed Brown break; 1399c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1400c10200c1SHong Zhang A->submat_singleis = flg; 1401c10200c1SHong Zhang break; 1402071fcb05SBarry Smith case MAT_SORTED_FULL: 1403071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1404071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1405071fcb05SBarry Smith break; 14061a2c6b5cSJunchao Zhang case MAT_FORM_EXPLICIT_TRANSPOSE: 14071a2c6b5cSJunchao Zhang A->form_explicit_transpose = flg; 14081a2c6b5cSJunchao Zhang break; 1409a65d3064SKris Buschelman default: 1410e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1411a65d3064SKris Buschelman } 14123a40ed3dSBarry Smith PetscFunctionReturn(0); 141317ab2063SBarry Smith } 141417ab2063SBarry Smith 1415dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 141617ab2063SBarry Smith { 1417416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14186849ba73SBarry Smith PetscErrorCode ierr; 1419fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1420c898d852SStefano Zampini PetscScalar *x; 1421c898d852SStefano Zampini const PetscScalar *aa; 142217ab2063SBarry Smith 14233a40ed3dSBarry Smith PetscFunctionBegin; 1424d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1425e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1426c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1427d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1428d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1429fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 14302c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1431fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1432c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 143335e7444dSHong Zhang PetscFunctionReturn(0); 143435e7444dSHong Zhang } 143535e7444dSHong Zhang 1436fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 143735e7444dSHong Zhang for (i=0; i<n; i++) { 1438fdc842d1SBarry Smith x[i] = 0.0; 143935e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 144035e7444dSHong Zhang if (aj[j] == i) { 144135e7444dSHong Zhang x[i] = aa[j]; 144217ab2063SBarry Smith break; 144317ab2063SBarry Smith } 144417ab2063SBarry Smith } 144517ab2063SBarry Smith } 1446fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1447c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14483a40ed3dSBarry Smith PetscFunctionReturn(0); 144917ab2063SBarry Smith } 145017ab2063SBarry Smith 1451c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1452dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 145317ab2063SBarry Smith { 1454416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1455d9ca1df4SBarry Smith PetscScalar *y; 1456d9ca1df4SBarry Smith const PetscScalar *x; 1457dfbe8321SBarry Smith PetscErrorCode ierr; 1458d0f46423SBarry Smith PetscInt m = A->rmap->n; 14595c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1460d9ca1df4SBarry Smith const MatScalar *v; 1461a77337e4SBarry Smith PetscScalar alpha; 1462d9ca1df4SBarry Smith PetscInt n,i,j; 1463d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14643447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1465ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14665c897100SBarry Smith #endif 146717ab2063SBarry Smith 14683a40ed3dSBarry Smith PetscFunctionBegin; 14692e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1470d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14711ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14725c897100SBarry Smith 14735c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1474bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 14755c897100SBarry Smith #else 14763447b6efSHong Zhang if (usecprow) { 14773447b6efSHong Zhang m = cprow.nrows; 14783447b6efSHong Zhang ii = cprow.i; 14797b2bb3b9SHong Zhang ridx = cprow.rindex; 14803447b6efSHong Zhang } else { 14813447b6efSHong Zhang ii = a->i; 14823447b6efSHong Zhang } 148317ab2063SBarry Smith for (i=0; i<m; i++) { 14843447b6efSHong Zhang idx = a->j + ii[i]; 14853447b6efSHong Zhang v = a->a + ii[i]; 14863447b6efSHong Zhang n = ii[i+1] - ii[i]; 14873447b6efSHong Zhang if (usecprow) { 14887b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14893447b6efSHong Zhang } else { 149017ab2063SBarry Smith alpha = x[i]; 14913447b6efSHong Zhang } 149204fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 149317ab2063SBarry Smith } 14945c897100SBarry Smith #endif 1495dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1496d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14971ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14983a40ed3dSBarry Smith PetscFunctionReturn(0); 149917ab2063SBarry Smith } 150017ab2063SBarry Smith 1501dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 15025c897100SBarry Smith { 1503dfbe8321SBarry Smith PetscErrorCode ierr; 15045c897100SBarry Smith 15055c897100SBarry Smith PetscFunctionBegin; 1506170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 15075c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 15085c897100SBarry Smith PetscFunctionReturn(0); 15095c897100SBarry Smith } 15105c897100SBarry Smith 1511c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 151278b84d54SShri Abhyankar 1513dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 151417ab2063SBarry Smith { 1515416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1516d9fead3dSBarry Smith PetscScalar *y; 151754f21887SBarry Smith const PetscScalar *x; 151854f21887SBarry Smith const MatScalar *aa; 1519dfbe8321SBarry Smith PetscErrorCode ierr; 1520003131ecSBarry Smith PetscInt m=A->rmap->n; 15210298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 15227b083b7cSBarry Smith PetscInt n,i; 1523362ced78SSatish Balay PetscScalar sum; 1524ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 152517ab2063SBarry Smith 1526b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 152797952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1528fee21e36SBarry Smith #endif 1529fee21e36SBarry Smith 15303a40ed3dSBarry Smith PetscFunctionBegin; 1531b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1532b215bc84SStefano Zampini ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr); 1533b215bc84SStefano Zampini PetscFunctionReturn(0); 1534b215bc84SStefano Zampini } 15353649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15361ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1537416022c9SBarry Smith ii = a->i; 15384eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1539580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 154097952fefSHong Zhang m = a->compressedrow.nrows; 154197952fefSHong Zhang ii = a->compressedrow.i; 154297952fefSHong Zhang ridx = a->compressedrow.rindex; 154397952fefSHong Zhang for (i=0; i<m; i++) { 154497952fefSHong Zhang n = ii[i+1] - ii[i]; 154597952fefSHong Zhang aj = a->j + ii[i]; 154697952fefSHong Zhang aa = a->a + ii[i]; 154797952fefSHong Zhang sum = 0.0; 1548003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1549003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 155097952fefSHong Zhang y[*ridx++] = sum; 155197952fefSHong Zhang } 155297952fefSHong Zhang } else { /* do not use compressed row format */ 1553b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15543d3eaba7SBarry Smith aj = a->j; 15553d3eaba7SBarry Smith aa = a->a; 1556b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1557b05257ddSBarry Smith #else 155817ab2063SBarry Smith for (i=0; i<m; i++) { 1559003131ecSBarry Smith n = ii[i+1] - ii[i]; 1560003131ecSBarry Smith aj = a->j + ii[i]; 1561003131ecSBarry Smith aa = a->a + ii[i]; 156217ab2063SBarry Smith sum = 0.0; 1563003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 156417ab2063SBarry Smith y[i] = sum; 156517ab2063SBarry Smith } 15668d195f9aSBarry Smith #endif 1567b05257ddSBarry Smith } 15687b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15693649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15701ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15713a40ed3dSBarry Smith PetscFunctionReturn(0); 157217ab2063SBarry Smith } 157317ab2063SBarry Smith 1574b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1575b434eb95SMatthew G. Knepley { 1576b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1577b434eb95SMatthew G. Knepley PetscScalar *y; 1578b434eb95SMatthew G. Knepley const PetscScalar *x; 1579b434eb95SMatthew G. Knepley const MatScalar *aa; 1580b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1581b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1582b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1583b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1584b434eb95SMatthew G. Knepley PetscScalar sum; 1585b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1586b434eb95SMatthew G. Knepley 1587b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1588b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1589b434eb95SMatthew G. Knepley #endif 1590b434eb95SMatthew G. Knepley 1591b434eb95SMatthew G. Knepley PetscFunctionBegin; 1592b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1593b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1594b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1595b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1596b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1597b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1598b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1599b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1600b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1601b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1602b434eb95SMatthew G. Knepley sum = 0.0; 1603b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1604b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1605b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1606b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1607b434eb95SMatthew G. Knepley } 1608b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16093d3eaba7SBarry Smith ii = a->i; 1610b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1611b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1612b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1613b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1614b434eb95SMatthew G. Knepley sum = 0.0; 1615b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1616b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1617b434eb95SMatthew G. Knepley y[i] = sum; 1618b434eb95SMatthew G. Knepley } 1619b434eb95SMatthew G. Knepley } 1620b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1621b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1622b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1623b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1624b434eb95SMatthew G. Knepley } 1625b434eb95SMatthew G. Knepley 1626b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1627b434eb95SMatthew G. Knepley { 1628b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1629b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1630b434eb95SMatthew G. Knepley const PetscScalar *x; 1631b434eb95SMatthew G. Knepley const MatScalar *aa; 1632b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1633b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1634b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1635b434eb95SMatthew G. Knepley PetscScalar sum; 1636b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1637b434eb95SMatthew G. Knepley 1638b434eb95SMatthew G. Knepley PetscFunctionBegin; 1639b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1640d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1641b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1642b434eb95SMatthew G. Knepley if (zz != yy) { 1643580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1644b434eb95SMatthew G. Knepley } 1645b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1646b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1647b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1648b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1649b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1650b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1651b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1652b434eb95SMatthew G. Knepley sum = y[*ridx]; 1653b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1654b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1655b434eb95SMatthew G. Knepley } 1656b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16573d3eaba7SBarry Smith ii = a->i; 1658b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1659b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1660b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1661b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1662b434eb95SMatthew G. Knepley sum = y[i]; 1663b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1664b434eb95SMatthew G. Knepley z[i] = sum; 1665b434eb95SMatthew G. Knepley } 1666b434eb95SMatthew G. Knepley } 1667b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1668b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1669d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1670b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1671b434eb95SMatthew G. Knepley } 1672b434eb95SMatthew G. Knepley 1673c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1674dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 167517ab2063SBarry Smith { 1676416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1677f15663dcSBarry Smith PetscScalar *y,*z; 1678f15663dcSBarry Smith const PetscScalar *x; 167954f21887SBarry Smith const MatScalar *aa; 1680dfbe8321SBarry Smith PetscErrorCode ierr; 1681d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1682d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1683362ced78SSatish Balay PetscScalar sum; 1684ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16859ea0dfa2SSatish Balay 16863a40ed3dSBarry Smith PetscFunctionBegin; 1687b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1688b215bc84SStefano Zampini ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr); 1689b215bc84SStefano Zampini PetscFunctionReturn(0); 1690b215bc84SStefano Zampini } 1691f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1692d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16934eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16944eb6d288SHong Zhang if (zz != yy) { 1695580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16964eb6d288SHong Zhang } 169797952fefSHong Zhang m = a->compressedrow.nrows; 169897952fefSHong Zhang ii = a->compressedrow.i; 169997952fefSHong Zhang ridx = a->compressedrow.rindex; 170097952fefSHong Zhang for (i=0; i<m; i++) { 170197952fefSHong Zhang n = ii[i+1] - ii[i]; 170297952fefSHong Zhang aj = a->j + ii[i]; 170397952fefSHong Zhang aa = a->a + ii[i]; 170497952fefSHong Zhang sum = y[*ridx]; 1705f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 170697952fefSHong Zhang z[*ridx++] = sum; 170797952fefSHong Zhang } 170897952fefSHong Zhang } else { /* do not use compressed row format */ 17093d3eaba7SBarry Smith ii = a->i; 1710f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 17113d3eaba7SBarry Smith aj = a->j; 17123d3eaba7SBarry Smith aa = a->a; 1713f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1714f15663dcSBarry Smith #else 171517ab2063SBarry Smith for (i=0; i<m; i++) { 1716f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1717f15663dcSBarry Smith aj = a->j + ii[i]; 1718f15663dcSBarry Smith aa = a->a + ii[i]; 171917ab2063SBarry Smith sum = y[i]; 1720f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 172117ab2063SBarry Smith z[i] = sum; 172217ab2063SBarry Smith } 172302ab625aSSatish Balay #endif 1724f15663dcSBarry Smith } 1725dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1726f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1727d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 17283a40ed3dSBarry Smith PetscFunctionReturn(0); 172917ab2063SBarry Smith } 173017ab2063SBarry Smith 173117ab2063SBarry Smith /* 173217ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 173317ab2063SBarry Smith */ 1734dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 173517ab2063SBarry Smith { 1736416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17376849ba73SBarry Smith PetscErrorCode ierr; 1738d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 173917ab2063SBarry Smith 17403a40ed3dSBarry Smith PetscFunctionBegin; 174109f38230SBarry Smith if (!a->diag) { 1742785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17433bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 174409f38230SBarry Smith } 1745d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 174609f38230SBarry Smith a->diag[i] = a->i[i+1]; 1747bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1748bfeeae90SHong Zhang if (a->j[j] == i) { 174909f38230SBarry Smith a->diag[i] = j; 175017ab2063SBarry Smith break; 175117ab2063SBarry Smith } 175217ab2063SBarry Smith } 175317ab2063SBarry Smith } 17543a40ed3dSBarry Smith PetscFunctionReturn(0); 175517ab2063SBarry Smith } 175617ab2063SBarry Smith 175761ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 175861ecd0c6SBarry Smith { 175961ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 176061ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 176161ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 176261ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 176361ecd0c6SBarry Smith PetscErrorCode ierr; 176461ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 176561ecd0c6SBarry Smith 176661ecd0c6SBarry Smith PetscFunctionBegin; 176761ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 176861ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 176961ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 177061ecd0c6SBarry Smith PetscFunctionReturn(0); 177161ecd0c6SBarry Smith } 177261ecd0c6SBarry Smith 177361ecd0c6SBarry Smith if (a->diagonaldense) { 177461ecd0c6SBarry Smith cnt = 0; 177561ecd0c6SBarry Smith } else { 177661ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 177761ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 177861ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 177961ecd0c6SBarry Smith cnt++; 178061ecd0c6SBarry Smith mdiag[i] = 1; 178161ecd0c6SBarry Smith } 178261ecd0c6SBarry Smith } 178361ecd0c6SBarry Smith } 178461ecd0c6SBarry Smith if (!cnt) { 178561ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 178661ecd0c6SBarry Smith } else { 1787b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1788b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 178961ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 179061ecd0c6SBarry Smith 179161ecd0c6SBarry Smith a->a = NULL; 179261ecd0c6SBarry Smith a->j = NULL; 179361ecd0c6SBarry Smith a->i = NULL; 179461ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 179561ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 179661ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1797447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 179861ecd0c6SBarry Smith } 179961ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 180061ecd0c6SBarry Smith 180161ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 180261ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 180361ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1804447d62f5SStefano Zampini if (i < A->cmap->n) { 180561ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 180661ecd0c6SBarry Smith } 1807447d62f5SStefano Zampini } 180861ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180961ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 181061ecd0c6SBarry Smith if (singlemalloc) { 181161ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 181261ecd0c6SBarry Smith } else { 181361ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 181461ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 181561ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 181661ecd0c6SBarry Smith } 181761ecd0c6SBarry Smith } 181861ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 181961ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 182061ecd0c6SBarry Smith PetscFunctionReturn(0); 182161ecd0c6SBarry Smith } 182261ecd0c6SBarry Smith 1823be5855fcSBarry Smith /* 1824be5855fcSBarry Smith Checks for missing diagonals 1825be5855fcSBarry Smith */ 1826ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1827be5855fcSBarry Smith { 1828be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18297734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1830994fe344SLisandro Dalcin PetscErrorCode ierr; 1831be5855fcSBarry Smith 1832be5855fcSBarry Smith PetscFunctionBegin; 183309f38230SBarry Smith *missing = PETSC_FALSE; 18347734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 183509f38230SBarry Smith *missing = PETSC_TRUE; 183609f38230SBarry Smith if (d) *d = 0; 1837994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 183809f38230SBarry Smith } else { 183901445905SHong Zhang PetscInt n; 184001445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1841f1e2ffcdSBarry Smith diag = a->diag; 184201445905SHong Zhang for (i=0; i<n; i++) { 18437734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 184409f38230SBarry Smith *missing = PETSC_TRUE; 184509f38230SBarry Smith if (d) *d = i; 1846994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1847358d2f5dSShri Abhyankar break; 184809f38230SBarry Smith } 1849be5855fcSBarry Smith } 1850be5855fcSBarry Smith } 1851be5855fcSBarry Smith PetscFunctionReturn(0); 1852be5855fcSBarry Smith } 1853be5855fcSBarry Smith 18540da83c2eSBarry Smith #include <petscblaslapack.h> 18550da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18560da83c2eSBarry Smith 18570da83c2eSBarry Smith /* 18580da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18590da83c2eSBarry Smith */ 18600da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18610da83c2eSBarry Smith { 18620da83c2eSBarry Smith PetscErrorCode ierr; 18630da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18640da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18650da83c2eSBarry Smith const PetscReal shift = 0.0; 18660da83c2eSBarry Smith PetscInt ipvt[5]; 18670da83c2eSBarry Smith PetscScalar work[25],*v_work; 18680da83c2eSBarry Smith 18690da83c2eSBarry Smith PetscFunctionBegin; 18700da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18710da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18720da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18730da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18740da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18750da83c2eSBarry Smith } 18760da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18770da83c2eSBarry Smith if (bsizemax > 7) { 18780da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18790da83c2eSBarry Smith } 18800da83c2eSBarry Smith ncnt = 0; 18810da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18820da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18830da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18840da83c2eSBarry Smith switch (bsizes[i]) { 18850da83c2eSBarry Smith case 1: 18860da83c2eSBarry Smith *diag = 1.0/(*diag); 18870da83c2eSBarry Smith break; 18880da83c2eSBarry Smith case 2: 18890da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18900da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18910da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18920da83c2eSBarry Smith break; 18930da83c2eSBarry Smith case 3: 18940da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18950da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18960da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18970da83c2eSBarry Smith break; 18980da83c2eSBarry Smith case 4: 18990da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19000da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19010da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 19020da83c2eSBarry Smith break; 19030da83c2eSBarry Smith case 5: 19040da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19050da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19060da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 19070da83c2eSBarry Smith break; 19080da83c2eSBarry Smith case 6: 19090da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19100da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19110da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 19120da83c2eSBarry Smith break; 19130da83c2eSBarry Smith case 7: 19140da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19150da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19160da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 19170da83c2eSBarry Smith break; 19180da83c2eSBarry Smith default: 19190da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 19200da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19210da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 19220da83c2eSBarry Smith } 19230da83c2eSBarry Smith ncnt += bsizes[i]; 19240da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 19250da83c2eSBarry Smith } 19260da83c2eSBarry Smith if (bsizemax > 7) { 19270da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 19280da83c2eSBarry Smith } 19290da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 19300da83c2eSBarry Smith PetscFunctionReturn(0); 19310da83c2eSBarry Smith } 19320da83c2eSBarry Smith 1933422a814eSBarry Smith /* 1934422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1935422a814eSBarry Smith */ 19367087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 193771f1c65dSBarry Smith { 193871f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 193971f1c65dSBarry Smith PetscErrorCode ierr; 1940d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 19412e5835c6SStefano Zampini const MatScalar *v; 194254f21887SBarry Smith PetscScalar *idiag,*mdiag; 194371f1c65dSBarry Smith 194471f1c65dSBarry Smith PetscFunctionBegin; 194571f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 194671f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 194771f1c65dSBarry Smith diag = a->diag; 194871f1c65dSBarry Smith if (!a->idiag) { 1949dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19503bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,3*m*sizeof(PetscScalar));CHKERRQ(ierr); 195171f1c65dSBarry Smith } 19522e5835c6SStefano Zampini 195371f1c65dSBarry Smith mdiag = a->mdiag; 195471f1c65dSBarry Smith idiag = a->idiag; 19552e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 1956422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 195771f1c65dSBarry Smith for (i=0; i<m; i++) { 195871f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1959899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1960899639b0SHong Zhang if (PetscRealPart(fshift)) { 1961899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19627b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19637b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19647b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1965a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1966899639b0SHong Zhang } 196771f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 196871f1c65dSBarry Smith } 196971f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 197071f1c65dSBarry Smith } else { 197171f1c65dSBarry Smith for (i=0; i<m; i++) { 197271f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 197371f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 197471f1c65dSBarry Smith } 1975dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 197671f1c65dSBarry Smith } 197771f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 19782e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 197971f1c65dSBarry Smith PetscFunctionReturn(0); 198071f1c65dSBarry Smith } 198171f1c65dSBarry Smith 1982c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 198341f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 198417ab2063SBarry Smith { 1985416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1986e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 19872e5835c6SStefano Zampini const MatScalar *v,*idiag=NULL,*mdiag,*aa; 198854f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1989dfbe8321SBarry Smith PetscErrorCode ierr; 19903d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 199197f1f81fSBarry Smith const PetscInt *idx,*diag; 199217ab2063SBarry Smith 19933a40ed3dSBarry Smith PetscFunctionBegin; 1994b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 1995b215bc84SStefano Zampini ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 1996b215bc84SStefano Zampini PetscFunctionReturn(0); 1997b215bc84SStefano Zampini } 1998b965ef7fSBarry Smith its = its*lits; 199991723122SBarry Smith 200071f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 200171f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 200271f1c65dSBarry Smith a->fshift = fshift; 200371f1c65dSBarry Smith a->omega = omega; 2004ed480e8bSBarry Smith 200571f1c65dSBarry Smith diag = a->diag; 200671f1c65dSBarry Smith t = a->ssor_work; 2007ed480e8bSBarry Smith idiag = a->idiag; 200871f1c65dSBarry Smith mdiag = a->mdiag; 2009ed480e8bSBarry Smith 20102e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 20111ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 20123649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 2013ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 201417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 201517ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 2016ed480e8bSBarry Smith bs = b; 201717ab2063SBarry Smith for (i=0; i<m; i++) { 201871f1c65dSBarry Smith d = fshift + mdiag[i]; 2019416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2020ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20212e5835c6SStefano Zampini v = aa + diag[i] + 1; 202217ab2063SBarry Smith sum = b[i]*d/omega; 2023003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 202417ab2063SBarry Smith x[i] = sum; 202517ab2063SBarry Smith } 20261ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20273649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20282e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 2029efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20303a40ed3dSBarry Smith PetscFunctionReturn(0); 203117ab2063SBarry Smith } 2032c783ea89SBarry Smith 20332205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 20342205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 20354c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 2036887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 203717ab2063SBarry Smith 203817ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 203917ab2063SBarry Smith 2040887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 204117ab2063SBarry Smith */ 204217ab2063SBarry Smith scale = (2.0/omega) - 1.0; 204317ab2063SBarry Smith 204417ab2063SBarry Smith /* x = (E + U)^{-1} b */ 204517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2046416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2047ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20482e5835c6SStefano Zampini v = aa + diag[i] + 1; 204917ab2063SBarry Smith sum = b[i]; 2050e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2051ed480e8bSBarry Smith x[i] = sum*idiag[i]; 205217ab2063SBarry Smith } 205317ab2063SBarry Smith 205417ab2063SBarry Smith /* t = b - (2*E - D)x */ 20552e5835c6SStefano Zampini v = aa; 20562205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 205717ab2063SBarry Smith 205817ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2059ed480e8bSBarry Smith ts = t; 2060416022c9SBarry Smith diag = a->diag; 206117ab2063SBarry Smith for (i=0; i<m; i++) { 2062416022c9SBarry Smith n = diag[i] - a->i[i]; 2063ed480e8bSBarry Smith idx = a->j + a->i[i]; 20642e5835c6SStefano Zampini v = aa + a->i[i]; 206517ab2063SBarry Smith sum = t[i]; 2066003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2067ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2068733d66baSBarry Smith /* x = x + t */ 2069733d66baSBarry Smith x[i] += t[i]; 207017ab2063SBarry Smith } 207117ab2063SBarry Smith 2072dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20731ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20743649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20753a40ed3dSBarry Smith PetscFunctionReturn(0); 207617ab2063SBarry Smith } 207717ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 207817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 207917ab2063SBarry Smith for (i=0; i<m; i++) { 2080416022c9SBarry Smith n = diag[i] - a->i[i]; 2081ed480e8bSBarry Smith idx = a->j + a->i[i]; 20822e5835c6SStefano Zampini v = aa + a->i[i]; 208317ab2063SBarry Smith sum = b[i]; 2084e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20855c99c7daSBarry Smith t[i] = sum; 2086ed480e8bSBarry Smith x[i] = sum*idiag[i]; 208717ab2063SBarry Smith } 20885c99c7daSBarry Smith xb = t; 2089efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20903a40ed3dSBarry Smith } else xb = b; 209117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 209217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2093416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2094ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 20952e5835c6SStefano Zampini v = aa + diag[i] + 1; 209617ab2063SBarry Smith sum = xb[i]; 2097e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20985c99c7daSBarry Smith if (xb == b) { 2099ed480e8bSBarry Smith x[i] = sum*idiag[i]; 21005c99c7daSBarry Smith } else { 2101b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 210217ab2063SBarry Smith } 21035c99c7daSBarry Smith } 2104b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 210517ab2063SBarry Smith } 210617ab2063SBarry Smith its--; 210717ab2063SBarry Smith } 210817ab2063SBarry Smith while (its--) { 210917ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 211017ab2063SBarry Smith for (i=0; i<m; i++) { 2111b19a5dc2SMark Adams /* lower */ 2112b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2113ed480e8bSBarry Smith idx = a->j + a->i[i]; 21142e5835c6SStefano Zampini v = aa + a->i[i]; 211517ab2063SBarry Smith sum = b[i]; 2116e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2117b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2118b19a5dc2SMark Adams /* upper */ 2119b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2120b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21212e5835c6SStefano Zampini v = aa + diag[i] + 1; 2122b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2123b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 212417ab2063SBarry Smith } 2125b19a5dc2SMark Adams xb = t; 21269f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2127b19a5dc2SMark Adams } else xb = b; 212817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 212917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2130b19a5dc2SMark Adams sum = xb[i]; 2131b19a5dc2SMark Adams if (xb == b) { 2132b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2133416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2134ed480e8bSBarry Smith idx = a->j + a->i[i]; 21352e5835c6SStefano Zampini v = aa + a->i[i]; 2136e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2137ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2138b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2139b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2140b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 21412e5835c6SStefano Zampini v = aa + diag[i] + 1; 2142b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2143b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 214417ab2063SBarry Smith } 2145b19a5dc2SMark Adams } 2146b19a5dc2SMark Adams if (xb == b) { 21479f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2148b19a5dc2SMark Adams } else { 2149b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2150b19a5dc2SMark Adams } 215117ab2063SBarry Smith } 215217ab2063SBarry Smith } 21532e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 21541ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 21553649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2156365a8a9eSBarry Smith PetscFunctionReturn(0); 215717ab2063SBarry Smith } 215817ab2063SBarry Smith 2159dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 216017ab2063SBarry Smith { 2161416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21624e220ebcSLois Curfman McInnes 21633a40ed3dSBarry Smith PetscFunctionBegin; 21644e220ebcSLois Curfman McInnes info->block_size = 1.0; 21653966268fSBarry Smith info->nz_allocated = a->maxnz; 21663966268fSBarry Smith info->nz_used = a->nz; 21673966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21683966268fSBarry Smith info->assemblies = A->num_ass; 21693966268fSBarry Smith info->mallocs = A->info.mallocs; 21707adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2171d5f3da31SBarry Smith if (A->factortype) { 21724e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21734e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21744e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21754e220ebcSLois Curfman McInnes } else { 21764e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21774e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21784e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21794e220ebcSLois Curfman McInnes } 21803a40ed3dSBarry Smith PetscFunctionReturn(0); 218117ab2063SBarry Smith } 218217ab2063SBarry Smith 21832b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 218417ab2063SBarry Smith { 2185416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2186c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21876849ba73SBarry Smith PetscErrorCode ierr; 218897b48c8fSBarry Smith const PetscScalar *xx; 21892e5835c6SStefano Zampini PetscScalar *bb,*aa; 2190c7da8527SEric Chamberland PetscInt d = 0; 219117ab2063SBarry Smith 21923a40ed3dSBarry Smith PetscFunctionBegin; 219397b48c8fSBarry Smith if (x && b) { 219497b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 219597b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 219697b48c8fSBarry Smith for (i=0; i<N; i++) { 219797b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2198447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 219997b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 220097b48c8fSBarry Smith } 220197b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 220297b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 220397b48c8fSBarry Smith } 220497b48c8fSBarry Smith 22052e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 2206a9817697SBarry Smith if (a->keepnonzeropattern) { 2207f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2208e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22092e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2210f1e2ffcdSBarry Smith } 2211f4df32b1SMatthew Knepley if (diag != 0.0) { 2212c7da8527SEric Chamberland for (i=0; i<N; i++) { 2213c7da8527SEric Chamberland d = rows[i]; 2214447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2215c7da8527SEric 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); 2216c7da8527SEric Chamberland } 2217f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2218447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 22192e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 2220f1e2ffcdSBarry Smith } 2221f1e2ffcdSBarry Smith } 2222f1e2ffcdSBarry Smith } else { 2223f4df32b1SMatthew Knepley if (diag != 0.0) { 222417ab2063SBarry Smith for (i=0; i<N; i++) { 2225e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22267ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2227447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2228447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2229447d62f5SStefano Zampini } else { 2230416022c9SBarry Smith a->ilen[rows[i]] = 1; 22312e5835c6SStefano Zampini aa[a->i[rows[i]]] = diag; 2232bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2233447d62f5SStefano Zampini } 2234447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2235f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 223617ab2063SBarry Smith } 223717ab2063SBarry Smith } 22383a40ed3dSBarry Smith } else { 223917ab2063SBarry Smith for (i=0; i<N; i++) { 2240e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2241416022c9SBarry Smith a->ilen[rows[i]] = 0; 224217ab2063SBarry Smith } 224317ab2063SBarry Smith } 2244e56f5c9eSBarry Smith A->nonzerostate++; 2245f1e2ffcdSBarry Smith } 22462e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 22478c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2248c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2249e2cf4d64SStefano Zampini #endif 22504099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22513a40ed3dSBarry Smith PetscFunctionReturn(0); 225217ab2063SBarry Smith } 225317ab2063SBarry Smith 22546e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 22556e169961SBarry Smith { 22566e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22576e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22586e169961SBarry Smith PetscErrorCode ierr; 22592b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22606e169961SBarry Smith const PetscScalar *xx; 22612e5835c6SStefano Zampini PetscScalar *bb,*aa; 22626e169961SBarry Smith 22636e169961SBarry Smith PetscFunctionBegin; 22642e5835c6SStefano Zampini if (!N) PetscFunctionReturn(0); 22652e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); 22666e169961SBarry Smith if (x && b) { 22676e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22686e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22692b40b63fSBarry Smith vecs = PETSC_TRUE; 22706e169961SBarry Smith } 22711795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22726e169961SBarry Smith for (i=0; i<N; i++) { 22736e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 22742e5835c6SStefano Zampini ierr = PetscArrayzero(&aa[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22752205254eSKarl Rupp 22766e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22776e169961SBarry Smith } 22786e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22796e169961SBarry Smith if (!zeroed[i]) { 22806e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22814cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22822e5835c6SStefano Zampini if (vecs) bb[i] -= aa[j]*xx[a->j[j]]; 22832e5835c6SStefano Zampini aa[j] = 0.0; 22846e169961SBarry Smith } 22856e169961SBarry Smith } 22864cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22876e169961SBarry Smith } 22886e169961SBarry Smith if (x && b) { 22896e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22906e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22916e169961SBarry Smith } 22926e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22936e169961SBarry Smith if (diag != 0.0) { 22946e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22951d5a398dSstefano_zampini if (missing) { 22961d5a398dSstefano_zampini for (i=0; i<N; i++) { 22974cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22984cf107fdSStefano 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]); 22991d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 23001d5a398dSstefano_zampini } 23011d5a398dSstefano_zampini } else { 23026e169961SBarry Smith for (i=0; i<N; i++) { 23032e5835c6SStefano Zampini aa[a->diag[rows[i]]] = diag; 23046e169961SBarry Smith } 23056e169961SBarry Smith } 23061d5a398dSstefano_zampini } 23072e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); 23088c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2309c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2310e2cf4d64SStefano Zampini #endif 23114099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23126e169961SBarry Smith PetscFunctionReturn(0); 23136e169961SBarry Smith } 23146e169961SBarry Smith 2315a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 231617ab2063SBarry Smith { 2317416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23182e5835c6SStefano Zampini const PetscScalar *aa = a->a; 231997f1f81fSBarry Smith PetscInt *itmp; 23202e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23212e5835c6SStefano Zampini PetscErrorCode ierr; 23222e5835c6SStefano Zampini PetscBool rest = PETSC_FALSE; 23232e5835c6SStefano Zampini #endif 232417ab2063SBarry Smith 23253a40ed3dSBarry Smith PetscFunctionBegin; 23262e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23272e5835c6SStefano Zampini if (v && A->offloadmask == PETSC_OFFLOAD_GPU) { 23282e5835c6SStefano Zampini /* triggers copy to CPU */ 23292e5835c6SStefano Zampini rest = PETSC_TRUE; 23302e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 23312e5835c6SStefano Zampini } else aa = a->a; 23322e5835c6SStefano Zampini #endif 2333416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 23342e5835c6SStefano Zampini if (v) *v = (PetscScalar*)(aa + a->i[row]); 233517ab2063SBarry Smith if (idx) { 2336bfeeae90SHong Zhang itmp = a->j + a->i[row]; 233726fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2338f4259b30SLisandro Dalcin else *idx = NULL; 233917ab2063SBarry Smith } 23402e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 23412e5835c6SStefano Zampini if (rest) { 23422e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 23432e5835c6SStefano Zampini } 23442e5835c6SStefano Zampini #endif 23453a40ed3dSBarry Smith PetscFunctionReturn(0); 234617ab2063SBarry Smith } 234717ab2063SBarry Smith 2348a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 234917ab2063SBarry Smith { 23503a40ed3dSBarry Smith PetscFunctionBegin; 2351cb4a9cd9SHong Zhang if (nz) *nz = 0; 23522e5835c6SStefano Zampini if (idx) *idx = NULL; 23532e5835c6SStefano Zampini if (v) *v = NULL; 23543a40ed3dSBarry Smith PetscFunctionReturn(0); 235517ab2063SBarry Smith } 235617ab2063SBarry Smith 2357dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 235817ab2063SBarry Smith { 2359416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23602e5835c6SStefano Zampini const MatScalar *v; 236136db0b34SBarry Smith PetscReal sum = 0.0; 23626849ba73SBarry Smith PetscErrorCode ierr; 236397f1f81fSBarry Smith PetscInt i,j; 236417ab2063SBarry Smith 23653a40ed3dSBarry Smith PetscFunctionBegin; 23662e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&v);CHKERRQ(ierr); 236717ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2368570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2369570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 237073cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2371570b7f6dSBarry Smith #else 2372416022c9SBarry Smith for (i=0; i<a->nz; i++) { 237336db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 237417ab2063SBarry Smith } 23758f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2376570b7f6dSBarry Smith #endif 2377ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 23783a40ed3dSBarry Smith } else if (type == NORM_1) { 237936db0b34SBarry Smith PetscReal *tmp; 238097f1f81fSBarry Smith PetscInt *jj = a->j; 23811795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2382064f8208SBarry Smith *nrm = 0.0; 2383416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2384bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 238517ab2063SBarry Smith } 2386d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2387064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 238817ab2063SBarry Smith } 2389606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 239051f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23913a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2392064f8208SBarry Smith *nrm = 0.0; 2393d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 23942e5835c6SStefano Zampini const PetscScalar *v2 = v + a->i[j]; 239517ab2063SBarry Smith sum = 0.0; 2396416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 23972e5835c6SStefano Zampini sum += PetscAbsScalar(*v2); v2++; 239817ab2063SBarry Smith } 2399064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 240017ab2063SBarry Smith } 240151f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2402f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 24032e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&v);CHKERRQ(ierr); 24043a40ed3dSBarry Smith PetscFunctionReturn(0); 240517ab2063SBarry Smith } 240617ab2063SBarry Smith 24074e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 24084e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 24094e938277SHong Zhang { 24104e938277SHong Zhang PetscErrorCode ierr; 24114e938277SHong Zhang PetscInt i,j,anzj; 24124e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 24134e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 24144e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 24154e938277SHong Zhang 24164e938277SHong Zhang PetscFunctionBegin; 24174e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2418854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2419785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2420785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 24214e938277SHong Zhang 24224e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 24234e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 242426fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 24254e938277SHong Zhang /* Form ati for csr format of A^T. */ 242626fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 24274e938277SHong Zhang 24284e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2429580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 24304e938277SHong Zhang 24314e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 24324e938277SHong Zhang for (i=0;i<am;i++) { 24334e938277SHong Zhang anzj = ai[i+1] - ai[i]; 24344e938277SHong Zhang for (j=0;j<anzj;j++) { 24354e938277SHong Zhang atj[atfill[*aj]] = i; 24364e938277SHong Zhang atfill[*aj++] += 1; 24374e938277SHong Zhang } 24384e938277SHong Zhang } 24394e938277SHong Zhang 24404e938277SHong Zhang /* Clean up temporary space and complete requests. */ 24414e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2442ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 244333d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2444b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2445a2f3521dSMark F. Adams 24464e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 24474e938277SHong Zhang b->free_a = PETSC_FALSE; 24484e938277SHong Zhang b->free_ij = PETSC_TRUE; 24494e938277SHong Zhang b->nonew = 0; 24504e938277SHong Zhang PetscFunctionReturn(0); 24514e938277SHong Zhang } 24524e938277SHong Zhang 24537087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2454cd0d46ebSvictorle { 24553d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 245654f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 24572e5835c6SStefano Zampini const MatScalar *va,*vb; 24586849ba73SBarry Smith PetscErrorCode ierr; 245997f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2460cd0d46ebSvictorle 2461cd0d46ebSvictorle PetscFunctionBegin; 2462cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2463cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24645485867bSBarry Smith if (ma!=nb || na!=mb) { 24655485867bSBarry Smith *f = PETSC_FALSE; 24665485867bSBarry Smith PetscFunctionReturn(0); 24675485867bSBarry Smith } 24682e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&va);CHKERRQ(ierr); 24692e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(B,&vb);CHKERRQ(ierr); 2470cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2471cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2472785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2473785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2474cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2475cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2476cd0d46ebSvictorle 2477cd0d46ebSvictorle *f = PETSC_TRUE; 2478cd0d46ebSvictorle for (i=0; i<ma; i++) { 2479cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 248097f1f81fSBarry Smith PetscInt idc,idr; 24815485867bSBarry Smith PetscScalar vc,vr; 2482cd0d46ebSvictorle /* column/row index/value */ 24835485867bSBarry Smith idc = adx[aptr[i]]; 24845485867bSBarry Smith idr = bdx[bptr[idc]]; 24855485867bSBarry Smith vc = va[aptr[i]]; 24865485867bSBarry Smith vr = vb[bptr[idc]]; 24875485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24885485867bSBarry Smith *f = PETSC_FALSE; 24895485867bSBarry Smith goto done; 2490cd0d46ebSvictorle } else { 24915485867bSBarry Smith aptr[i]++; 24925485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2493cd0d46ebSvictorle } 2494cd0d46ebSvictorle } 2495cd0d46ebSvictorle } 2496cd0d46ebSvictorle done: 2497cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24983aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 24992e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&va);CHKERRQ(ierr); 25002e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(B,&vb);CHKERRQ(ierr); 2501cd0d46ebSvictorle PetscFunctionReturn(0); 2502cd0d46ebSvictorle } 2503cd0d46ebSvictorle 25047087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 25051cbb95d3SBarry Smith { 25063d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 250754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 250854f21887SBarry Smith MatScalar *va,*vb; 25091cbb95d3SBarry Smith PetscErrorCode ierr; 25101cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 25111cbb95d3SBarry Smith 25121cbb95d3SBarry Smith PetscFunctionBegin; 25131cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 25141cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 25151cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 25161cbb95d3SBarry Smith *f = PETSC_FALSE; 25171cbb95d3SBarry Smith PetscFunctionReturn(0); 25181cbb95d3SBarry Smith } 25191cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 25201cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 25211cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2522785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2523785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 25241cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 25251cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 25261cbb95d3SBarry Smith 25271cbb95d3SBarry Smith *f = PETSC_TRUE; 25281cbb95d3SBarry Smith for (i=0; i<ma; i++) { 25291cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 25301cbb95d3SBarry Smith PetscInt idc,idr; 25311cbb95d3SBarry Smith PetscScalar vc,vr; 25321cbb95d3SBarry Smith /* column/row index/value */ 25331cbb95d3SBarry Smith idc = adx[aptr[i]]; 25341cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 25351cbb95d3SBarry Smith vc = va[aptr[i]]; 25361cbb95d3SBarry Smith vr = vb[bptr[idc]]; 25371cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 25381cbb95d3SBarry Smith *f = PETSC_FALSE; 25391cbb95d3SBarry Smith goto done; 25401cbb95d3SBarry Smith } else { 25411cbb95d3SBarry Smith aptr[i]++; 25421cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 25431cbb95d3SBarry Smith } 25441cbb95d3SBarry Smith } 25451cbb95d3SBarry Smith } 25461cbb95d3SBarry Smith done: 25471cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 25481cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 25491cbb95d3SBarry Smith PetscFunctionReturn(0); 25501cbb95d3SBarry Smith } 25511cbb95d3SBarry Smith 2552ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25539e29f15eSvictorle { 2554dfbe8321SBarry Smith PetscErrorCode ierr; 25556e111a19SKarl Rupp 25569e29f15eSvictorle PetscFunctionBegin; 25575485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25589e29f15eSvictorle PetscFunctionReturn(0); 25599e29f15eSvictorle } 25609e29f15eSvictorle 2561ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25621cbb95d3SBarry Smith { 25631cbb95d3SBarry Smith PetscErrorCode ierr; 25646e111a19SKarl Rupp 25651cbb95d3SBarry Smith PetscFunctionBegin; 25661cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25671cbb95d3SBarry Smith PetscFunctionReturn(0); 25681cbb95d3SBarry Smith } 25691cbb95d3SBarry Smith 2570dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 257117ab2063SBarry Smith { 2572416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2573fff8e43fSBarry Smith const PetscScalar *l,*r; 2574fff8e43fSBarry Smith PetscScalar x; 257554f21887SBarry Smith MatScalar *v; 2576dfbe8321SBarry Smith PetscErrorCode ierr; 2577fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2578fff8e43fSBarry Smith const PetscInt *jj; 257917ab2063SBarry Smith 25803a40ed3dSBarry Smith PetscFunctionBegin; 258117ab2063SBarry Smith if (ll) { 25823ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 25833ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2584e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2585e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2586fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 25872e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 258817ab2063SBarry Smith for (i=0; i<m; i++) { 258917ab2063SBarry Smith x = l[i]; 2590416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25912205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 259217ab2063SBarry Smith } 2593fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2594efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 25952e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 259617ab2063SBarry Smith } 259717ab2063SBarry Smith if (rr) { 2598e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2599e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2600fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 26012e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(A,&v);CHKERRQ(ierr); 26022e5835c6SStefano Zampini jj = a->j; 26032205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 26042e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&v);CHKERRQ(ierr); 2605fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2606efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 260717ab2063SBarry Smith } 2608acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 26098c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2610c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2611e2cf4d64SStefano Zampini #endif 26123a40ed3dSBarry Smith PetscFunctionReturn(0); 261317ab2063SBarry Smith } 261417ab2063SBarry Smith 26157dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 261617ab2063SBarry Smith { 2617db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 26186849ba73SBarry Smith PetscErrorCode ierr; 2619d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 262097f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 26215d0c19d7SBarry Smith const PetscInt *irow,*icol; 26222e5835c6SStefano Zampini const PetscScalar *aa; 26235d0c19d7SBarry Smith PetscInt nrows,ncols; 262497f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 262554f21887SBarry Smith MatScalar *a_new,*mat_a; 2626416022c9SBarry Smith Mat C; 2627cdc6f3adSToby Isaac PetscBool stride; 262817ab2063SBarry Smith 26293a40ed3dSBarry Smith PetscFunctionBegin; 263017ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2631b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2632b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 263317ab2063SBarry Smith 2634251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2635ff718158SBarry Smith if (stride) { 2636ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2637ff718158SBarry Smith } else { 2638ff718158SBarry Smith first = 0; 2639ff718158SBarry Smith step = 0; 2640ff718158SBarry Smith } 2641fee21e36SBarry Smith if (stride && step == 1) { 264202834360SBarry Smith /* special case of contiguous rows */ 2643dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 264402834360SBarry Smith /* loop over new rows determining lens and starting points */ 264502834360SBarry Smith for (i=0; i<nrows; i++) { 2646bfeeae90SHong Zhang kstart = ai[irow[i]]; 2647a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2648a91a9bebSLisandro Dalcin starts[i] = kstart; 264902834360SBarry Smith for (k=kstart; k<kend; k++) { 2650bfeeae90SHong Zhang if (aj[k] >= first) { 265102834360SBarry Smith starts[i] = k; 265202834360SBarry Smith break; 265302834360SBarry Smith } 265402834360SBarry Smith } 2655a2744918SBarry Smith sum = 0; 265602834360SBarry Smith while (k < kend) { 2657bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2658a2744918SBarry Smith sum++; 265902834360SBarry Smith } 2660a2744918SBarry Smith lens[i] = sum; 266102834360SBarry Smith } 266202834360SBarry Smith /* create submatrix */ 2663cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 266497f1f81fSBarry Smith PetscInt n_cols,n_rows; 266508480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2666e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2667d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 266808480c60SBarry Smith C = *B; 26693a40ed3dSBarry Smith } else { 26703bef6203SJed Brown PetscInt rbs,cbs; 2671ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2672f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26733bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26743bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26753bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26767adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2677ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 267808480c60SBarry Smith } 2679db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2680db02288aSLois Curfman McInnes 268102834360SBarry Smith /* loop over rows inserting into submatrix */ 2682db02288aSLois Curfman McInnes a_new = c->a; 2683db02288aSLois Curfman McInnes j_new = c->j; 2684db02288aSLois Curfman McInnes i_new = c->i; 26852e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 268602834360SBarry Smith for (i=0; i<nrows; i++) { 2687a2744918SBarry Smith ii = starts[i]; 2688a2744918SBarry Smith lensi = lens[i]; 2689a2744918SBarry Smith for (k=0; k<lensi; k++) { 2690a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 269102834360SBarry Smith } 26922e5835c6SStefano Zampini ierr = PetscArraycpy(a_new,aa + starts[i],lensi);CHKERRQ(ierr); 2693a2744918SBarry Smith a_new += lensi; 2694a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2695a2744918SBarry Smith c->ilen[i] = lensi; 269602834360SBarry Smith } 26972e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 26980e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26993a40ed3dSBarry Smith } else { 270002834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 27011795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2702854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 27034dcab191SBarry Smith for (i=0; i<ncols; i++) { 2704d9ef940eSSatish 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); 27054dcab191SBarry Smith smap[icol[i]] = i+1; 27064dcab191SBarry Smith } 27074dcab191SBarry Smith 270802834360SBarry Smith /* determine lens of each row */ 270902834360SBarry Smith for (i=0; i<nrows; i++) { 2710bfeeae90SHong Zhang kstart = ai[irow[i]]; 271102834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 271202834360SBarry Smith lens[i] = 0; 271302834360SBarry Smith for (k=kstart; k<kend; k++) { 2714bfeeae90SHong Zhang if (smap[aj[k]]) { 271502834360SBarry Smith lens[i]++; 271602834360SBarry Smith } 271702834360SBarry Smith } 271802834360SBarry Smith } 271917ab2063SBarry Smith /* Create and fill new matrix */ 2720a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2721ace3abfcSBarry Smith PetscBool equal; 27220f5bd95cSBarry Smith 272399141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2724e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2725580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2726f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2727580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 272808480c60SBarry Smith C = *B; 27293a40ed3dSBarry Smith } else { 27303bef6203SJed Brown PetscInt rbs,cbs; 2731ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2732f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 27333bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 27343bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 27353bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 27367adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2737ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 273808480c60SBarry Smith } 27392e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 274099141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 274117ab2063SBarry Smith for (i=0; i<nrows; i++) { 274299141d43SSatish Balay row = irow[i]; 2743bfeeae90SHong Zhang kstart = ai[row]; 274499141d43SSatish Balay kend = kstart + a->ilen[row]; 2745bfeeae90SHong Zhang mat_i = c->i[i]; 274699141d43SSatish Balay mat_j = c->j + mat_i; 274799141d43SSatish Balay mat_a = c->a + mat_i; 274899141d43SSatish Balay mat_ilen = c->ilen + i; 274917ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2750bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2751ed480e8bSBarry Smith *mat_j++ = tcol - 1; 27522e5835c6SStefano Zampini *mat_a++ = aa[k]; 275399141d43SSatish Balay (*mat_ilen)++; 275499141d43SSatish Balay 275517ab2063SBarry Smith } 275617ab2063SBarry Smith } 275717ab2063SBarry Smith } 27582e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 275902834360SBarry Smith /* Free work space */ 276002834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2761606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2762606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2763cdc6f3adSToby Isaac /* sort */ 2764cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2765cdc6f3adSToby Isaac PetscInt ilen; 2766cdc6f3adSToby Isaac 2767cdc6f3adSToby Isaac mat_i = c->i[i]; 2768cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2769cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2770cdc6f3adSToby Isaac ilen = c->ilen[i]; 2771390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2772cdc6f3adSToby Isaac } 277302834360SBarry Smith } 27748c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2775b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2776305c6ccfSStefano Zampini #endif 27776d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27786d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 277917ab2063SBarry Smith 278017ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2781416022c9SBarry Smith *B = C; 27823a40ed3dSBarry Smith PetscFunctionReturn(0); 278317ab2063SBarry Smith } 278417ab2063SBarry Smith 2785fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 278682d44351SHong Zhang { 278782d44351SHong Zhang PetscErrorCode ierr; 278882d44351SHong Zhang Mat B; 278982d44351SHong Zhang 279082d44351SHong Zhang PetscFunctionBegin; 2791c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 279282d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 279382d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 279433d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 279582d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 279682d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 279782d44351SHong Zhang *subMat = B; 2798c2d650bdSHong Zhang } else { 2799c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2800c2d650bdSHong Zhang } 280182d44351SHong Zhang PetscFunctionReturn(0); 280282d44351SHong Zhang } 280382d44351SHong Zhang 28049a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2805a871dcd8SBarry Smith { 280663b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2807dfbe8321SBarry Smith PetscErrorCode ierr; 280863b91edcSBarry Smith Mat outA; 2809ace3abfcSBarry Smith PetscBool row_identity,col_identity; 281063b91edcSBarry Smith 28113a40ed3dSBarry Smith PetscFunctionBegin; 2812e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 28131df811f5SHong Zhang 2814b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2815b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2816a871dcd8SBarry Smith 281763b91edcSBarry Smith outA = inA; 2818d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2819f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2820f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 28212205254eSKarl Rupp 2822c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 28236bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 28242205254eSKarl Rupp 2825c3122656SLisandro Dalcin a->row = row; 28262205254eSKarl Rupp 2827c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 28286bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 28292205254eSKarl Rupp 2830c3122656SLisandro Dalcin a->col = col; 283163b91edcSBarry Smith 283236db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 28336bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 28344c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 28353bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2836f0ec6fceSSatish Balay 283794a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2838854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 28393bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 284094a9d846SBarry Smith } 284163b91edcSBarry Smith 2842f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2843137fb511SHong Zhang if (row_identity && col_identity) { 2844ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2845137fb511SHong Zhang } else { 2846719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2847137fb511SHong Zhang } 28483a40ed3dSBarry Smith PetscFunctionReturn(0); 2849a871dcd8SBarry Smith } 2850a871dcd8SBarry Smith 2851f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2852f0b747eeSBarry Smith { 2853f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2854dfa0f9e5SStefano Zampini PetscScalar *v; 2855efee365bSSatish Balay PetscErrorCode ierr; 2856c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 28573a40ed3dSBarry Smith 28583a40ed3dSBarry Smith PetscFunctionBegin; 2859dfa0f9e5SStefano Zampini ierr = MatSeqAIJGetArray(inA,&v);CHKERRQ(ierr); 2860c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 2861dfa0f9e5SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&alpha,v,&one)); 2862efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2863dfa0f9e5SStefano Zampini ierr = MatSeqAIJRestoreArray(inA,&v);CHKERRQ(ierr); 2864acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 28653a40ed3dSBarry Smith PetscFunctionReturn(0); 2866f0b747eeSBarry Smith } 2867f0b747eeSBarry Smith 2868f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 286916b64355SHong Zhang { 287016b64355SHong Zhang PetscErrorCode ierr; 287116b64355SHong Zhang PetscInt i; 287216b64355SHong Zhang 287316b64355SHong Zhang PetscFunctionBegin; 287416b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 287516b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 287616b64355SHong Zhang 287716b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 287816b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 287916b64355SHong Zhang } 288016b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 288116b64355SHong Zhang 288216b64355SHong Zhang if (submatj->rbuf1) { 288316b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 288416b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 288516b64355SHong Zhang } 288616b64355SHong Zhang 288716b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 288816b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 288916b64355SHong Zhang } 289016b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 289116b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 289216b64355SHong Zhang } 289316b64355SHong Zhang 289416b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 289516b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 289616b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 289716b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 289816b64355SHong Zhang #else 289916b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 290016b64355SHong Zhang #endif 290116b64355SHong Zhang 290216b64355SHong Zhang if (!submatj->allcolumns) { 290316b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 290416b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 290516b64355SHong Zhang #else 290616b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 290716b64355SHong Zhang #endif 290816b64355SHong Zhang } 290916b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 291016b64355SHong Zhang 291116b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 291216b64355SHong Zhang PetscFunctionReturn(0); 291316b64355SHong Zhang } 291416b64355SHong Zhang 29150fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 291616b64355SHong Zhang { 291716b64355SHong Zhang PetscErrorCode ierr; 291816b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 29195c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 292016b64355SHong Zhang 292116b64355SHong Zhang PetscFunctionBegin; 292234136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2923f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 292416b64355SHong Zhang PetscFunctionReturn(0); 292516b64355SHong Zhang } 292616b64355SHong Zhang 29272d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 29282d033e1fSHong Zhang { 29292d033e1fSHong Zhang PetscErrorCode ierr; 29302d033e1fSHong Zhang PetscInt i; 29310fb991dcSHong Zhang Mat C; 29320fb991dcSHong Zhang Mat_SeqAIJ *c; 29330fb991dcSHong Zhang Mat_SubSppt *submatj; 29342d033e1fSHong Zhang 29352d033e1fSHong Zhang PetscFunctionBegin; 29362d033e1fSHong Zhang for (i=0; i<n; i++) { 29370fb991dcSHong Zhang C = (*mat)[i]; 29380fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 29390fb991dcSHong Zhang submatj = c->submatis1; 29402d033e1fSHong Zhang if (submatj) { 2941682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 294234136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2943f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 294434136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 29452d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 29462d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 29472d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2948682e4c99SStefano Zampini } 29492d033e1fSHong Zhang } else { 29502d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 29512d033e1fSHong Zhang } 29522d033e1fSHong Zhang } 295386e85357SHong Zhang 295463a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 295563a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 295663a75b2aSHong Zhang 29572d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 29582d033e1fSHong Zhang PetscFunctionReturn(0); 29592d033e1fSHong Zhang } 29602d033e1fSHong Zhang 29617dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2962cddf8d76SBarry Smith { 2963dfbe8321SBarry Smith PetscErrorCode ierr; 296497f1f81fSBarry Smith PetscInt i; 2965cddf8d76SBarry Smith 29663a40ed3dSBarry Smith PetscFunctionBegin; 2967cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2968df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2969cddf8d76SBarry Smith } 2970cddf8d76SBarry Smith 2971cddf8d76SBarry Smith for (i=0; i<n; i++) { 29727dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2973cddf8d76SBarry Smith } 29743a40ed3dSBarry Smith PetscFunctionReturn(0); 2975cddf8d76SBarry Smith } 2976cddf8d76SBarry Smith 297797f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 29784dcbc457SBarry Smith { 2979e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29806849ba73SBarry Smith PetscErrorCode ierr; 29815d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 29825d0c19d7SBarry Smith const PetscInt *idx; 298397f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2984f1af5d2fSBarry Smith PetscBT table; 2985bbd702dbSSatish Balay 29863a40ed3dSBarry Smith PetscFunctionBegin; 2987d0f46423SBarry Smith m = A->rmap->n; 2988e4d965acSSatish Balay ai = a->i; 2989bfeeae90SHong Zhang aj = a->j; 29908a047759SSatish Balay 2991e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 299206763907SSatish Balay 2993854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 299453b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 299506763907SSatish Balay 2996e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2997b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2998e4d965acSSatish Balay isz = 0; 29996831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 3000e4d965acSSatish Balay 3001e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 30024dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 3003b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 3004e4d965acSSatish Balay 3005dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 3006e4d965acSSatish Balay for (j=0; j<n; ++j) { 30072205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 30084dcbc457SBarry Smith } 300906763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 30106bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 3011e4d965acSSatish Balay 301204a348a9SBarry Smith k = 0; 301304a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 301404a348a9SBarry Smith n = isz; 301506763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 3016e4d965acSSatish Balay row = nidx[k]; 3017e4d965acSSatish Balay start = ai[row]; 3018e4d965acSSatish Balay end = ai[row+1]; 301904a348a9SBarry Smith for (l = start; l<end; l++) { 3020efb16452SHong Zhang val = aj[l]; 30212205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 3022e4d965acSSatish Balay } 3023e4d965acSSatish Balay } 3024e4d965acSSatish Balay } 302570b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 3026e4d965acSSatish Balay } 302794bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 3028606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 30293a40ed3dSBarry Smith PetscFunctionReturn(0); 30304dcbc457SBarry Smith } 303117ab2063SBarry Smith 30320513a670SBarry Smith /* -------------------------------------------------------------- */ 3033dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 30340513a670SBarry Smith { 30350513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30366849ba73SBarry Smith PetscErrorCode ierr; 30373b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 30385d0c19d7SBarry Smith const PetscInt *row,*col; 30395d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 304056cd22aeSBarry Smith IS icolp,irowp; 30410298fd71SBarry Smith PetscInt *cwork = NULL; 30420298fd71SBarry Smith PetscScalar *vwork = NULL; 30430513a670SBarry Smith 30443a40ed3dSBarry Smith PetscFunctionBegin; 30454c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 304656cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 30474c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 304856cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 30490513a670SBarry Smith 30500513a670SBarry Smith /* determine lengths of permuted rows */ 3051854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 30522205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 3053ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 3054f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 305533d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 30567adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 3057ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 3058606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 30590513a670SBarry Smith 3060785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 30610513a670SBarry Smith for (i=0; i<m; i++) { 306232ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30632205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 3064cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 306532ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30660513a670SBarry Smith } 3067606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 30682205254eSKarl Rupp 30693c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 30702205254eSKarl Rupp 30718c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3072b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 30739fe5e383SStefano Zampini #endif 30740513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30750513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 307656cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 307756cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 30786bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 30796bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 30806768869dSprj- if (rowp == colp) { 3081dc29a518SPierre Jolivet ierr = MatPropagateSymmetryOptions(A,*B);CHKERRQ(ierr); 30826768869dSprj- } 30833a40ed3dSBarry Smith PetscFunctionReturn(0); 30840513a670SBarry Smith } 30850513a670SBarry Smith 3086dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3087cb5b572fSBarry Smith { 3088dfbe8321SBarry Smith PetscErrorCode ierr; 3089cb5b572fSBarry Smith 3090cb5b572fSBarry Smith PetscFunctionBegin; 309133f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 309233f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3093be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3094be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 30952e5835c6SStefano Zampini const PetscScalar *aa; 3096be6bf707SBarry Smith 30972e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 30984d805d7cSStefano 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]); 30992e5835c6SStefano Zampini ierr = PetscArraycpy(b->a,aa,a->i[A->rmap->n]);CHKERRQ(ierr); 3100cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 31012e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 3102cb5b572fSBarry Smith } else { 3103cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3104cb5b572fSBarry Smith } 3105cb5b572fSBarry Smith PetscFunctionReturn(0); 3106cb5b572fSBarry Smith } 3107cb5b572fSBarry Smith 31084994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3109273d9f13SBarry Smith { 3110dfbe8321SBarry Smith PetscErrorCode ierr; 3111273d9f13SBarry Smith 3112273d9f13SBarry Smith PetscFunctionBegin; 3113f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3114273d9f13SBarry Smith PetscFunctionReturn(0); 3115273d9f13SBarry Smith } 3116273d9f13SBarry Smith 3117f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 31186c0721eeSBarry Smith { 31196c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 31206e111a19SKarl Rupp 31216c0721eeSBarry Smith PetscFunctionBegin; 31226c0721eeSBarry Smith *array = a->a; 31236c0721eeSBarry Smith PetscFunctionReturn(0); 31246c0721eeSBarry Smith } 31256c0721eeSBarry Smith 3126f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 31276c0721eeSBarry Smith { 31286c0721eeSBarry Smith PetscFunctionBegin; 3129f38c1e66SStefano Zampini *array = NULL; 31306c0721eeSBarry Smith PetscFunctionReturn(0); 31316c0721eeSBarry Smith } 3132273d9f13SBarry Smith 31338229c054SShri Abhyankar /* 31348229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 31358229c054SShri Abhyankar have different nonzero structure. 31368229c054SShri Abhyankar */ 3137b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3138ec7775f6SShri Abhyankar { 3139b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3140ec7775f6SShri Abhyankar 3141ec7775f6SShri Abhyankar PetscFunctionBegin; 3142ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3143ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3144b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3145b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3146b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 31478af7cee1SJed Brown nnz[i] = 0; 31488af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3149b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3150b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 31518af7cee1SJed Brown nnz[i]++; 31528af7cee1SJed Brown } 31538af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3154ec7775f6SShri Abhyankar } 3155ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3156ec7775f6SShri Abhyankar } 3157ec7775f6SShri Abhyankar 3158b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3159b264fe52SHong Zhang { 3160b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3161b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3162b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3163b264fe52SHong Zhang PetscErrorCode ierr; 3164b264fe52SHong Zhang 3165b264fe52SHong Zhang PetscFunctionBegin; 3166b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3167b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3168b264fe52SHong Zhang PetscFunctionReturn(0); 3169b264fe52SHong Zhang } 3170b264fe52SHong Zhang 3171f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3172ac90fabeSBarry Smith { 3173dfbe8321SBarry Smith PetscErrorCode ierr; 3174ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3175ac90fabeSBarry Smith 3176ac90fabeSBarry Smith PetscFunctionBegin; 3177134adf20SPierre Jolivet if (str == UNKNOWN_NONZERO_PATTERN || (PetscDefined(USE_DEBUG) && str == SAME_NONZERO_PATTERN)) { 3178134adf20SPierre Jolivet PetscBool e = x->nz == y->nz ? PETSC_TRUE : PETSC_FALSE; 3179134adf20SPierre Jolivet if (e) { 318081fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 318181fa06acSBarry Smith if (e) { 318281fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 3183134adf20SPierre Jolivet if (e) str = SAME_NONZERO_PATTERN; 318481fa06acSBarry Smith } 318581fa06acSBarry Smith } 3186134adf20SPierre Jolivet if (!e && str == SAME_NONZERO_PATTERN) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MatStructure is not SAME_NONZERO_PATTERN"); 318781fa06acSBarry Smith } 3188ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 31892e5835c6SStefano Zampini const PetscScalar *xa; 31902e5835c6SStefano Zampini PetscScalar *ya,alpha = a; 319181fa06acSBarry Smith PetscBLASInt one = 1,bnz; 319281fa06acSBarry Smith 319381fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31942e5835c6SStefano Zampini ierr = MatSeqAIJGetArray(Y,&ya);CHKERRQ(ierr); 31952e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(X,&xa);CHKERRQ(ierr); 31962e5835c6SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,xa,&one,ya,&one)); 31972e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(X,&xa);CHKERRQ(ierr); 31982e5835c6SStefano Zampini ierr = MatSeqAIJRestoreArray(Y,&ya);CHKERRQ(ierr); 319941f5e1b1SStefano Zampini ierr = PetscLogFlops(2.0*bnz);CHKERRQ(ierr); 3200acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3201a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 3202ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3203ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3204ac90fabeSBarry Smith } else { 32058229c054SShri Abhyankar Mat B; 32068229c054SShri Abhyankar PetscInt *nnz; 3207785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3208ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3209bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 321081fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 32112e5835c6SStefano Zampini ierr = MatSetType(B,((PetscObject)Y)->type_name);CHKERRQ(ierr); 32128229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3213ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3214ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 321528be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 32168229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3217ac90fabeSBarry Smith } 3218ac90fabeSBarry Smith PetscFunctionReturn(0); 3219ac90fabeSBarry Smith } 3220ac90fabeSBarry Smith 32212726fb6dSPierre Jolivet PETSC_INTERN PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3222354c94deSBarry Smith { 3223354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3224354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3225354c94deSBarry Smith PetscInt i,nz; 3226354c94deSBarry Smith PetscScalar *a; 3227ce496241SStefano Zampini PetscErrorCode ierr; 3228354c94deSBarry Smith 3229354c94deSBarry Smith PetscFunctionBegin; 3230354c94deSBarry Smith nz = aij->nz; 3231ce496241SStefano Zampini ierr = MatSeqAIJGetArray(mat,&a);CHKERRQ(ierr); 32322205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 3233ce496241SStefano Zampini ierr = MatSeqAIJRestoreArray(mat,&a);CHKERRQ(ierr); 3234354c94deSBarry Smith #else 3235354c94deSBarry Smith PetscFunctionBegin; 3236354c94deSBarry Smith #endif 3237354c94deSBarry Smith PetscFunctionReturn(0); 3238354c94deSBarry Smith } 3239354c94deSBarry Smith 3240985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3241e34fafa9SBarry Smith { 3242e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3243e34fafa9SBarry Smith PetscErrorCode ierr; 3244d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3245e34fafa9SBarry Smith PetscReal atmp; 3246985db425SBarry Smith PetscScalar *x; 3247ce496241SStefano Zampini const MatScalar *aa,*av; 3248e34fafa9SBarry Smith 3249e34fafa9SBarry Smith PetscFunctionBegin; 3250e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3251ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3252ce496241SStefano Zampini aa = av; 3253e34fafa9SBarry Smith ai = a->i; 3254e34fafa9SBarry Smith aj = a->j; 3255e34fafa9SBarry Smith 3256985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3257475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3258e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3259e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3260e34fafa9SBarry Smith for (i=0; i<m; i++) { 3261e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3262e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3263985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3264985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3265985db425SBarry Smith aa++; aj++; 3266985db425SBarry Smith } 3267985db425SBarry Smith } 3268475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3269ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3270985db425SBarry Smith PetscFunctionReturn(0); 3271985db425SBarry Smith } 3272985db425SBarry Smith 3273985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3274985db425SBarry Smith { 3275985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3276985db425SBarry Smith PetscErrorCode ierr; 3277d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3278985db425SBarry Smith PetscScalar *x; 3279ce496241SStefano Zampini const MatScalar *aa,*av; 3280985db425SBarry Smith 3281985db425SBarry Smith PetscFunctionBegin; 3282e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3283ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3284ce496241SStefano Zampini aa = av; 3285985db425SBarry Smith ai = a->i; 3286985db425SBarry Smith aj = a->j; 3287985db425SBarry Smith 3288985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3289fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3290985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3291e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3292985db425SBarry Smith for (i=0; i<m; i++) { 3293985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3294d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3295985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3296985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3297985db425SBarry Smith x[i] = 0.0; 3298985db425SBarry Smith if (idx) { 3299985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3300985db425SBarry Smith if (aj[j] > j) { 3301985db425SBarry Smith idx[i] = j; 3302985db425SBarry Smith break; 3303985db425SBarry Smith } 3304985db425SBarry Smith } 33051a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 33061a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3307985db425SBarry Smith } 3308985db425SBarry Smith } 3309985db425SBarry Smith for (j=0; j<ncols; j++) { 3310985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3311985db425SBarry Smith aa++; aj++; 3312985db425SBarry Smith } 3313985db425SBarry Smith } 3314fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3315ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3316985db425SBarry Smith PetscFunctionReturn(0); 3317985db425SBarry Smith } 3318985db425SBarry Smith 3319c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3320c87e5d42SMatthew Knepley { 3321c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3322c87e5d42SMatthew Knepley PetscErrorCode ierr; 3323c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3324ce496241SStefano Zampini PetscScalar *x; 3325ce496241SStefano Zampini const MatScalar *aa,*av; 3326c87e5d42SMatthew Knepley 3327c87e5d42SMatthew Knepley PetscFunctionBegin; 3328ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3329ce496241SStefano Zampini aa = av; 3330c87e5d42SMatthew Knepley ai = a->i; 3331c87e5d42SMatthew Knepley aj = a->j; 3332c87e5d42SMatthew Knepley 3333c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3334f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3335c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3336f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3337c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3338c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3339f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3340f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3341f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3342f07e67edSHong Zhang x[i] = 0.0; 3343f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3344289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3345f07e67edSHong Zhang if (aj[j] > j) { 3346f07e67edSHong Zhang idx[i] = j; 33472205254eSKarl Rupp break; 33482205254eSKarl Rupp } 3349289a08f5SMatthew Knepley } 3350f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3351f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3352f07e67edSHong Zhang } 3353289a08f5SMatthew Knepley } 3354c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3355f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3356c87e5d42SMatthew Knepley aa++; aj++; 3357c87e5d42SMatthew Knepley } 3358c87e5d42SMatthew Knepley } 3359f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3360ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3361c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3362c87e5d42SMatthew Knepley } 3363c87e5d42SMatthew Knepley 3364985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3365985db425SBarry Smith { 3366985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3367985db425SBarry Smith PetscErrorCode ierr; 3368d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3369d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3370985db425SBarry Smith PetscScalar *x; 3371ce496241SStefano Zampini const MatScalar *aa,*av; 3372985db425SBarry Smith 3373985db425SBarry Smith PetscFunctionBegin; 3374e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3375ce496241SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 3376ce496241SStefano Zampini aa = av; 3377985db425SBarry Smith ai = a->i; 3378985db425SBarry Smith aj = a->j; 3379985db425SBarry Smith 3380985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3381fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3382985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3383f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3384985db425SBarry Smith for (i=0; i<m; i++) { 3385985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3386d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3387985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3388985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3389985db425SBarry Smith x[i] = 0.0; 3390985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3391985db425SBarry Smith for (j=0; j<ncols; j++) { 3392985db425SBarry Smith if (aj[j] > j) { 3393985db425SBarry Smith idx[i] = j; 3394985db425SBarry Smith break; 3395985db425SBarry Smith } 3396985db425SBarry Smith } 3397fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3398fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3399985db425SBarry Smith } 3400985db425SBarry Smith } 3401985db425SBarry Smith for (j=0; j<ncols; j++) { 3402985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3403985db425SBarry Smith aa++; aj++; 3404e34fafa9SBarry Smith } 3405e34fafa9SBarry Smith } 3406fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3407ce496241SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 3408e34fafa9SBarry Smith PetscFunctionReturn(0); 3409e34fafa9SBarry Smith } 3410bbead8a2SBarry Smith 3411713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3412bbead8a2SBarry Smith { 3413bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3414bbead8a2SBarry Smith PetscErrorCode ierr; 341533d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3416bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 34170da83c2eSBarry Smith const PetscReal shift = 0.0; 34181a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3419bbead8a2SBarry Smith 3420bbead8a2SBarry Smith PetscFunctionBegin; 3421a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 34224a0d0026SBarry Smith if (a->ibdiagvalid) { 34234a0d0026SBarry Smith if (values) *values = a->ibdiag; 34244a0d0026SBarry Smith PetscFunctionReturn(0); 34254a0d0026SBarry Smith } 3426bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3427bbead8a2SBarry Smith if (!a->ibdiag) { 3428785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 34293bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3430bbead8a2SBarry Smith } 3431bbead8a2SBarry Smith diag = a->ibdiag; 3432bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3433bbead8a2SBarry Smith /* factor and invert each block */ 3434bbead8a2SBarry Smith switch (bs) { 3435bbead8a2SBarry Smith case 1: 3436bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3437bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3438ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3439ec1892c8SHong Zhang if (allowzeropivot) { 34407b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 34417b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 34427b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 34437b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 34447b6c816cSBarry 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); 3445ec1892c8SHong Zhang } 3446bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3447bbead8a2SBarry Smith } 3448bbead8a2SBarry Smith break; 3449bbead8a2SBarry Smith case 2: 3450bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3451bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3452bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3453a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34547b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 345596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3456bbead8a2SBarry Smith diag += 4; 3457bbead8a2SBarry Smith } 3458bbead8a2SBarry Smith break; 3459bbead8a2SBarry Smith case 3: 3460bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3461bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3462bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3463a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34647b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 346596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3466bbead8a2SBarry Smith diag += 9; 3467bbead8a2SBarry Smith } 3468bbead8a2SBarry Smith break; 3469bbead8a2SBarry Smith case 4: 3470bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3471bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3472bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3473a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34747b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 347596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3476bbead8a2SBarry Smith diag += 16; 3477bbead8a2SBarry Smith } 3478bbead8a2SBarry Smith break; 3479bbead8a2SBarry Smith case 5: 3480bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3481bbead8a2SBarry 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; 3482bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3483a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34847b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 348596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3486bbead8a2SBarry Smith diag += 25; 3487bbead8a2SBarry Smith } 3488bbead8a2SBarry Smith break; 3489bbead8a2SBarry Smith case 6: 3490bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3491bbead8a2SBarry 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; 3492bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3493a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34947b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 349596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3496bbead8a2SBarry Smith diag += 36; 3497bbead8a2SBarry Smith } 3498bbead8a2SBarry Smith break; 3499bbead8a2SBarry Smith case 7: 3500bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3501bbead8a2SBarry 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; 3502bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3503a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 35047b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 350596b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3506bbead8a2SBarry Smith diag += 49; 3507bbead8a2SBarry Smith } 3508bbead8a2SBarry Smith break; 3509bbead8a2SBarry Smith default: 3510dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3511bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3512bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3513bbead8a2SBarry Smith IJ[j] = bs*i + j; 3514bbead8a2SBarry Smith } 3515bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 35165f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 35177b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 351896b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3519bbead8a2SBarry Smith diag += bs2; 3520bbead8a2SBarry Smith } 3521bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3522bbead8a2SBarry Smith } 3523bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3524bbead8a2SBarry Smith PetscFunctionReturn(0); 3525bbead8a2SBarry Smith } 3526bbead8a2SBarry Smith 352773a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 352873a71a0fSBarry Smith { 352973a71a0fSBarry Smith PetscErrorCode ierr; 353073a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 353173a71a0fSBarry Smith PetscScalar a; 353273a71a0fSBarry Smith PetscInt m,n,i,j,col; 353373a71a0fSBarry Smith 353473a71a0fSBarry Smith PetscFunctionBegin; 353573a71a0fSBarry Smith if (!x->assembled) { 353673a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 353773a71a0fSBarry Smith for (i=0; i<m; i++) { 353873a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 353973a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 354073a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 354173a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 354273a71a0fSBarry Smith } 354373a71a0fSBarry Smith } 3544e2ce353bSJunchao Zhang } else { 3545e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3546e2ce353bSJunchao Zhang } 3547ce496241SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 3548ce496241SStefano Zampini if (x->offloadmask != PETSC_OFFLOAD_UNALLOCATED) x->offloadmask = PETSC_OFFLOAD_CPU; 3549ce496241SStefano Zampini #endif 355073a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 355173a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 355273a71a0fSBarry Smith PetscFunctionReturn(0); 355373a71a0fSBarry Smith } 355473a71a0fSBarry Smith 3555679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3556679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3557679944adSJunchao Zhang { 3558679944adSJunchao Zhang PetscErrorCode ierr; 3559679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3560679944adSJunchao Zhang PetscScalar a; 3561679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3562679944adSJunchao Zhang 3563679944adSJunchao Zhang PetscFunctionBegin; 3564679944adSJunchao Zhang nskip = high - low; 3565679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3566679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3567679944adSJunchao Zhang for (i=0; i<m; i++) { 3568679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3569679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3570679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3571679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3572679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3573679944adSJunchao Zhang } 3574e2ce353bSJunchao Zhang } 3575679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3576679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3577679944adSJunchao Zhang PetscFunctionReturn(0); 3578679944adSJunchao Zhang } 3579679944adSJunchao Zhang 3580682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 35810a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3582cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3583cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3584cb5b572fSBarry Smith MatMult_SeqAIJ, 358597304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 35867c922b88SBarry Smith MatMultTranspose_SeqAIJ, 35877c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3588f4259b30SLisandro Dalcin NULL, 3589f4259b30SLisandro Dalcin NULL, 3590f4259b30SLisandro Dalcin NULL, 3591f4259b30SLisandro Dalcin /* 10*/ NULL, 3592cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3593f4259b30SLisandro Dalcin NULL, 359441f059aeSBarry Smith MatSOR_SeqAIJ, 359591e9d3e2SHong Zhang MatTranspose_SeqAIJ, 359697304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3597cb5b572fSBarry Smith MatEqual_SeqAIJ, 3598cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3599cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3600cb5b572fSBarry Smith MatNorm_SeqAIJ, 3601f4259b30SLisandro Dalcin /* 20*/ NULL, 3602cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3603cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3604cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3605d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3606f4259b30SLisandro Dalcin NULL, 3607f4259b30SLisandro Dalcin NULL, 3608f4259b30SLisandro Dalcin NULL, 3609f4259b30SLisandro Dalcin NULL, 36104994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3611f4259b30SLisandro Dalcin NULL, 3612f4259b30SLisandro Dalcin NULL, 3613f4259b30SLisandro Dalcin NULL, 3614f4259b30SLisandro Dalcin NULL, 3615d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3616f4259b30SLisandro Dalcin NULL, 3617f4259b30SLisandro Dalcin NULL, 3618cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3619f4259b30SLisandro Dalcin NULL, 3620d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 36217dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3622cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3623cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3624cb5b572fSBarry Smith MatCopy_SeqAIJ, 3625d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3626cb5b572fSBarry Smith MatScale_SeqAIJ, 36277d68702bSBarry Smith MatShift_SeqAIJ, 362879299369SBarry Smith MatDiagonalSet_SeqAIJ, 36296e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 363073a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 36313b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 36323b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 36333b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3634a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 363593dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3636f4259b30SLisandro Dalcin NULL, 3637f4259b30SLisandro Dalcin NULL, 3638cda55fadSBarry Smith MatPermute_SeqAIJ, 3639f4259b30SLisandro Dalcin NULL, 3640f4259b30SLisandro Dalcin /* 59*/ NULL, 3641b9b97703SBarry Smith MatDestroy_SeqAIJ, 3642b9b97703SBarry Smith MatView_SeqAIJ, 3643f4259b30SLisandro Dalcin NULL, 3644f4259b30SLisandro Dalcin NULL, 3645f4259b30SLisandro Dalcin /* 64*/ NULL, 3646321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3647f4259b30SLisandro Dalcin NULL, 3648f4259b30SLisandro Dalcin NULL, 3649f4259b30SLisandro Dalcin NULL, 3650d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3651c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3652f4259b30SLisandro Dalcin NULL, 3653f4259b30SLisandro Dalcin NULL, 3654f4259b30SLisandro Dalcin NULL, 3655f4259b30SLisandro Dalcin /* 74*/ NULL, 36563acb8795SBarry Smith MatFDColoringApply_AIJ, 3657f4259b30SLisandro Dalcin NULL, 3658f4259b30SLisandro Dalcin NULL, 3659f4259b30SLisandro Dalcin NULL, 36606ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3661f4259b30SLisandro Dalcin NULL, 3662f4259b30SLisandro Dalcin NULL, 3663f4259b30SLisandro Dalcin NULL, 3664bc011b1eSHong Zhang MatLoad_SeqAIJ, 3665d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 36661cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3667f4259b30SLisandro Dalcin NULL, 3668f4259b30SLisandro Dalcin NULL, 3669f4259b30SLisandro Dalcin NULL, 3670f4259b30SLisandro Dalcin /* 89*/ NULL, 3671f4259b30SLisandro Dalcin NULL, 367226be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3673f4259b30SLisandro Dalcin NULL, 3674f4259b30SLisandro Dalcin NULL, 36758fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3676f4259b30SLisandro Dalcin NULL, 3677f4259b30SLisandro Dalcin NULL, 36786fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3679f4259b30SLisandro Dalcin NULL, 36804222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3681f4259b30SLisandro Dalcin NULL, 3682f4259b30SLisandro Dalcin NULL, 368387d4246cSBarry Smith MatConjugate_SeqAIJ, 3684f4259b30SLisandro Dalcin NULL, 3685d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 368699cafbc1SBarry Smith MatRealPart_SeqAIJ, 3687f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3688f4259b30SLisandro Dalcin NULL, 3689f4259b30SLisandro Dalcin NULL, 3690cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3691f4259b30SLisandro Dalcin NULL, 36922af78befSBarry Smith MatGetRowMin_SeqAIJ, 3693f4259b30SLisandro Dalcin NULL, 3694599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3695f4259b30SLisandro Dalcin /*114*/ NULL, 3696f4259b30SLisandro Dalcin NULL, 3697f4259b30SLisandro Dalcin NULL, 3698f4259b30SLisandro Dalcin NULL, 3699f4259b30SLisandro Dalcin NULL, 3700f4259b30SLisandro Dalcin /*119*/ NULL, 3701f4259b30SLisandro Dalcin NULL, 3702f4259b30SLisandro Dalcin NULL, 3703f4259b30SLisandro Dalcin NULL, 3704b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 37050716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3706a873a8cdSSam Reynolds MatGetColumnReductions_SeqAIJ, 370737868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 37080da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3709f4259b30SLisandro Dalcin NULL, 3710f4259b30SLisandro Dalcin /*129*/ NULL, 3711f4259b30SLisandro Dalcin NULL, 3712f4259b30SLisandro Dalcin NULL, 371375648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3714b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3715b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 37162b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3717f4259b30SLisandro Dalcin NULL, 3718f4259b30SLisandro Dalcin NULL, 37193964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3720f4259b30SLisandro Dalcin /*139*/NULL, 3721f4259b30SLisandro Dalcin NULL, 3722f4259b30SLisandro Dalcin NULL, 37233a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 37249c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 37254222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 37264222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3727f4259b30SLisandro Dalcin NULL, 3728f4259b30SLisandro Dalcin NULL 37299e29f15eSvictorle }; 373017ab2063SBarry Smith 37317087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3732bef8e0ddSBarry Smith { 3733bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 373497f1f81fSBarry Smith PetscInt i,nz,n; 3735bef8e0ddSBarry Smith 3736bef8e0ddSBarry Smith PetscFunctionBegin; 3737bef8e0ddSBarry Smith nz = aij->maxnz; 3738d0f46423SBarry Smith n = mat->rmap->n; 3739bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3740bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3741bef8e0ddSBarry Smith } 3742bef8e0ddSBarry Smith aij->nz = nz; 3743bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3744bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3745bef8e0ddSBarry Smith } 3746bef8e0ddSBarry Smith PetscFunctionReturn(0); 3747bef8e0ddSBarry Smith } 3748bef8e0ddSBarry Smith 3749a3bb6f32SFande Kong /* 3750ddea5d60SJunchao Zhang * Given a sparse matrix with global column indices, compact it by using a local column space. 3751ddea5d60SJunchao Zhang * The result matrix helps saving memory in other algorithms, such as MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3752ddea5d60SJunchao Zhang */ 3753a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3754a3bb6f32SFande Kong { 3755a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3756a3bb6f32SFande Kong PetscTable gid1_lid1; 3757a3bb6f32SFande Kong PetscTablePosition tpos; 375825b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 375925b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3760a3bb6f32SFande Kong PetscErrorCode ierr; 3761a3bb6f32SFande Kong 3762a3bb6f32SFande Kong PetscFunctionBegin; 3763a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3764a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3765a3bb6f32SFande Kong /* use a table */ 3766a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3767a3bb6f32SFande Kong ec = 0; 376825b670f0SStefano Zampini for (i=0; i<nz; i++) { 376925b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 3770a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3771a3bb6f32SFande Kong if (!data) { 3772a3bb6f32SFande Kong /* one based table */ 3773a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3774a3bb6f32SFande Kong } 3775a3bb6f32SFande Kong } 3776a3bb6f32SFande Kong /* form array of columns we need */ 3777b3c64f9dSJunchao Zhang ierr = PetscMalloc1(ec,&garray);CHKERRQ(ierr); 3778a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3779a3bb6f32SFande Kong while (tpos) { 3780a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3781a3bb6f32SFande Kong gid--; 3782a3bb6f32SFande Kong lid--; 3783a3bb6f32SFande Kong garray[lid] = gid; 3784a3bb6f32SFande Kong } 3785a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3786a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3787a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3788a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3789a3bb6f32SFande Kong } 3790a3bb6f32SFande Kong /* compact out the extra columns in B */ 379125b670f0SStefano Zampini for (i=0; i<nz; i++) { 379225b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 3793a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3794a3bb6f32SFande Kong lid--; 379525b670f0SStefano Zampini jj[i] = lid; 3796a3bb6f32SFande Kong } 3797ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3798a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 379925b670f0SStefano Zampini ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3800a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3801a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3802a3bb6f32SFande Kong PetscFunctionReturn(0); 3803a3bb6f32SFande Kong } 3804a3bb6f32SFande Kong 3805bef8e0ddSBarry Smith /*@ 3806bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3807bef8e0ddSBarry Smith in the matrix. 3808bef8e0ddSBarry Smith 3809bef8e0ddSBarry Smith Input Parameters: 3810bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3811bef8e0ddSBarry Smith - indices - the column indices 3812bef8e0ddSBarry Smith 381315091d37SBarry Smith Level: advanced 381415091d37SBarry Smith 3815bef8e0ddSBarry Smith Notes: 3816bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3817bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3818bef8e0ddSBarry Smith of the MatSetValues() operation. 3819bef8e0ddSBarry Smith 3820bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3821d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3822bef8e0ddSBarry Smith 3823bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3824bef8e0ddSBarry Smith 3825b9617806SBarry Smith The indices should start with zero, not one. 3826b9617806SBarry Smith 3827bef8e0ddSBarry Smith @*/ 38287087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3829bef8e0ddSBarry Smith { 38304ac538c5SBarry Smith PetscErrorCode ierr; 3831bef8e0ddSBarry Smith 3832bef8e0ddSBarry Smith PetscFunctionBegin; 38330700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 38344482741eSBarry Smith PetscValidPointer(indices,2); 38354ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3836bef8e0ddSBarry Smith PetscFunctionReturn(0); 3837bef8e0ddSBarry Smith } 3838bef8e0ddSBarry Smith 3839be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3840be6bf707SBarry Smith 38417087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3842be6bf707SBarry Smith { 3843be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38446849ba73SBarry Smith PetscErrorCode ierr; 3845d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3846be6bf707SBarry Smith 3847be6bf707SBarry Smith PetscFunctionBegin; 3848169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3849be6bf707SBarry Smith 3850be6bf707SBarry Smith /* allocate space for values if not already there */ 3851be6bf707SBarry Smith if (!aij->saved_values) { 3852854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 38533bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3854be6bf707SBarry Smith } 3855be6bf707SBarry Smith 3856be6bf707SBarry Smith /* copy values over */ 3857580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3858be6bf707SBarry Smith PetscFunctionReturn(0); 3859be6bf707SBarry Smith } 3860be6bf707SBarry Smith 3861be6bf707SBarry Smith /*@ 3862be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3863be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3864be6bf707SBarry Smith nonlinear portion. 3865be6bf707SBarry Smith 3866be6bf707SBarry Smith Collect on Mat 3867be6bf707SBarry Smith 3868be6bf707SBarry Smith Input Parameters: 38690e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3870be6bf707SBarry Smith 387115091d37SBarry Smith Level: advanced 387215091d37SBarry Smith 3873be6bf707SBarry Smith Common Usage, with SNESSolve(): 3874be6bf707SBarry Smith $ Create Jacobian matrix 3875be6bf707SBarry Smith $ Set linear terms into matrix 3876be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3877be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3878be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3879512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3880be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3881be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3882be6bf707SBarry Smith $ In your Jacobian routine 3883be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3884be6bf707SBarry Smith $ Set nonlinear terms in matrix 3885be6bf707SBarry Smith 3886be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3887be6bf707SBarry Smith $ // build linear portion of Jacobian 3888512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3889be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3890be6bf707SBarry Smith $ loop over nonlinear iterations 3891be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3892be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3893be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3894be6bf707SBarry Smith $ Solve linear system with Jacobian 3895be6bf707SBarry Smith $ endloop 3896be6bf707SBarry Smith 3897be6bf707SBarry Smith Notes: 3898be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3899512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3900be6bf707SBarry Smith calling this routine. 3901be6bf707SBarry Smith 39020c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 39030c468ba9SBarry Smith and does not allocated additional space. 39040c468ba9SBarry Smith 3905be6bf707SBarry Smith .seealso: MatRetrieveValues() 3906be6bf707SBarry Smith 3907be6bf707SBarry Smith @*/ 39087087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3909be6bf707SBarry Smith { 39104ac538c5SBarry Smith PetscErrorCode ierr; 3911be6bf707SBarry Smith 3912be6bf707SBarry Smith PetscFunctionBegin; 39130700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3914e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3915e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39164ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3917be6bf707SBarry Smith PetscFunctionReturn(0); 3918be6bf707SBarry Smith } 3919be6bf707SBarry Smith 39207087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3921be6bf707SBarry Smith { 3922be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 39236849ba73SBarry Smith PetscErrorCode ierr; 3924d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3925be6bf707SBarry Smith 3926be6bf707SBarry Smith PetscFunctionBegin; 3927169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3928f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3929be6bf707SBarry Smith /* copy values over */ 3930580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3931be6bf707SBarry Smith PetscFunctionReturn(0); 3932be6bf707SBarry Smith } 3933be6bf707SBarry Smith 3934be6bf707SBarry Smith /*@ 3935be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3936be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3937be6bf707SBarry Smith nonlinear portion. 3938be6bf707SBarry Smith 3939be6bf707SBarry Smith Collect on Mat 3940be6bf707SBarry Smith 3941be6bf707SBarry Smith Input Parameters: 3942386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3943be6bf707SBarry Smith 394415091d37SBarry Smith Level: advanced 394515091d37SBarry Smith 3946be6bf707SBarry Smith .seealso: MatStoreValues() 3947be6bf707SBarry Smith 3948be6bf707SBarry Smith @*/ 39497087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3950be6bf707SBarry Smith { 39514ac538c5SBarry Smith PetscErrorCode ierr; 3952be6bf707SBarry Smith 3953be6bf707SBarry Smith PetscFunctionBegin; 39540700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3955e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3956e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 39574ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3958be6bf707SBarry Smith PetscFunctionReturn(0); 3959be6bf707SBarry Smith } 3960be6bf707SBarry Smith 3961be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 396217ab2063SBarry Smith /*@C 3963682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 39640d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 39656e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 396651c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 39672bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 396817ab2063SBarry Smith 3969d083f849SBarry Smith Collective 3970db81eaa0SLois Curfman McInnes 397117ab2063SBarry Smith Input Parameters: 3972db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 397317ab2063SBarry Smith . m - number of rows 397417ab2063SBarry Smith . n - number of columns 397517ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 397651c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39770298fd71SBarry Smith (possibly different for each row) or NULL 397817ab2063SBarry Smith 397917ab2063SBarry Smith Output Parameter: 3980416022c9SBarry Smith . A - the matrix 398117ab2063SBarry Smith 3982175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3983f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3984175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3985175b88e8SBarry Smith 3986b259b22eSLois Curfman McInnes Notes: 398749a6f317SBarry Smith If nnz is given then nz is ignored 398849a6f317SBarry Smith 398917ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 399017ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39910002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 399244cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 399317ab2063SBarry Smith 399417ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39950298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39963d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39976da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 399817ab2063SBarry Smith 3999682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 40004fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 4001682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 40026c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 40036c7ebb05SLois Curfman McInnes 40046c7ebb05SLois Curfman McInnes Options Database Keys: 4005698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 40069db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 400717ab2063SBarry Smith 4008027ccd11SLois Curfman McInnes Level: intermediate 4009027ccd11SLois Curfman McInnes 401069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 401136db0b34SBarry Smith 401217ab2063SBarry Smith @*/ 40137087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 401417ab2063SBarry Smith { 4015dfbe8321SBarry Smith PetscErrorCode ierr; 40166945ee14SBarry Smith 40173a40ed3dSBarry Smith PetscFunctionBegin; 4018f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 4019117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 4020c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 4021d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 4022273d9f13SBarry Smith PetscFunctionReturn(0); 4023273d9f13SBarry Smith } 4024273d9f13SBarry Smith 4025273d9f13SBarry Smith /*@C 4026273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 4027273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 4028273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 4029273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 4030273d9f13SBarry Smith 4031d083f849SBarry Smith Collective 4032273d9f13SBarry Smith 4033273d9f13SBarry Smith Input Parameters: 40341c4f3114SJed Brown + B - The matrix 4035273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 4036273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 40370298fd71SBarry Smith (possibly different for each row) or NULL 4038273d9f13SBarry Smith 4039273d9f13SBarry Smith Notes: 404049a6f317SBarry Smith If nnz is given then nz is ignored 404149a6f317SBarry Smith 4042273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 4043273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 4044273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 4045273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 4046273d9f13SBarry Smith 4047273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 40480298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 4049273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 4050273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 4051273d9f13SBarry Smith 4052aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 4053aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 4054aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 4055aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 4056aa95bbe8SBarry Smith 4057a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 4058a96a251dSBarry Smith entries or columns indices 4059a96a251dSBarry Smith 4060273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 4061273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 4062273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 4063273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 4064273d9f13SBarry Smith 4065273d9f13SBarry Smith Options Database Keys: 4066698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 406747b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 4068273d9f13SBarry Smith 4069273d9f13SBarry Smith Level: intermediate 4070273d9f13SBarry Smith 407119b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 407219b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 4073273d9f13SBarry Smith 4074273d9f13SBarry Smith @*/ 40757087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 4076273d9f13SBarry Smith { 40774ac538c5SBarry Smith PetscErrorCode ierr; 4078a23d5eceSKris Buschelman 4079a23d5eceSKris Buschelman PetscFunctionBegin; 40806ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40816ba663aaSJed Brown PetscValidType(B,1); 40824ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 4083a23d5eceSKris Buschelman PetscFunctionReturn(0); 4084a23d5eceSKris Buschelman } 4085a23d5eceSKris Buschelman 40867087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 4087a23d5eceSKris Buschelman { 4088273d9f13SBarry Smith Mat_SeqAIJ *b; 40892576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40906849ba73SBarry Smith PetscErrorCode ierr; 409197f1f81fSBarry Smith PetscInt i; 4092273d9f13SBarry Smith 4093273d9f13SBarry Smith PetscFunctionBegin; 40942576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4095a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4096c461c341SBarry Smith skipallocation = PETSC_TRUE; 4097c461c341SBarry Smith nz = 0; 4098c461c341SBarry Smith } 409926283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 410026283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4101899cda47SBarry Smith 4102435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 410360e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4104cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4105d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 410660e0710aSBarry 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]); 410760e0710aSBarry 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); 4108b73539f3SBarry Smith } 4109b73539f3SBarry Smith } 4110b73539f3SBarry Smith 4111273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 41122205254eSKarl Rupp 4113273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4114273d9f13SBarry Smith 4115ab93d7beSBarry Smith if (!skipallocation) { 41162ee49352SLisandro Dalcin if (!b->imax) { 4117071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4118071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4119071fcb05SBarry Smith } 4120071fcb05SBarry Smith if (!b->ilen) { 4121071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4122071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4123071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4124071fcb05SBarry Smith } else { 4125071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 41262ee49352SLisandro Dalcin } 4127846b4da1SFande Kong if (!b->ipre) { 4128846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4129846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4130846b4da1SFande Kong } 4131273d9f13SBarry Smith if (!nnz) { 4132435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4133c62bd62aSJed Brown else if (nz < 0) nz = 1; 41345d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4135d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4136d0f46423SBarry Smith nz = nz*B->rmap->n; 4137273d9f13SBarry Smith } else { 4138c73702f5SBarry Smith PetscInt64 nz64 = 0; 4139c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4140c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4141273d9f13SBarry Smith } 4142ab93d7beSBarry Smith 4143273d9f13SBarry Smith /* allocate the matrix space */ 414453dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 41452ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4146396832f4SHong Zhang if (B->structure_only) { 41475848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 41485848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4149396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4150396832f4SHong Zhang } else { 4151dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 41523bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4153396832f4SHong Zhang } 4154bfeeae90SHong Zhang b->i[0] = 0; 4155d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 41565da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 41575da197adSKris Buschelman } 4158396832f4SHong Zhang if (B->structure_only) { 4159396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4160396832f4SHong Zhang b->free_a = PETSC_FALSE; 4161396832f4SHong Zhang } else { 4162273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4163e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4164396832f4SHong Zhang } 4165e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4166c461c341SBarry Smith } else { 4167e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4168e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4169c461c341SBarry Smith } 4170273d9f13SBarry Smith 4171846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4172846b4da1SFande Kong /* reserve user-requested sparsity */ 4173580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4174846b4da1SFande Kong } 4175846b4da1SFande Kong 4176273d9f13SBarry Smith b->nz = 0; 4177273d9f13SBarry Smith b->maxnz = nz; 4178273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 41792205254eSKarl Rupp if (realalloc) { 41802205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 41812205254eSKarl Rupp } 4182cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4183cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4184273d9f13SBarry Smith PetscFunctionReturn(0); 4185273d9f13SBarry Smith } 4186273d9f13SBarry Smith 4187846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4188846b4da1SFande Kong { 4189846b4da1SFande Kong Mat_SeqAIJ *a; 4190a5bbaf83SFande Kong PetscInt i; 4191846b4da1SFande Kong PetscErrorCode ierr; 4192846b4da1SFande Kong 4193846b4da1SFande Kong PetscFunctionBegin; 4194846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 419514d0e64fSAlex Lindsay 419614d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 419714d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 419814d0e64fSAlex Lindsay 4199846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 42002c814fdeSFande Kong /* if no saved info, we error out */ 4201fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 42022c814fdeSFande Kong 4203fb4dc15dSAlex 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"); 42042c814fdeSFande Kong 4205580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4206580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4207846b4da1SFande Kong a->i[0] = 0; 4208846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4209846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4210846b4da1SFande Kong } 4211846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4212846b4da1SFande Kong a->nz = 0; 4213846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4214846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4215846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4216846b4da1SFande Kong A->assembled = PETSC_FALSE; 4217846b4da1SFande Kong PetscFunctionReturn(0); 4218846b4da1SFande Kong } 4219846b4da1SFande Kong 422058d36128SBarry Smith /*@ 4221a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4222a1661176SMatthew Knepley 4223a1661176SMatthew Knepley Input Parameters: 4224a1661176SMatthew Knepley + B - the matrix 4225a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4226a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4227a1661176SMatthew Knepley - v - optional values in the matrix 4228a1661176SMatthew Knepley 4229a1661176SMatthew Knepley Level: developer 4230a1661176SMatthew Knepley 42316a9b8d82SBarry Smith Notes: 423258d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 423358d36128SBarry Smith 42346a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 42356a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 42366a9b8d82SBarry Smith 42376a9b8d82SBarry Smith Developer Notes: 42386a9b8d82SBarry 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 42396a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 42406a9b8d82SBarry Smith 42416a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 42426a9b8d82SBarry Smith 42436a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4244a1661176SMatthew Knepley @*/ 4245a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4246a1661176SMatthew Knepley { 4247a1661176SMatthew Knepley PetscErrorCode ierr; 4248a1661176SMatthew Knepley 4249a1661176SMatthew Knepley PetscFunctionBegin; 42500700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 42516ba663aaSJed Brown PetscValidType(B,1); 42524ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4253a1661176SMatthew Knepley PetscFunctionReturn(0); 4254a1661176SMatthew Knepley } 4255a1661176SMatthew Knepley 42567087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4257a1661176SMatthew Knepley { 4258a1661176SMatthew Knepley PetscInt i; 4259a1661176SMatthew Knepley PetscInt m,n; 4260a1661176SMatthew Knepley PetscInt nz; 42616a9b8d82SBarry Smith PetscInt *nnz; 4262a1661176SMatthew Knepley PetscErrorCode ierr; 4263a1661176SMatthew Knepley 4264a1661176SMatthew Knepley PetscFunctionBegin; 426565e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4266779a8d59SSatish Balay 4267779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4268779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4269779a8d59SSatish Balay 4270779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4271854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4272a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4273b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 427465e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4275a1661176SMatthew Knepley nnz[i] = nz; 4276a1661176SMatthew Knepley } 4277a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4278a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4279a1661176SMatthew Knepley 4280a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4281071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4282a1661176SMatthew Knepley } 4283a1661176SMatthew Knepley 4284a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4285a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4286a1661176SMatthew Knepley 42877827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4288a1661176SMatthew Knepley PetscFunctionReturn(0); 4289a1661176SMatthew Knepley } 4290a1661176SMatthew Knepley 4291ad7e164aSPierre Jolivet /*@ 4292ad7e164aSPierre Jolivet MatSeqAIJKron - Computes C, the Kronecker product of A and B. 4293ad7e164aSPierre Jolivet 4294ad7e164aSPierre Jolivet Input Parameters: 4295ad7e164aSPierre Jolivet + A - left-hand side matrix 4296ad7e164aSPierre Jolivet . B - right-hand side matrix 4297ad7e164aSPierre Jolivet - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX 4298ad7e164aSPierre Jolivet 4299ad7e164aSPierre Jolivet Output Parameter: 4300ad7e164aSPierre Jolivet . C - Kronecker product of A and B 4301ad7e164aSPierre Jolivet 4302ad7e164aSPierre Jolivet Level: intermediate 4303ad7e164aSPierre Jolivet 4304ad7e164aSPierre Jolivet Notes: 4305ad7e164aSPierre 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(). 4306ad7e164aSPierre Jolivet 4307ad7e164aSPierre Jolivet .seealso: MatCreateSeqAIJ(), MATSEQAIJ, MATKAIJ, MatReuse 4308ad7e164aSPierre Jolivet @*/ 4309ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron(Mat A,Mat B,MatReuse reuse,Mat *C) 4310ad7e164aSPierre Jolivet { 4311ad7e164aSPierre Jolivet PetscErrorCode ierr; 4312ad7e164aSPierre Jolivet 4313ad7e164aSPierre Jolivet PetscFunctionBegin; 4314ad7e164aSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 4315ad7e164aSPierre Jolivet PetscValidType(A,1); 4316ad7e164aSPierre Jolivet PetscValidHeaderSpecific(B,MAT_CLASSID,2); 4317ad7e164aSPierre Jolivet PetscValidType(B,2); 4318ad7e164aSPierre Jolivet PetscValidPointer(C,4); 4319ad7e164aSPierre Jolivet if (reuse == MAT_REUSE_MATRIX) { 4320ad7e164aSPierre Jolivet PetscValidHeaderSpecific(*C,MAT_CLASSID,4); 4321ad7e164aSPierre Jolivet PetscValidType(*C,4); 4322ad7e164aSPierre Jolivet } 4323ad7e164aSPierre Jolivet ierr = PetscTryMethod(A,"MatSeqAIJKron_C",(Mat,Mat,MatReuse,Mat*),(A,B,reuse,C));CHKERRQ(ierr); 4324ad7e164aSPierre Jolivet PetscFunctionReturn(0); 4325ad7e164aSPierre Jolivet } 4326ad7e164aSPierre Jolivet 4327ad7e164aSPierre Jolivet PetscErrorCode MatSeqAIJKron_SeqAIJ(Mat A,Mat B,MatReuse reuse,Mat *C) 4328ad7e164aSPierre Jolivet { 4329ad7e164aSPierre Jolivet Mat newmat; 4330ad7e164aSPierre Jolivet Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4331ad7e164aSPierre Jolivet Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 4332ad7e164aSPierre Jolivet PetscScalar *v; 4333ad7e164aSPierre 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; 4334ad7e164aSPierre Jolivet PetscBool flg; 4335ad7e164aSPierre Jolivet PetscErrorCode ierr; 4336ad7e164aSPierre Jolivet 4337ad7e164aSPierre Jolivet PetscFunctionBegin; 4338ad7e164aSPierre Jolivet if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4339ad7e164aSPierre Jolivet if (!A->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4340ad7e164aSPierre Jolivet if (B->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 4341ad7e164aSPierre Jolivet if (!B->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 4342ad7e164aSPierre Jolivet ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&flg);CHKERRQ(ierr); 4343ad7e164aSPierre Jolivet if (!flg) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatType %s",((PetscObject)B)->type_name); 4344ad7e164aSPierre Jolivet if (reuse != MAT_INITIAL_MATRIX && reuse != MAT_REUSE_MATRIX) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatReuse %d",(int)reuse); 4345ad7e164aSPierre Jolivet if (reuse == MAT_INITIAL_MATRIX) { 4346ad7e164aSPierre Jolivet ierr = PetscMalloc2(am*bm+1,&i,a->i[am]*b->i[bm],&j);CHKERRQ(ierr); 4347ad7e164aSPierre Jolivet ierr = MatCreate(PETSC_COMM_SELF,&newmat);CHKERRQ(ierr); 4348ad7e164aSPierre Jolivet ierr = MatSetSizes(newmat,am*bm,an*bn,am*bm,an*bn);CHKERRQ(ierr); 4349ad7e164aSPierre Jolivet ierr = MatSetType(newmat,MATAIJ);CHKERRQ(ierr); 4350ad7e164aSPierre Jolivet i[0] = 0; 4351ad7e164aSPierre Jolivet for (m = 0; m < am; ++m) { 4352ad7e164aSPierre Jolivet for (p = 0; p < bm; ++p) { 4353ad7e164aSPierre Jolivet i[m*bm + p + 1] = i[m*bm + p] + (a->i[m+1] - a->i[m]) * (b->i[p+1] - b->i[p]); 4354ad7e164aSPierre Jolivet for (n = a->i[m]; n < a->i[m+1]; ++n) { 4355ad7e164aSPierre Jolivet for (q = b->i[p]; q < b->i[p+1]; ++q) { 4356ad7e164aSPierre Jolivet j[nnz++] = a->j[n]*bn + b->j[q]; 4357ad7e164aSPierre Jolivet } 4358ad7e164aSPierre Jolivet } 4359ad7e164aSPierre Jolivet } 4360ad7e164aSPierre Jolivet } 4361ad7e164aSPierre Jolivet ierr = MatSeqAIJSetPreallocationCSR(newmat,i,j,NULL);CHKERRQ(ierr); 4362ad7e164aSPierre Jolivet *C = newmat; 4363ad7e164aSPierre Jolivet ierr = PetscFree2(i,j);CHKERRQ(ierr); 4364ad7e164aSPierre Jolivet nnz = 0; 4365ad7e164aSPierre Jolivet } 4366ad7e164aSPierre Jolivet ierr = MatSeqAIJGetArray(*C,&v);CHKERRQ(ierr); 4367ad7e164aSPierre Jolivet for (m = 0; m < am; ++m) { 4368ad7e164aSPierre Jolivet for (p = 0; p < bm; ++p) { 4369ad7e164aSPierre Jolivet for (n = a->i[m]; n < a->i[m+1]; ++n) { 4370ad7e164aSPierre Jolivet for (q = b->i[p]; q < b->i[p+1]; ++q) { 4371ad7e164aSPierre Jolivet v[nnz++] = a->a[n] * b->a[q]; 4372ad7e164aSPierre Jolivet } 4373ad7e164aSPierre Jolivet } 4374ad7e164aSPierre Jolivet } 4375ad7e164aSPierre Jolivet } 4376ad7e164aSPierre Jolivet ierr = MatSeqAIJRestoreArray(*C,&v);CHKERRQ(ierr); 4377ad7e164aSPierre Jolivet PetscFunctionReturn(0); 4378ad7e164aSPierre Jolivet } 4379ad7e164aSPierre Jolivet 4380c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4381af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4382170fe5c8SBarry Smith 4383170fe5c8SBarry Smith /* 4384170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4385170fe5c8SBarry Smith 4386170fe5c8SBarry Smith n p p 43872da392ccSBarry Smith [ ] [ ] [ ] 43882da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 43892da392ccSBarry Smith [ ] [ ] [ ] 4390170fe5c8SBarry Smith 4391170fe5c8SBarry Smith */ 4392170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4393170fe5c8SBarry Smith { 4394170fe5c8SBarry Smith PetscErrorCode ierr; 4395170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4396170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4397170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 439886214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4399170fe5c8SBarry Smith const PetscInt *ii,*idx; 4400170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4401170fe5c8SBarry Smith PetscScalar *c,*c_q; 440286214ceeSStefano Zampini PetscInt clda = sub_c->lda; 440386214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4404170fe5c8SBarry Smith 4405170fe5c8SBarry Smith PetscFunctionBegin; 4406d0f46423SBarry Smith m = A->rmap->n; 4407d0f46423SBarry Smith n = A->cmap->n; 4408d0f46423SBarry Smith p = B->cmap->n; 4409170fe5c8SBarry Smith a = sub_a->v; 4410170fe5c8SBarry Smith b = sub_b->a; 4411170fe5c8SBarry Smith c = sub_c->v; 441286214ceeSStefano Zampini if (clda == m) { 4413580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 441486214ceeSStefano Zampini } else { 441586214ceeSStefano Zampini for (j=0;j<p;j++) 441686214ceeSStefano Zampini for (i=0;i<m;i++) 441786214ceeSStefano Zampini c[j*clda + i] = 0.0; 441886214ceeSStefano Zampini } 4419170fe5c8SBarry Smith ii = sub_b->i; 4420170fe5c8SBarry Smith idx = sub_b->j; 4421170fe5c8SBarry Smith for (i=0; i<n; i++) { 4422170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4423170fe5c8SBarry Smith while (q-->0) { 442486214ceeSStefano Zampini c_q = c + clda*(*idx); 442586214ceeSStefano Zampini a_q = a + alda*i; 4426854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4427170fe5c8SBarry Smith idx++; 4428170fe5c8SBarry Smith b++; 4429170fe5c8SBarry Smith } 4430170fe5c8SBarry Smith } 4431170fe5c8SBarry Smith PetscFunctionReturn(0); 4432170fe5c8SBarry Smith } 4433170fe5c8SBarry Smith 44344222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4435170fe5c8SBarry Smith { 4436170fe5c8SBarry Smith PetscErrorCode ierr; 4437d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 443886214ceeSStefano Zampini PetscBool cisdense; 4439170fe5c8SBarry Smith 4440170fe5c8SBarry Smith PetscFunctionBegin; 444160e0710aSBarry 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); 44424222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 44434222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 444486214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 444586214ceeSStefano Zampini if (!cisdense) { 444686214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 444786214ceeSStefano Zampini } 444886214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4449d73949e8SHong Zhang 44504222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4451170fe5c8SBarry Smith PetscFunctionReturn(0); 4452170fe5c8SBarry Smith } 4453170fe5c8SBarry Smith 4454170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 44550bad9183SKris Buschelman /*MC 4456fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 44570bad9183SKris Buschelman based on compressed sparse row format. 44580bad9183SKris Buschelman 44590bad9183SKris Buschelman Options Database Keys: 44600bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 44610bad9183SKris Buschelman 44620bad9183SKris Buschelman Level: beginner 44630bad9183SKris Buschelman 44640cd7f59aSBarry Smith Notes: 44650cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 44660cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 44670cd7f59aSBarry Smith in the matrix 44680cd7f59aSBarry Smith 44690cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 44700cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 44710cd7f59aSBarry Smith 44720cd7f59aSBarry Smith Developer Notes: 44730cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 44740cd7f59aSBarry Smith 4475f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 44760bad9183SKris Buschelman M*/ 44770bad9183SKris Buschelman 4478ccd284c7SBarry Smith /*MC 4479ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4480ccd284c7SBarry Smith 4481ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4482ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 44830cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4484ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4485ccd284c7SBarry Smith the above preallocation routines for simplicity. 4486ccd284c7SBarry Smith 4487ccd284c7SBarry Smith Options Database Keys: 4488ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4489ccd284c7SBarry Smith 449095452b02SPatrick Sanan Developer Notes: 4491ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4492ccd284c7SBarry Smith enough exist. 4493ccd284c7SBarry Smith 4494ccd284c7SBarry Smith Level: beginner 4495ccd284c7SBarry Smith 4496ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4497ccd284c7SBarry Smith M*/ 4498ccd284c7SBarry Smith 4499ccd284c7SBarry Smith /*MC 4500ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4501ccd284c7SBarry Smith 4502ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4503ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4504ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4505ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4506ccd284c7SBarry Smith the above preallocation routines for simplicity. 4507ccd284c7SBarry Smith 4508ccd284c7SBarry Smith Options Database Keys: 4509ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4510ccd284c7SBarry Smith 4511ccd284c7SBarry Smith Level: beginner 4512ccd284c7SBarry Smith 4513ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4514ccd284c7SBarry Smith M*/ 4515ccd284c7SBarry Smith 45167906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 45177906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 45187906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 45197906f579SHong Zhang #endif 4520d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4521d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4522d24d4204SJose E. Roman #endif 45237906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 45247906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 45257906f579SHong Zhang #endif 45267906f579SHong Zhang 4527d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4528c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 45294222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 45307906f579SHong Zhang 45318c778c55SBarry Smith /*@C 45328f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 45338c778c55SBarry Smith 45348c778c55SBarry Smith Not Collective 45358c778c55SBarry Smith 45368c778c55SBarry Smith Input Parameter: 4537579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 45388c778c55SBarry Smith 45398c778c55SBarry Smith Output Parameter: 45408c778c55SBarry Smith . array - pointer to the data 45418c778c55SBarry Smith 45428c778c55SBarry Smith Level: intermediate 45438c778c55SBarry Smith 4544774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 45458c778c55SBarry Smith @*/ 45468c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 45478c778c55SBarry Smith { 45488c778c55SBarry Smith PetscErrorCode ierr; 45498c778c55SBarry Smith 45508c778c55SBarry Smith PetscFunctionBegin; 45518c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 45522e5835c6SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 45532e5835c6SStefano Zampini if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 45542e5835c6SStefano Zampini #endif 45558c778c55SBarry Smith PetscFunctionReturn(0); 45568c778c55SBarry Smith } 45578c778c55SBarry Smith 455821e72a00SBarry Smith /*@C 45598f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 45608f1ea47aSStefano Zampini 45618f1ea47aSStefano Zampini Not Collective 45628f1ea47aSStefano Zampini 45638f1ea47aSStefano Zampini Input Parameter: 45648f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 45658f1ea47aSStefano Zampini 45668f1ea47aSStefano Zampini Output Parameter: 45678f1ea47aSStefano Zampini . array - pointer to the data 45688f1ea47aSStefano Zampini 45698f1ea47aSStefano Zampini Level: intermediate 45708f1ea47aSStefano Zampini 45718f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 45728f1ea47aSStefano Zampini @*/ 45738f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 45748f1ea47aSStefano Zampini { 45758c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4576c70f7ee4SJunchao Zhang PetscOffloadMask oval; 45778f1ea47aSStefano Zampini #endif 45788f1ea47aSStefano Zampini PetscErrorCode ierr; 45798f1ea47aSStefano Zampini 45808f1ea47aSStefano Zampini PetscFunctionBegin; 45818c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4582c70f7ee4SJunchao Zhang oval = A->offloadmask; 45838f1ea47aSStefano Zampini #endif 45848f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 45858c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4586c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 45878f1ea47aSStefano Zampini #endif 45888f1ea47aSStefano Zampini PetscFunctionReturn(0); 45898f1ea47aSStefano Zampini } 45908f1ea47aSStefano Zampini 45918f1ea47aSStefano Zampini /*@C 45928f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 45938f1ea47aSStefano Zampini 45948f1ea47aSStefano Zampini Not Collective 45958f1ea47aSStefano Zampini 45968f1ea47aSStefano Zampini Input Parameter: 45978f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 45988f1ea47aSStefano Zampini 45998f1ea47aSStefano Zampini Output Parameter: 46008f1ea47aSStefano Zampini . array - pointer to the data 46018f1ea47aSStefano Zampini 46028f1ea47aSStefano Zampini Level: intermediate 46038f1ea47aSStefano Zampini 46048f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 46058f1ea47aSStefano Zampini @*/ 46068f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 46078f1ea47aSStefano Zampini { 46088c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4609c70f7ee4SJunchao Zhang PetscOffloadMask oval; 46108f1ea47aSStefano Zampini #endif 46118f1ea47aSStefano Zampini PetscErrorCode ierr; 46128f1ea47aSStefano Zampini 46138f1ea47aSStefano Zampini PetscFunctionBegin; 46148c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4615c70f7ee4SJunchao Zhang oval = A->offloadmask; 46168f1ea47aSStefano Zampini #endif 46178f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 46188c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4619c70f7ee4SJunchao Zhang A->offloadmask = oval; 46208f1ea47aSStefano Zampini #endif 46218f1ea47aSStefano Zampini PetscFunctionReturn(0); 46228f1ea47aSStefano Zampini } 46238f1ea47aSStefano Zampini 46248f1ea47aSStefano Zampini /*@C 462521e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 462621e72a00SBarry Smith 462721e72a00SBarry Smith Not Collective 462821e72a00SBarry Smith 462921e72a00SBarry Smith Input Parameter: 4630579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 463121e72a00SBarry Smith 463221e72a00SBarry Smith Output Parameter: 463321e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 463421e72a00SBarry Smith 463521e72a00SBarry Smith Level: intermediate 463621e72a00SBarry Smith 463721e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 463821e72a00SBarry Smith @*/ 463921e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 464021e72a00SBarry Smith { 464121e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 464221e72a00SBarry Smith 464321e72a00SBarry Smith PetscFunctionBegin; 464421e72a00SBarry Smith *nz = aij->rmax; 464521e72a00SBarry Smith PetscFunctionReturn(0); 464621e72a00SBarry Smith } 464721e72a00SBarry Smith 46488c778c55SBarry Smith /*@C 4649579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 46508c778c55SBarry Smith 46518c778c55SBarry Smith Not Collective 46528c778c55SBarry Smith 46538c778c55SBarry Smith Input Parameters: 4654a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4655a2b725a8SWilliam Gropp - array - pointer to the data 46568c778c55SBarry Smith 46578c778c55SBarry Smith Level: intermediate 46588c778c55SBarry Smith 4659774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 46608c778c55SBarry Smith @*/ 46618c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 46628c778c55SBarry Smith { 46638c778c55SBarry Smith PetscErrorCode ierr; 46648c778c55SBarry Smith 46658c778c55SBarry Smith PetscFunctionBegin; 46668c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 46678c778c55SBarry Smith PetscFunctionReturn(0); 46688c778c55SBarry Smith } 46698c778c55SBarry Smith 467034b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 46715063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat,MatType,MatReuse,Mat*); 467202fe1965SBarry Smith #endif 46733d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 46745063d097SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat,MatType,MatReuse,Mat*); 46753d0639e7SStefano Zampini #endif 467602fe1965SBarry Smith 46778cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4678273d9f13SBarry Smith { 4679273d9f13SBarry Smith Mat_SeqAIJ *b; 4680dfbe8321SBarry Smith PetscErrorCode ierr; 468138baddfdSBarry Smith PetscMPIInt size; 4682273d9f13SBarry Smith 4683273d9f13SBarry Smith PetscFunctionBegin; 4684ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr); 4685e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4686273d9f13SBarry Smith 4687b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 46882205254eSKarl Rupp 4689b0a32e0cSBarry Smith B->data = (void*)b; 46902205254eSKarl Rupp 4691549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4692071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 46932205254eSKarl Rupp 4694f4259b30SLisandro Dalcin b->row = NULL; 4695f4259b30SLisandro Dalcin b->col = NULL; 4696f4259b30SLisandro Dalcin b->icol = NULL; 4697b810aeb4SBarry Smith b->reallocs = 0; 469836db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4699f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4700416022c9SBarry Smith b->nonew = 0; 4701f4259b30SLisandro Dalcin b->diag = NULL; 4702f4259b30SLisandro Dalcin b->solve_work = NULL; 4703f4259b30SLisandro Dalcin B->spptr = NULL; 4704f4259b30SLisandro Dalcin b->saved_values = NULL; 4705f4259b30SLisandro Dalcin b->idiag = NULL; 4706f4259b30SLisandro Dalcin b->mdiag = NULL; 4707f4259b30SLisandro Dalcin b->ssor_work = NULL; 470871f1c65dSBarry Smith b->omega = 1.0; 470971f1c65dSBarry Smith b->fshift = 0.0; 471071f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4711bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4712a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 471317ab2063SBarry Smith 471435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4715bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4716bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 47178c778c55SBarry Smith 4718b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4719bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4720bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4721b3866ffcSBarry Smith #endif 472217f1a0eaSHong Zhang 4723bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4724bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4725bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4726bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4727bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4728bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 47294dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 47309779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 47314a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4732191b95cbSRichard Tran Mills #endif 473334b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 473402fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 47354222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4736fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 473702fe1965SBarry Smith #endif 47383d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 47393d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 47403d0639e7SStefano Zampini #endif 4741bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4742af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4743af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4744af8000cdSHong Zhang #endif 4745d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4746d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4747d24d4204SJose E. Roman #endif 474863c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 474963c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 47504222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 475163c07aadSStefano Zampini #endif 4752b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4753d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4754c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4755bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4756bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4757bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4758846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4759bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4760bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 47614222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 47624222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 47634222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4764ad7e164aSPierre Jolivet ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJKron_C",MatSeqAIJKron_SeqAIJ);CHKERRQ(ierr); 47654108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 476617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 47674099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 47683a40ed3dSBarry Smith PetscFunctionReturn(0); 476917ab2063SBarry Smith } 477017ab2063SBarry Smith 4771b24902e0SBarry Smith /* 4772b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4773b24902e0SBarry Smith */ 4774ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 477517ab2063SBarry Smith { 47762a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 47776849ba73SBarry Smith PetscErrorCode ierr; 4778071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 477917ab2063SBarry Smith 47803a40ed3dSBarry Smith PetscFunctionBegin; 4781ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4782273d9f13SBarry Smith 4783d5f3da31SBarry Smith C->factortype = A->factortype; 4784f4259b30SLisandro Dalcin c->row = NULL; 4785f4259b30SLisandro Dalcin c->col = NULL; 4786f4259b30SLisandro Dalcin c->icol = NULL; 47876ad4291fSHong Zhang c->reallocs = 0; 478817ab2063SBarry Smith 4789*69272f91SPierre Jolivet C->assembled = A->assembled; 4790*69272f91SPierre Jolivet C->preallocated = A->preallocated; 479117ab2063SBarry Smith 4792*69272f91SPierre Jolivet if (A->preallocated) { 4793aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4794aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4795eec197d1SBarry Smith 4796071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4797071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4798071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4799071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 48003bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 480117ab2063SBarry Smith 480217ab2063SBarry Smith /* allocate the matrix space */ 4803f77e22a1SHong Zhang if (mallocmatspace) { 4804dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 48053bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 48062205254eSKarl Rupp 4807f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 48082205254eSKarl Rupp 4809580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 481017ab2063SBarry Smith if (m > 0) { 4811580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4812be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 48132e5835c6SStefano Zampini const PetscScalar *aa; 48142e5835c6SStefano Zampini 48152e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 48162e5835c6SStefano Zampini ierr = PetscArraycpy(c->a,aa,a->i[m]);CHKERRQ(ierr); 48172e5835c6SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 4818be6bf707SBarry Smith } else { 4819580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 482017ab2063SBarry Smith } 482108480c60SBarry Smith } 4822f77e22a1SHong Zhang } 482317ab2063SBarry Smith 48246ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4825416022c9SBarry Smith c->roworiented = a->roworiented; 4826416022c9SBarry Smith c->nonew = a->nonew; 4827416022c9SBarry Smith if (a->diag) { 4828854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4829071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 48303bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4831071fcb05SBarry Smith } else c->diag = NULL; 48322205254eSKarl Rupp 4833f4259b30SLisandro Dalcin c->solve_work = NULL; 4834f4259b30SLisandro Dalcin c->saved_values = NULL; 4835f4259b30SLisandro Dalcin c->idiag = NULL; 4836f4259b30SLisandro Dalcin c->ssor_work = NULL; 4837a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4838e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4839e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 48406ad4291fSHong Zhang 4841893ad86cSHong Zhang c->rmax = a->rmax; 4842416022c9SBarry Smith c->nz = a->nz; 48438ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4844754ec7b1SSatish Balay 48456ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 48466ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4847cd6b891eSBarry Smith if (a->compressedrow.use) { 48486ad4291fSHong Zhang i = a->compressedrow.nrows; 4849dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4850580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4851580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 485227ea64f8SHong Zhang } else { 485327ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 48540298fd71SBarry Smith c->compressedrow.i = NULL; 48550298fd71SBarry Smith c->compressedrow.rindex = NULL; 48566ad4291fSHong Zhang } 4857ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4858e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 48594846f1f5SKris Buschelman 48602205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4861*69272f91SPierre Jolivet } 4862140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 48633a40ed3dSBarry Smith PetscFunctionReturn(0); 486417ab2063SBarry Smith } 486517ab2063SBarry Smith 4866b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4867b24902e0SBarry Smith { 4868b24902e0SBarry Smith PetscErrorCode ierr; 4869b24902e0SBarry Smith 4870b24902e0SBarry Smith PetscFunctionBegin; 4871ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 48724b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4873cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 487433d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4875cfd3f464SBarry Smith } 4876a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4877f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4878b24902e0SBarry Smith PetscFunctionReturn(0); 4879b24902e0SBarry Smith } 4880b24902e0SBarry Smith 4881112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4882fbdbba38SShri Abhyankar { 488352f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 488452f91c60SVaclav Hapla PetscErrorCode ierr; 488552f91c60SVaclav Hapla 488652f91c60SVaclav Hapla PetscFunctionBegin; 488752f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 488852f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4889c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4890c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 489152f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 489252f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 489352f91c60SVaclav Hapla if (isbinary) { 489452f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 489552f91c60SVaclav Hapla } else if (ishdf5) { 489652f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 489752f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 489852f91c60SVaclav Hapla #else 489952f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 490052f91c60SVaclav Hapla #endif 490152f91c60SVaclav Hapla } else { 490252f91c60SVaclav 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); 490352f91c60SVaclav Hapla } 490452f91c60SVaclav Hapla PetscFunctionReturn(0); 490552f91c60SVaclav Hapla } 490652f91c60SVaclav Hapla 49073ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 490852f91c60SVaclav Hapla { 49093ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4910fbdbba38SShri Abhyankar PetscErrorCode ierr; 49113ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4912fbdbba38SShri Abhyankar 4913fbdbba38SShri Abhyankar PetscFunctionBegin; 49143ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4915bbead8a2SBarry Smith 49163ea6fe3dSLisandro Dalcin /* read in matrix header */ 49173ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 49183ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4919fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 49203ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 49213ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4922bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4923fbdbba38SShri Abhyankar 49243ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 49253ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 49263ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 49273ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 49283ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 49293ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 49303ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 49313ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 49323ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 49333ea6fe3dSLisandro Dalcin 49343ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 49353ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 49363ea6fe3dSLisandro 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); 49373ea6fe3dSLisandro Dalcin 4938fbdbba38SShri Abhyankar /* read in row lengths */ 49393ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 49403ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 49413ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 49423ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 49433ea6fe3dSLisandro 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); 49443ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 49453ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 49463ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 494760e0710aSBarry 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); 49483ea6fe3dSLisandro Dalcin /* store row lengths */ 49493ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 49503ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4951fbdbba38SShri Abhyankar 49523ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 49533ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 49543ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 49553ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 49563ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 49573ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4958fbdbba38SShri Abhyankar 49593ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49603ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4961fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4962fbdbba38SShri Abhyankar } 4963fbdbba38SShri Abhyankar 4964ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 49657264ac53SSatish Balay { 49667264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4967dfbe8321SBarry Smith PetscErrorCode ierr; 4968eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4969eeffb40dSHong Zhang PetscInt k; 4970eeffb40dSHong Zhang #endif 49717264ac53SSatish Balay 49723a40ed3dSBarry Smith PetscFunctionBegin; 4973bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4974d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4975ca44d042SBarry Smith *flg = PETSC_FALSE; 4976ca44d042SBarry Smith PetscFunctionReturn(0); 4977bcd2baecSBarry Smith } 49787264ac53SSatish Balay 49797264ac53SSatish Balay /* if the a->i are the same */ 4980580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4981abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 49827264ac53SSatish Balay 49837264ac53SSatish Balay /* if a->j are the same */ 4984580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4985abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4986bcd2baecSBarry Smith 4987bcd2baecSBarry Smith /* if a->a are the same */ 4988eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4989eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4990eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4991eeffb40dSHong Zhang *flg = PETSC_FALSE; 49923a40ed3dSBarry Smith PetscFunctionReturn(0); 4993eeffb40dSHong Zhang } 4994eeffb40dSHong Zhang } 4995eeffb40dSHong Zhang #else 4996580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4997eeffb40dSHong Zhang #endif 4998eeffb40dSHong Zhang PetscFunctionReturn(0); 49997264ac53SSatish Balay } 500036db0b34SBarry Smith 500105869f15SSatish Balay /*@ 500236db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 500336db0b34SBarry Smith provided by the user. 500436db0b34SBarry Smith 5005d083f849SBarry Smith Collective 500636db0b34SBarry Smith 500736db0b34SBarry Smith Input Parameters: 500836db0b34SBarry Smith + comm - must be an MPI communicator of size 1 500936db0b34SBarry Smith . m - number of rows 501036db0b34SBarry Smith . n - number of columns 5011483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 501236db0b34SBarry Smith . j - column indices 501336db0b34SBarry Smith - a - matrix values 501436db0b34SBarry Smith 501536db0b34SBarry Smith Output Parameter: 501636db0b34SBarry Smith . mat - the matrix 501736db0b34SBarry Smith 501836db0b34SBarry Smith Level: intermediate 501936db0b34SBarry Smith 502036db0b34SBarry Smith Notes: 50210551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 5022292fb18eSBarry Smith once the matrix is destroyed and not before 502336db0b34SBarry Smith 502436db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 502536db0b34SBarry Smith 5026bfeeae90SHong Zhang The i and j indices are 0 based 502736db0b34SBarry Smith 5028a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 5029a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 50308eef79e4SBarry Smith as shown 5031a4552177SSatish Balay 50328eef79e4SBarry Smith $ 1 0 0 50338eef79e4SBarry Smith $ 2 0 3 50348eef79e4SBarry Smith $ 4 5 6 50358eef79e4SBarry Smith $ 50368eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 50378eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 50388eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 5039a4552177SSatish Balay 504069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 504136db0b34SBarry Smith 504236db0b34SBarry Smith @*/ 5043c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 504436db0b34SBarry Smith { 5045dfbe8321SBarry Smith PetscErrorCode ierr; 5046cbcfb4deSHong Zhang PetscInt ii; 504736db0b34SBarry Smith Mat_SeqAIJ *aij; 5048cbcfb4deSHong Zhang PetscInt jj; 504936db0b34SBarry Smith 505036db0b34SBarry Smith PetscFunctionBegin; 505141096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 5052f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 5053f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 5054a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 5055ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 5056f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 5057ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 5058071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 5059071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 5060ab93d7beSBarry Smith 506136db0b34SBarry Smith aij->i = i; 506236db0b34SBarry Smith aij->j = j; 506336db0b34SBarry Smith aij->a = a; 506436db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 506536db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 5066e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 5067e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 506836db0b34SBarry Smith 506936db0b34SBarry Smith for (ii=0; ii<m; ii++) { 507036db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 507176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 507260e0710aSBarry 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]); 50739985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 5074a061629eSStefano 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); 5075a061629eSStefano 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); 50769985e31cSBarry Smith } 507736db0b34SBarry Smith } 507876bd3646SJed Brown } 507976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 508036db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 508160e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 508260e0710aSBarry 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]); 508336db0b34SBarry Smith } 508476bd3646SJed Brown } 508536db0b34SBarry Smith 5086b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5087b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 508836db0b34SBarry Smith PetscFunctionReturn(0); 508936db0b34SBarry Smith } 509080ef6e79SMatthew G Knepley /*@C 5091d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 50928a0b0e6bSVictor Minden provided by the user. 50938a0b0e6bSVictor Minden 5094d083f849SBarry Smith Collective 50958a0b0e6bSVictor Minden 50968a0b0e6bSVictor Minden Input Parameters: 50978a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 50988a0b0e6bSVictor Minden . m - number of rows 50998a0b0e6bSVictor Minden . n - number of columns 51008a0b0e6bSVictor Minden . i - row indices 51018a0b0e6bSVictor Minden . j - column indices 51021230e6d1SVictor Minden . a - matrix values 51031230e6d1SVictor Minden . nz - number of nonzeros 51041230e6d1SVictor Minden - idx - 0 or 1 based 51058a0b0e6bSVictor Minden 51068a0b0e6bSVictor Minden Output Parameter: 51078a0b0e6bSVictor Minden . mat - the matrix 51088a0b0e6bSVictor Minden 51098a0b0e6bSVictor Minden Level: intermediate 51108a0b0e6bSVictor Minden 51118a0b0e6bSVictor Minden Notes: 51129e99939fSJunchao 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, 51139e99939fSJunchao Zhang the input data expected is as shown 51149e99939fSJunchao Zhang .vb 51158a0b0e6bSVictor Minden 1 0 0 51168a0b0e6bSVictor Minden 2 0 3 51178a0b0e6bSVictor Minden 4 5 6 51188a0b0e6bSVictor Minden 51198a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 51208a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 51218a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 51229e99939fSJunchao Zhang .ve 51238a0b0e6bSVictor Minden 512469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 51258a0b0e6bSVictor Minden 51268a0b0e6bSVictor Minden @*/ 5127c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 51288a0b0e6bSVictor Minden { 51298a0b0e6bSVictor Minden PetscErrorCode ierr; 5130d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 51318a0b0e6bSVictor Minden 51328a0b0e6bSVictor Minden PetscFunctionBegin; 51331795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 51341230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 5135c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 51361230e6d1SVictor Minden } 51378a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 51388a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 51398a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 51401230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 51411230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 51421230e6d1SVictor Minden if (idx) { 51431230e6d1SVictor Minden row = i[ii] - 1; 51441230e6d1SVictor Minden col = j[ii] - 1; 51451230e6d1SVictor Minden } else { 51461230e6d1SVictor Minden row = i[ii]; 51471230e6d1SVictor Minden col = j[ii]; 51488a0b0e6bSVictor Minden } 51491230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 51508a0b0e6bSVictor Minden } 51518a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 51528a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5153d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 51548a0b0e6bSVictor Minden PetscFunctionReturn(0); 51558a0b0e6bSVictor Minden } 515636db0b34SBarry Smith 5157acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 5158acf2f550SJed Brown { 5159acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5160acf2f550SJed Brown PetscErrorCode ierr; 5161acf2f550SJed Brown 5162acf2f550SJed Brown PetscFunctionBegin; 5163acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5164acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 51652205254eSKarl Rupp 5166acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 5167acf2f550SJed Brown PetscFunctionReturn(0); 5168acf2f550SJed Brown } 5169acf2f550SJed Brown 51709c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 51719c8f2541SHong Zhang { 51729c8f2541SHong Zhang PetscErrorCode ierr; 51738761c3d6SHong Zhang PetscMPIInt size; 51749c8f2541SHong Zhang 51759c8f2541SHong Zhang PetscFunctionBegin; 5176ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 51777bbdc51dSHong Zhang if (size == 1) { 51787bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 51797bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 51807bbdc51dSHong Zhang } else { 51818761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 51827bbdc51dSHong Zhang } 51838761c3d6SHong Zhang } else { 51849c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 51858761c3d6SHong Zhang } 51869c8f2541SHong Zhang PetscFunctionReturn(0); 51879c8f2541SHong Zhang } 51889c8f2541SHong Zhang 518981824310SBarry Smith /* 519053dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 519153dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 519253dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 519353dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 519453dd7562SDmitry Karpeev */ 519553dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 519653dd7562SDmitry Karpeev { 519753dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 519853dd7562SDmitry Karpeev PetscErrorCode ierr; 519953dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 520053dd7562SDmitry Karpeev PetscBool seqaij; 520153dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 520253dd7562SDmitry Karpeev PetscScalar v; 520353dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 520453dd7562SDmitry Karpeev 520553dd7562SDmitry Karpeev PetscFunctionBegin; 520653dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 520753dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 52084099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 520953dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 521053dd7562SDmitry Karpeev if (rowemb) { 521153dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 521253dd7562SDmitry 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); 521353dd7562SDmitry Karpeev } else { 52146c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 521553dd7562SDmitry Karpeev } 521653dd7562SDmitry Karpeev if (colemb) { 521753dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 521853dd7562SDmitry 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); 521953dd7562SDmitry Karpeev } else { 522053dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 522153dd7562SDmitry Karpeev } 522253dd7562SDmitry Karpeev 522353dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 522453dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 522553dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 522653dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 522753dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 522853dd7562SDmitry Karpeev } 522953dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 523053dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 523153dd7562SDmitry Karpeev } 523253dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 523353dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 523453dd7562SDmitry Karpeev } 523553dd7562SDmitry Karpeev count = 0; 523653dd7562SDmitry Karpeev rowindices = NULL; 523753dd7562SDmitry Karpeev colindices = NULL; 523853dd7562SDmitry Karpeev if (rowemb) { 523953dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 524053dd7562SDmitry Karpeev } 524153dd7562SDmitry Karpeev if (colemb) { 524253dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 524353dd7562SDmitry Karpeev } 524453dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 524553dd7562SDmitry Karpeev PetscInt row; 524653dd7562SDmitry Karpeev row = i; 524753dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 524853dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 524953dd7562SDmitry Karpeev PetscInt col; 525053dd7562SDmitry Karpeev col = Baij->j[count]; 525153dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 525253dd7562SDmitry Karpeev v = Baij->a[count]; 525353dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 525453dd7562SDmitry Karpeev ++count; 525553dd7562SDmitry Karpeev } 525653dd7562SDmitry Karpeev } 525753dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 525853dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 525953dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 526053dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 526153dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 526253dd7562SDmitry Karpeev PetscFunctionReturn(0); 526353dd7562SDmitry Karpeev } 526453dd7562SDmitry Karpeev 52654099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 52664099cc6bSBarry Smith 52674099cc6bSBarry Smith /*@C 52684099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 52694099cc6bSBarry Smith 52704099cc6bSBarry Smith Collective on Mat 52714099cc6bSBarry Smith 52724099cc6bSBarry Smith Input Parameters: 52734099cc6bSBarry Smith + mat - the matrix object 52744099cc6bSBarry Smith - matype - matrix type 52754099cc6bSBarry Smith 52764099cc6bSBarry Smith Options Database Key: 52774099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 52784099cc6bSBarry Smith 52794099cc6bSBarry Smith Level: intermediate 52804099cc6bSBarry Smith 52814099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 52824099cc6bSBarry Smith @*/ 52834099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 52844099cc6bSBarry Smith { 5285fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 52864099cc6bSBarry Smith PetscBool sametype; 52874099cc6bSBarry Smith 52884099cc6bSBarry Smith PetscFunctionBegin; 52894099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 52904099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 52914099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 52924099cc6bSBarry Smith 52934099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 52944099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 52954099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 52964099cc6bSBarry Smith PetscFunctionReturn(0); 52974099cc6bSBarry Smith } 52984099cc6bSBarry Smith 52994099cc6bSBarry Smith /*@C 53004099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 53014099cc6bSBarry Smith 53024099cc6bSBarry Smith Not Collective 53034099cc6bSBarry Smith 53044099cc6bSBarry Smith Input Parameters: 53054099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 53064099cc6bSBarry Smith - function - routine to convert to subtype 53074099cc6bSBarry Smith 53084099cc6bSBarry Smith Notes: 53094099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 53104099cc6bSBarry Smith 53114099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 53124099cc6bSBarry Smith $ -mat_seqaij_type my_mat 53134099cc6bSBarry Smith 53144099cc6bSBarry Smith Level: advanced 53154099cc6bSBarry Smith 53164099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 53174099cc6bSBarry Smith 53184099cc6bSBarry Smith Level: advanced 53194099cc6bSBarry Smith @*/ 5320388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 53214099cc6bSBarry Smith { 53224099cc6bSBarry Smith PetscErrorCode ierr; 53234099cc6bSBarry Smith 53244099cc6bSBarry Smith PetscFunctionBegin; 53259cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 53264099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 53274099cc6bSBarry Smith PetscFunctionReturn(0); 53284099cc6bSBarry Smith } 53294099cc6bSBarry Smith 53304099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 53314099cc6bSBarry Smith 53324099cc6bSBarry Smith /*@C 53334099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 53344099cc6bSBarry Smith 53354099cc6bSBarry Smith Not Collective 53364099cc6bSBarry Smith 53374099cc6bSBarry Smith Level: advanced 53384099cc6bSBarry Smith 53394099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 53404099cc6bSBarry Smith @*/ 53414099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 53424099cc6bSBarry Smith { 53434099cc6bSBarry Smith PetscErrorCode ierr; 53444099cc6bSBarry Smith 53454099cc6bSBarry Smith PetscFunctionBegin; 53464099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 53474099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 53484099cc6bSBarry Smith 53494099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 53504099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 53514dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 53529779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 53536b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5354485f9817SRichard Tran Mills #endif 53555063d097SStefano Zampini #if defined(PETSC_HAVE_CUDA) 53565063d097SStefano Zampini ierr = MatSeqAIJRegister(MATSEQAIJCUSPARSE, MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 53575063d097SStefano Zampini #endif 53585063d097SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 53595063d097SStefano Zampini ierr = MatSeqAIJRegister(MATSEQAIJKOKKOS, MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 53605063d097SStefano Zampini #endif 53614099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 53624099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 53634099cc6bSBarry Smith #endif 53644099cc6bSBarry Smith PetscFunctionReturn(0); 53654099cc6bSBarry Smith } 536653dd7562SDmitry Karpeev 536753dd7562SDmitry Karpeev /* 536881824310SBarry Smith Special version for direct calls from Fortran 536981824310SBarry Smith */ 5370af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 537181824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 537281824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 537381824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 537481824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 537581824310SBarry Smith #endif 537681824310SBarry Smith 537781824310SBarry Smith /* Change these macros so can be used in void function */ 537881824310SBarry Smith #undef CHKERRQ 5379ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 538081824310SBarry Smith #undef SETERRQ2 5381e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 53824994cf47SJed Brown #undef SETERRQ3 53834994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 538481824310SBarry Smith 538519caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 538681824310SBarry Smith { 538781824310SBarry Smith Mat A = *AA; 538881824310SBarry Smith PetscInt m = *mm, n = *nn; 538981824310SBarry Smith InsertMode is = *isis; 539081824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 539181824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 539281824310SBarry Smith PetscInt *imax,*ai,*ailen; 539381824310SBarry Smith PetscErrorCode ierr; 539481824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 539554f21887SBarry Smith MatScalar *ap,value,*aa; 5396ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5397ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 539881824310SBarry Smith 539981824310SBarry Smith PetscFunctionBegin; 54004994cf47SJed Brown MatCheckPreallocated(A,1); 540181824310SBarry Smith imax = a->imax; 540281824310SBarry Smith ai = a->i; 540381824310SBarry Smith ailen = a->ilen; 540481824310SBarry Smith aj = a->j; 540581824310SBarry Smith aa = a->a; 540681824310SBarry Smith 540781824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 540881824310SBarry Smith row = im[k]; 540981824310SBarry Smith if (row < 0) continue; 5410cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 541181824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 541281824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 541381824310SBarry Smith low = 0; 541481824310SBarry Smith high = nrow; 541581824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 541681824310SBarry Smith if (in[l] < 0) continue; 5417cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 541881824310SBarry Smith col = in[l]; 54192205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 54202205254eSKarl Rupp else value = v[k + l*m]; 54212205254eSKarl Rupp 542281824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 542381824310SBarry Smith 54242205254eSKarl Rupp if (col <= lastcol) low = 0; 54252205254eSKarl Rupp else high = nrow; 542681824310SBarry Smith lastcol = col; 542781824310SBarry Smith while (high-low > 5) { 542881824310SBarry Smith t = (low+high)/2; 542981824310SBarry Smith if (rp[t] > col) high = t; 543081824310SBarry Smith else low = t; 543181824310SBarry Smith } 543281824310SBarry Smith for (i=low; i<high; i++) { 543381824310SBarry Smith if (rp[i] > col) break; 543481824310SBarry Smith if (rp[i] == col) { 543581824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 543681824310SBarry Smith else ap[i] = value; 543781824310SBarry Smith goto noinsert; 543881824310SBarry Smith } 543981824310SBarry Smith } 544081824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 544181824310SBarry Smith if (nonew == 1) goto noinsert; 5442ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5443fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 544481824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 544581824310SBarry Smith /* shift up all the later entries in this row */ 544681824310SBarry Smith for (ii=N; ii>=i; ii--) { 544781824310SBarry Smith rp[ii+1] = rp[ii]; 544881824310SBarry Smith ap[ii+1] = ap[ii]; 544981824310SBarry Smith } 545081824310SBarry Smith rp[i] = col; 545181824310SBarry Smith ap[i] = value; 5452e56f5c9eSBarry Smith A->nonzerostate++; 545381824310SBarry Smith noinsert:; 545481824310SBarry Smith low = i + 1; 545581824310SBarry Smith } 545681824310SBarry Smith ailen[row] = nrow; 545781824310SBarry Smith } 545881824310SBarry Smith PetscFunctionReturnVoid(); 545981824310SBarry Smith } 5460