1d5d45c9bSBarry Smith /* 23369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 3d5d45c9bSBarry Smith matrix storage format. 4d5d45c9bSBarry Smith */ 53369ce9aSBarry Smith 67c4f633dSBarry Smith 7c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 8c6db04a5SJed Brown #include <petscblaslapack.h> 9c6db04a5SJed Brown #include <petscbt.h> 10af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 110716a85fSBarry Smith 124099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetTypeFromOptions(Mat A) 134099cc6bSBarry Smith { 144099cc6bSBarry Smith PetscErrorCode ierr; 154099cc6bSBarry Smith PetscBool flg; 164099cc6bSBarry Smith char type[256]; 174099cc6bSBarry Smith 184099cc6bSBarry Smith PetscFunctionBegin; 194099cc6bSBarry Smith ierr = PetscObjectOptionsBegin((PetscObject)A); 204099cc6bSBarry Smith ierr = PetscOptionsFList("-mat_seqaij_type","Matrix SeqAIJ type","MatSeqAIJSetType",MatSeqAIJList,"seqaij",type,256,&flg);CHKERRQ(ierr); 214099cc6bSBarry Smith if (flg) { 224099cc6bSBarry Smith ierr = MatSeqAIJSetType(A,type);CHKERRQ(ierr); 234099cc6bSBarry Smith } 244099cc6bSBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 254099cc6bSBarry Smith PetscFunctionReturn(0); 264099cc6bSBarry Smith } 274099cc6bSBarry Smith 280716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 290716a85fSBarry Smith { 300716a85fSBarry Smith PetscErrorCode ierr; 310716a85fSBarry Smith PetscInt i,m,n; 320716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 330716a85fSBarry Smith 340716a85fSBarry Smith PetscFunctionBegin; 350716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 36580bdb30SBarry Smith ierr = PetscArrayzero(norms,n);CHKERRQ(ierr); 370716a85fSBarry Smith if (type == NORM_2) { 380716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 390716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 400716a85fSBarry Smith } 410716a85fSBarry Smith } else if (type == NORM_1) { 420716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 430716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 440716a85fSBarry Smith } 450716a85fSBarry Smith } else if (type == NORM_INFINITY) { 460716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 470716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 480716a85fSBarry Smith } 490716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 500716a85fSBarry Smith 510716a85fSBarry Smith if (type == NORM_2) { 528f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 530716a85fSBarry Smith } 540716a85fSBarry Smith PetscFunctionReturn(0); 550716a85fSBarry Smith } 560716a85fSBarry Smith 573a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 583a062f41SBarry Smith { 593a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 603a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 613a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 623a062f41SBarry Smith PetscInt *rows; 633a062f41SBarry Smith PetscErrorCode ierr; 643a062f41SBarry Smith 653a062f41SBarry Smith PetscFunctionBegin; 663a062f41SBarry Smith for (i=0; i<m; i++) { 673a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 683a062f41SBarry Smith cnt++; 693a062f41SBarry Smith } 703a062f41SBarry Smith } 713a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 723a062f41SBarry Smith cnt = 0; 733a062f41SBarry Smith for (i=0; i<m; i++) { 743a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 753a062f41SBarry Smith rows[cnt] = i; 763a062f41SBarry Smith cnt++; 773a062f41SBarry Smith } 783a062f41SBarry Smith } 793a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 803a062f41SBarry Smith PetscFunctionReturn(0); 813a062f41SBarry Smith } 823a062f41SBarry Smith 83f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 846ce1633cSBarry Smith { 856ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 866ce1633cSBarry Smith const MatScalar *aa = a->a; 876ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 88b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 896ce1633cSBarry Smith PetscInt *rows; 906ce1633cSBarry Smith PetscErrorCode ierr; 916ce1633cSBarry Smith 926ce1633cSBarry Smith PetscFunctionBegin; 936ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 946ce1633cSBarry Smith diag = a->diag; 956ce1633cSBarry Smith for (i=0; i<m; i++) { 96b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 976ce1633cSBarry Smith cnt++; 986ce1633cSBarry Smith } 996ce1633cSBarry Smith } 100785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 1016ce1633cSBarry Smith cnt = 0; 1026ce1633cSBarry Smith for (i=0; i<m; i++) { 103b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 1046ce1633cSBarry Smith rows[cnt++] = i; 1056ce1633cSBarry Smith } 1066ce1633cSBarry Smith } 107f1f41ecbSJed Brown *nrows = cnt; 108f1f41ecbSJed Brown *zrows = rows; 109f1f41ecbSJed Brown PetscFunctionReturn(0); 110f1f41ecbSJed Brown } 111f1f41ecbSJed Brown 112f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 113f1f41ecbSJed Brown { 114f1f41ecbSJed Brown PetscInt nrows,*rows; 115f1f41ecbSJed Brown PetscErrorCode ierr; 116f1f41ecbSJed Brown 117f1f41ecbSJed Brown PetscFunctionBegin; 1180298fd71SBarry Smith *zrows = NULL; 119f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 120ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1216ce1633cSBarry Smith PetscFunctionReturn(0); 1226ce1633cSBarry Smith } 1236ce1633cSBarry Smith 124b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 125b3a44c85SBarry Smith { 126b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 127b3a44c85SBarry Smith const MatScalar *aa; 128b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 129b3a44c85SBarry Smith const PetscInt *ii; 130b3a44c85SBarry Smith PetscInt n,i,j,*rows; 131b3a44c85SBarry Smith PetscErrorCode ierr; 132b3a44c85SBarry Smith 133b3a44c85SBarry Smith PetscFunctionBegin; 134f4259b30SLisandro Dalcin *keptrows = NULL; 135b3a44c85SBarry Smith ii = a->i; 136b3a44c85SBarry Smith for (i=0; i<m; i++) { 137b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 138b3a44c85SBarry Smith if (!n) { 139b3a44c85SBarry Smith cnt++; 140b3a44c85SBarry Smith goto ok1; 141b3a44c85SBarry Smith } 142b3a44c85SBarry Smith aa = a->a + ii[i]; 143b3a44c85SBarry Smith for (j=0; j<n; j++) { 144b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 145b3a44c85SBarry Smith } 146b3a44c85SBarry Smith cnt++; 147b3a44c85SBarry Smith ok1:; 148b3a44c85SBarry Smith } 149b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 150854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 151b3a44c85SBarry Smith cnt = 0; 152b3a44c85SBarry Smith for (i=0; i<m; i++) { 153b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 154b3a44c85SBarry Smith if (!n) continue; 155b3a44c85SBarry Smith aa = a->a + ii[i]; 156b3a44c85SBarry Smith for (j=0; j<n; j++) { 157b3a44c85SBarry Smith if (aa[j] != 0.0) { 158b3a44c85SBarry Smith rows[cnt++] = i; 159b3a44c85SBarry Smith break; 160b3a44c85SBarry Smith } 161b3a44c85SBarry Smith } 162b3a44c85SBarry Smith } 163b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 164b3a44c85SBarry Smith PetscFunctionReturn(0); 165b3a44c85SBarry Smith } 166b3a44c85SBarry Smith 1677087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 16879299369SBarry Smith { 16979299369SBarry Smith PetscErrorCode ierr; 17079299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 17199e65526SBarry Smith PetscInt i,m = Y->rmap->n; 17299e65526SBarry Smith const PetscInt *diag; 17354f21887SBarry Smith MatScalar *aa = aij->a; 17499e65526SBarry Smith const PetscScalar *v; 175ace3abfcSBarry Smith PetscBool missing; 1768c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 177837a59e1SRichard Tran Mills PetscBool inserted = PETSC_FALSE; 178837a59e1SRichard Tran Mills #endif 17979299369SBarry Smith 18079299369SBarry Smith PetscFunctionBegin; 18109f38230SBarry Smith if (Y->assembled) { 1820298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 18309f38230SBarry Smith if (!missing) { 18479299369SBarry Smith diag = aij->diag; 18599e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 18679299369SBarry Smith if (is == INSERT_VALUES) { 1878c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 188837a59e1SRichard Tran Mills inserted = PETSC_TRUE; 189837a59e1SRichard Tran Mills #endif 19079299369SBarry Smith for (i=0; i<m; i++) { 19179299369SBarry Smith aa[diag[i]] = v[i]; 19279299369SBarry Smith } 19379299369SBarry Smith } else { 19479299369SBarry Smith for (i=0; i<m; i++) { 1958c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 196837a59e1SRichard Tran Mills if (v[i] != 0.0) inserted = PETSC_TRUE; 197837a59e1SRichard Tran Mills #endif 19879299369SBarry Smith aa[diag[i]] += v[i]; 19979299369SBarry Smith } 20079299369SBarry Smith } 2018c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 202837a59e1SRichard Tran Mills if (inserted) Y->offloadmask = PETSC_OFFLOAD_CPU; 203837a59e1SRichard Tran Mills #endif 20499e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 20579299369SBarry Smith PetscFunctionReturn(0); 20679299369SBarry Smith } 207acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 20809f38230SBarry Smith } 20909f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 21009f38230SBarry Smith PetscFunctionReturn(0); 21109f38230SBarry Smith } 21279299369SBarry Smith 2131a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 21417ab2063SBarry Smith { 215416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 216dfbe8321SBarry Smith PetscErrorCode ierr; 21797f1f81fSBarry Smith PetscInt i,ishift; 21817ab2063SBarry Smith 2193a40ed3dSBarry Smith PetscFunctionBegin; 220d0f46423SBarry Smith *m = A->rmap->n; 2213a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 222bfeeae90SHong Zhang ishift = 0; 22353e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 2242462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 225bfeeae90SHong Zhang } else if (oshift == 1) { 2261a83f524SJed Brown PetscInt *tia; 227d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2283b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 229854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2301a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2311a83f524SJed Brown *ia = tia; 232ecc77c7aSBarry Smith if (ja) { 2331a83f524SJed Brown PetscInt *tja; 234854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2351a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2361a83f524SJed Brown *ja = tja; 237ecc77c7aSBarry Smith } 2386945ee14SBarry Smith } else { 239ecc77c7aSBarry Smith *ia = a->i; 240ecc77c7aSBarry Smith if (ja) *ja = a->j; 241a2ce50c7SBarry Smith } 2423a40ed3dSBarry Smith PetscFunctionReturn(0); 243a2744918SBarry Smith } 244a2744918SBarry Smith 2451a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2466945ee14SBarry Smith { 247dfbe8321SBarry Smith PetscErrorCode ierr; 2486945ee14SBarry Smith 2493a40ed3dSBarry Smith PetscFunctionBegin; 2503a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 251bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 252606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 253ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 254bcd2baecSBarry Smith } 2553a40ed3dSBarry Smith PetscFunctionReturn(0); 25617ab2063SBarry Smith } 25717ab2063SBarry Smith 2581a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2593b2fbd54SBarry Smith { 2603b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 261dfbe8321SBarry Smith PetscErrorCode ierr; 262d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 26397f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2643b2fbd54SBarry Smith 2653a40ed3dSBarry Smith PetscFunctionBegin; 266899cda47SBarry Smith *nn = n; 2673a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2683b2fbd54SBarry Smith if (symmetric) { 2692462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2703b2fbd54SBarry Smith } else { 271b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 272854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 273b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 2743b2fbd54SBarry Smith jj = a->j; 2753b2fbd54SBarry Smith for (i=0; i<nz; i++) { 276bfeeae90SHong Zhang collengths[jj[i]]++; 2773b2fbd54SBarry Smith } 2783b2fbd54SBarry Smith cia[0] = oshift; 2793b2fbd54SBarry Smith for (i=0; i<n; i++) { 2803b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2813b2fbd54SBarry Smith } 282580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 2833b2fbd54SBarry Smith jj = a->j; 284a93ec695SBarry Smith for (row=0; row<m; row++) { 285a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 286a93ec695SBarry Smith for (i=0; i<mr; i++) { 287bfeeae90SHong Zhang col = *jj++; 2882205254eSKarl Rupp 2893b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2903b2fbd54SBarry Smith } 2913b2fbd54SBarry Smith } 292606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2933b2fbd54SBarry Smith *ia = cia; *ja = cja; 2943b2fbd54SBarry Smith } 2953a40ed3dSBarry Smith PetscFunctionReturn(0); 2963b2fbd54SBarry Smith } 2973b2fbd54SBarry Smith 2981a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2993b2fbd54SBarry Smith { 300dfbe8321SBarry Smith PetscErrorCode ierr; 301606d414cSSatish Balay 3023a40ed3dSBarry Smith PetscFunctionBegin; 3033a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 3043b2fbd54SBarry Smith 305606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 306606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 3073a40ed3dSBarry Smith PetscFunctionReturn(0); 3083b2fbd54SBarry Smith } 3093b2fbd54SBarry Smith 3107cee066cSHong Zhang /* 3117cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 3127cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 313040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 3147cee066cSHong Zhang */ 3157cee066cSHong 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) 3167cee066cSHong Zhang { 3177cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3187cee066cSHong Zhang PetscErrorCode ierr; 3197cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 320071fcb05SBarry Smith PetscInt nz = a->i[m],row,mr,col,tmp; 3217cee066cSHong Zhang PetscInt *cspidx; 322071fcb05SBarry Smith const PetscInt *jj; 3237cee066cSHong Zhang 3247cee066cSHong Zhang PetscFunctionBegin; 3257cee066cSHong Zhang *nn = n; 3267cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 327625f6d37SHong Zhang 328b9e7e5c1SBarry Smith ierr = PetscCalloc1(n,&collengths);CHKERRQ(ierr); 329854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 330b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cja);CHKERRQ(ierr); 331b9e7e5c1SBarry Smith ierr = PetscMalloc1(nz,&cspidx);CHKERRQ(ierr); 3327cee066cSHong Zhang jj = a->j; 3337cee066cSHong Zhang for (i=0; i<nz; i++) { 3347cee066cSHong Zhang collengths[jj[i]]++; 3357cee066cSHong Zhang } 3367cee066cSHong Zhang cia[0] = oshift; 3377cee066cSHong Zhang for (i=0; i<n; i++) { 3387cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3397cee066cSHong Zhang } 340580bdb30SBarry Smith ierr = PetscArrayzero(collengths,n);CHKERRQ(ierr); 3417cee066cSHong Zhang jj = a->j; 3427cee066cSHong Zhang for (row=0; row<m; row++) { 3437cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3447cee066cSHong Zhang for (i=0; i<mr; i++) { 3457cee066cSHong Zhang col = *jj++; 346071fcb05SBarry Smith tmp = cia[col] + collengths[col]++ - oshift; 347071fcb05SBarry Smith cspidx[tmp] = a->i[row] + i; /* index of a->j */ 348071fcb05SBarry Smith cja[tmp] = row + oshift; 3497cee066cSHong Zhang } 3507cee066cSHong Zhang } 3517cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 352071fcb05SBarry Smith *ia = cia; 353071fcb05SBarry Smith *ja = cja; 3547cee066cSHong Zhang *spidx = cspidx; 3557cee066cSHong Zhang PetscFunctionReturn(0); 3567cee066cSHong Zhang } 3577cee066cSHong Zhang 3587cee066cSHong 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) 3597cee066cSHong Zhang { 3607cee066cSHong Zhang PetscErrorCode ierr; 3617cee066cSHong Zhang 3627cee066cSHong Zhang PetscFunctionBegin; 3635243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3647cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3657cee066cSHong Zhang PetscFunctionReturn(0); 3667cee066cSHong Zhang } 3677cee066cSHong Zhang 36887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 36987d4246cSBarry Smith { 37087d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 37187d4246cSBarry Smith PetscInt *ai = a->i; 37287d4246cSBarry Smith PetscErrorCode ierr; 37387d4246cSBarry Smith 37487d4246cSBarry Smith PetscFunctionBegin; 375580bdb30SBarry Smith ierr = PetscArraycpy(a->a+ai[row],v,ai[row+1]-ai[row]);CHKERRQ(ierr); 3768c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 377c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && ai[row+1]-ai[row]) A->offloadmask = PETSC_OFFLOAD_CPU; 378e2cf4d64SStefano Zampini #endif 37987d4246cSBarry Smith PetscFunctionReturn(0); 38087d4246cSBarry Smith } 38187d4246cSBarry Smith 382bd04181cSBarry Smith /* 383bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 384bd04181cSBarry Smith 385bd04181cSBarry Smith - a single row of values is set with each call 386bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 387bd04181cSBarry Smith - the values are always added to the matrix, not set 388bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 389bd04181cSBarry Smith 3901f763a69SBarry Smith This does NOT assume the global column indices are sorted 391bd04181cSBarry Smith 3921f763a69SBarry Smith */ 393bd04181cSBarry Smith 394af0996ceSBarry Smith #include <petsc/private/isimpl.h> 395189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 396189e4007SBarry Smith { 397189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3981f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 3991f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 4001f763a69SBarry Smith PetscInt lastcol = -1; 401189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 402189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 403189e4007SBarry Smith 404f38dd0b8SBarry Smith row = ridx[im[0]]; 4051f763a69SBarry Smith rp = aj + ai[row]; 4061f763a69SBarry Smith ap = aa + ai[row]; 4071f763a69SBarry Smith nrow = ailen[row]; 408189e4007SBarry Smith low = 0; 409189e4007SBarry Smith high = nrow; 410189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 411189e4007SBarry Smith col = cidx[in[l]]; 412f38dd0b8SBarry Smith value = v[l]; 413189e4007SBarry Smith 414189e4007SBarry Smith if (col <= lastcol) low = 0; 415189e4007SBarry Smith else high = nrow; 416189e4007SBarry Smith lastcol = col; 417189e4007SBarry Smith while (high-low > 5) { 418189e4007SBarry Smith t = (low+high)/2; 419189e4007SBarry Smith if (rp[t] > col) high = t; 420189e4007SBarry Smith else low = t; 421189e4007SBarry Smith } 422189e4007SBarry Smith for (i=low; i<high; i++) { 423189e4007SBarry Smith if (rp[i] == col) { 4241f763a69SBarry Smith ap[i] += value; 425189e4007SBarry Smith low = i + 1; 4261f763a69SBarry Smith break; 427189e4007SBarry Smith } 428189e4007SBarry Smith } 429189e4007SBarry Smith } 4308c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 431c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 432e2cf4d64SStefano Zampini #endif 433f38dd0b8SBarry Smith return 0; 434189e4007SBarry Smith } 435189e4007SBarry Smith 43697f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 43717ab2063SBarry Smith { 438416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 439e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 44097f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4416849ba73SBarry Smith PetscErrorCode ierr; 442e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 443d8cdefa3SHong Zhang MatScalar *ap=NULL,value=0.0,*aa = a->a; 444ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 445ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 4468c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 447e2cf4d64SStefano Zampini PetscBool inserted = PETSC_FALSE; 448e2cf4d64SStefano Zampini #endif 44917ab2063SBarry Smith 4503a40ed3dSBarry Smith PetscFunctionBegin; 45117ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 452416022c9SBarry Smith row = im[k]; 4535ef9f2a5SBarry Smith if (row < 0) continue; 454cf9c20a2SJed 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); 455720833daSHong Zhang rp = aj + ai[row]; 456876c6284SHong Zhang if (!A->structure_only) ap = aa + ai[row]; 45717ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 458416022c9SBarry Smith low = 0; 459c71e6ed7SBarry Smith high = nrow; 46017ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4615ef9f2a5SBarry Smith if (in[l] < 0) continue; 462cf9c20a2SJed 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); 463bfeeae90SHong Zhang col = in[l]; 464071fcb05SBarry Smith if (v && !A->structure_only) value = roworiented ? v[l + k*n] : v[k + l*m]; 465071fcb05SBarry Smith if (!A->structure_only && value == 0.0 && ignorezeroentries && is == ADD_VALUES && row != col) continue; 46636db0b34SBarry Smith 4672205254eSKarl Rupp if (col <= lastcol) low = 0; 4682205254eSKarl Rupp else high = nrow; 469e2ee6c50SBarry Smith lastcol = col; 470416022c9SBarry Smith while (high-low > 5) { 471416022c9SBarry Smith t = (low+high)/2; 472416022c9SBarry Smith if (rp[t] > col) high = t; 473416022c9SBarry Smith else low = t; 47417ab2063SBarry Smith } 475416022c9SBarry Smith for (i=low; i<high; i++) { 47617ab2063SBarry Smith if (rp[i] > col) break; 47717ab2063SBarry Smith if (rp[i] == col) { 478876c6284SHong Zhang if (!A->structure_only) { 4790c0d7e18SFande Kong if (is == ADD_VALUES) { 4800c0d7e18SFande Kong ap[i] += value; 4810c0d7e18SFande Kong (void)PetscLogFlops(1.0); 4820c0d7e18SFande Kong } 48317ab2063SBarry Smith else ap[i] = value; 4848c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 485e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 486e2cf4d64SStefano Zampini #endif 487720833daSHong Zhang } 488e44c0bd4SBarry Smith low = i + 1; 48917ab2063SBarry Smith goto noinsert; 49017ab2063SBarry Smith } 49117ab2063SBarry Smith } 492dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 493c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 494e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 495720833daSHong Zhang if (A->structure_only) { 496876c6284SHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,ai,aj,rp,imax,nonew,MatScalar); 497720833daSHong Zhang } else { 498fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 499720833daSHong Zhang } 500c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 501416022c9SBarry Smith /* shift up all the later entries in this row */ 502580bdb30SBarry Smith ierr = PetscArraymove(rp+i+1,rp+i,N-i+1);CHKERRQ(ierr); 50317ab2063SBarry Smith rp[i] = col; 504580bdb30SBarry Smith if (!A->structure_only){ 505580bdb30SBarry Smith ierr = PetscArraymove(ap+i+1,ap+i,N-i+1);CHKERRQ(ierr); 506580bdb30SBarry Smith ap[i] = value; 507580bdb30SBarry Smith } 508416022c9SBarry Smith low = i + 1; 509e56f5c9eSBarry Smith A->nonzerostate++; 5108c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 511e2cf4d64SStefano Zampini inserted = PETSC_TRUE; 512e2cf4d64SStefano Zampini #endif 513e44c0bd4SBarry Smith noinsert:; 51417ab2063SBarry Smith } 51517ab2063SBarry Smith ailen[row] = nrow; 51617ab2063SBarry Smith } 5178c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 518c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && inserted) A->offloadmask = PETSC_OFFLOAD_CPU; 519e2cf4d64SStefano Zampini #endif 5203a40ed3dSBarry Smith PetscFunctionReturn(0); 52117ab2063SBarry Smith } 52217ab2063SBarry Smith 52319b08ed1SBarry Smith 52419b08ed1SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFullNoPreallocation(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 52519b08ed1SBarry Smith { 52619b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 52719b08ed1SBarry Smith PetscInt *rp,k,row; 52819b08ed1SBarry Smith PetscInt *ai = a->i; 52919b08ed1SBarry Smith PetscErrorCode ierr; 53019b08ed1SBarry Smith PetscInt *aj = a->j; 53119b08ed1SBarry Smith MatScalar *aa = a->a,*ap; 53219b08ed1SBarry Smith 53319b08ed1SBarry Smith PetscFunctionBegin; 53419b08ed1SBarry Smith if (A->was_assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot call on assembled matrix."); 53519b08ed1SBarry 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); 53619b08ed1SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 53719b08ed1SBarry Smith row = im[k]; 53819b08ed1SBarry Smith rp = aj + ai[row]; 53919b08ed1SBarry Smith ap = aa + ai[row]; 54019b08ed1SBarry Smith 54119b08ed1SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 54219b08ed1SBarry Smith if (!A->structure_only) { 54319b08ed1SBarry Smith if (v) { 54419b08ed1SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 54519b08ed1SBarry Smith v += n; 54619b08ed1SBarry Smith } else { 54719b08ed1SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 54819b08ed1SBarry Smith } 54919b08ed1SBarry Smith } 55019b08ed1SBarry Smith a->ilen[row] = n; 55119b08ed1SBarry Smith a->imax[row] = n; 55219b08ed1SBarry Smith a->i[row+1] = a->i[row]+n; 55319b08ed1SBarry Smith a->nz += n; 55419b08ed1SBarry Smith } 5558c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 55619b08ed1SBarry Smith if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 55719b08ed1SBarry Smith #endif 55819b08ed1SBarry Smith PetscFunctionReturn(0); 55919b08ed1SBarry Smith } 56019b08ed1SBarry Smith 56119b08ed1SBarry Smith /*@ 56219b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation - Sets an upper bound on the total number of expected nonzeros in the matrix. 56319b08ed1SBarry Smith 56419b08ed1SBarry Smith Input Parameters: 56519b08ed1SBarry Smith + A - the SeqAIJ matrix 56619b08ed1SBarry Smith - nztotal - bound on the number of nonzeros 56719b08ed1SBarry Smith 56819b08ed1SBarry Smith Level: advanced 56919b08ed1SBarry Smith 57019b08ed1SBarry Smith Notes: 57119b08ed1SBarry 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. 57219b08ed1SBarry Smith Simply call MatSetValues() after this call to provide the matrix entries in the usual manner. This matrix may be used 57319b08ed1SBarry Smith as always with multiple matrix assemblies. 57419b08ed1SBarry Smith 57519b08ed1SBarry Smith .seealso: MatSetOption(), MAT_SORTED_FULL, MatSetValues(), MatSeqAIJSetPreallocation() 57619b08ed1SBarry Smith @*/ 57719b08ed1SBarry Smith 57819b08ed1SBarry Smith PetscErrorCode MatSeqAIJSetTotalPreallocation(Mat A,PetscInt nztotal) 57919b08ed1SBarry Smith { 58019b08ed1SBarry Smith PetscErrorCode ierr; 58119b08ed1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 58219b08ed1SBarry Smith 58319b08ed1SBarry Smith PetscFunctionBegin; 58419b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 58519b08ed1SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 58619b08ed1SBarry Smith a->maxnz = nztotal; 58719b08ed1SBarry Smith if (!a->imax) { 58819b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->imax);CHKERRQ(ierr); 58919b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 59019b08ed1SBarry Smith } 59119b08ed1SBarry Smith if (!a->ilen) { 59219b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n,&a->ilen);CHKERRQ(ierr); 59319b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 59419b08ed1SBarry Smith } else { 59519b08ed1SBarry Smith ierr = PetscMemzero(a->ilen,A->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 59619b08ed1SBarry Smith } 59719b08ed1SBarry Smith 59819b08ed1SBarry Smith /* allocate the matrix space */ 59919b08ed1SBarry Smith if (A->structure_only) { 60019b08ed1SBarry Smith ierr = PetscMalloc1(nztotal,&a->j);CHKERRQ(ierr); 60119b08ed1SBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&a->i);CHKERRQ(ierr); 60219b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*sizeof(PetscInt));CHKERRQ(ierr); 60319b08ed1SBarry Smith } else { 60419b08ed1SBarry Smith ierr = PetscMalloc3(nztotal,&a->a,nztotal,&a->j,A->rmap->n+1,&a->i);CHKERRQ(ierr); 60519b08ed1SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,(A->rmap->n+1)*sizeof(PetscInt)+nztotal*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 60619b08ed1SBarry Smith } 60719b08ed1SBarry Smith a->i[0] = 0; 60819b08ed1SBarry Smith if (A->structure_only) { 60919b08ed1SBarry Smith a->singlemalloc = PETSC_FALSE; 61019b08ed1SBarry Smith a->free_a = PETSC_FALSE; 61119b08ed1SBarry Smith } else { 61219b08ed1SBarry Smith a->singlemalloc = PETSC_TRUE; 61319b08ed1SBarry Smith a->free_a = PETSC_TRUE; 61419b08ed1SBarry Smith } 61519b08ed1SBarry Smith a->free_ij = PETSC_TRUE; 61619b08ed1SBarry Smith A->ops->setvalues = MatSetValues_SeqAIJ_SortedFullNoPreallocation; 61719b08ed1SBarry Smith A->preallocated = PETSC_TRUE; 61819b08ed1SBarry Smith PetscFunctionReturn(0); 61919b08ed1SBarry Smith } 62019b08ed1SBarry Smith 621071fcb05SBarry Smith PetscErrorCode MatSetValues_SeqAIJ_SortedFull(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 622071fcb05SBarry Smith { 623071fcb05SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 624071fcb05SBarry Smith PetscInt *rp,k,row; 625071fcb05SBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 626071fcb05SBarry Smith PetscErrorCode ierr; 627071fcb05SBarry Smith PetscInt *aj = a->j; 628071fcb05SBarry Smith MatScalar *aa = a->a,*ap; 629071fcb05SBarry Smith 630071fcb05SBarry Smith PetscFunctionBegin; 631071fcb05SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 632071fcb05SBarry Smith row = im[k]; 63319b08ed1SBarry 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); 634071fcb05SBarry Smith rp = aj + ai[row]; 635071fcb05SBarry Smith ap = aa + ai[row]; 636071fcb05SBarry Smith if (!A->was_assembled) { 637071fcb05SBarry Smith ierr = PetscMemcpy(rp,in,n*sizeof(PetscInt));CHKERRQ(ierr); 638071fcb05SBarry Smith } 639071fcb05SBarry Smith if (!A->structure_only) { 640071fcb05SBarry Smith if (v) { 641071fcb05SBarry Smith ierr = PetscMemcpy(ap,v,n*sizeof(PetscScalar));CHKERRQ(ierr); 642071fcb05SBarry Smith v += n; 643071fcb05SBarry Smith } else { 644071fcb05SBarry Smith ierr = PetscMemzero(ap,n*sizeof(PetscScalar));CHKERRQ(ierr); 645071fcb05SBarry Smith } 646071fcb05SBarry Smith } 647071fcb05SBarry Smith ailen[row] = n; 648071fcb05SBarry Smith a->nz += n; 649071fcb05SBarry Smith } 6508c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 651c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED && m && n) A->offloadmask = PETSC_OFFLOAD_CPU; 652e2cf4d64SStefano Zampini #endif 653071fcb05SBarry Smith PetscFunctionReturn(0); 654071fcb05SBarry Smith } 655071fcb05SBarry Smith 65681824310SBarry Smith 657a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 6587eb43aa7SLois Curfman McInnes { 6597eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 66097f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 66197f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 66254f21887SBarry Smith MatScalar *ap,*aa = a->a; 6637eb43aa7SLois Curfman McInnes 6643a40ed3dSBarry Smith PetscFunctionBegin; 6657eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 6667eb43aa7SLois Curfman McInnes row = im[k]; 667e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 668e32f2f54SBarry 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); 669bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 6707eb43aa7SLois Curfman McInnes nrow = ailen[row]; 6717eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 672e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 673e32f2f54SBarry 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); 674bfeeae90SHong Zhang col = in[l]; 6757eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 6767eb43aa7SLois Curfman McInnes while (high-low > 5) { 6777eb43aa7SLois Curfman McInnes t = (low+high)/2; 6787eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 6797eb43aa7SLois Curfman McInnes else low = t; 6807eb43aa7SLois Curfman McInnes } 6817eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 6827eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 6837eb43aa7SLois Curfman McInnes if (rp[i] == col) { 684b49de8d1SLois Curfman McInnes *v++ = ap[i]; 6857eb43aa7SLois Curfman McInnes goto finished; 6867eb43aa7SLois Curfman McInnes } 6877eb43aa7SLois Curfman McInnes } 68897e567efSBarry Smith *v++ = 0.0; 6897eb43aa7SLois Curfman McInnes finished:; 6907eb43aa7SLois Curfman McInnes } 6917eb43aa7SLois Curfman McInnes } 6923a40ed3dSBarry Smith PetscFunctionReturn(0); 6937eb43aa7SLois Curfman McInnes } 6947eb43aa7SLois Curfman McInnes 6953ea6fe3dSLisandro Dalcin PetscErrorCode MatView_SeqAIJ_Binary(Mat mat,PetscViewer viewer) 69617ab2063SBarry Smith { 6973ea6fe3dSLisandro Dalcin Mat_SeqAIJ *A = (Mat_SeqAIJ*)mat->data; 6983ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 6993ea6fe3dSLisandro Dalcin PetscInt *rowlens; 7006849ba73SBarry Smith PetscErrorCode ierr; 70117ab2063SBarry Smith 7023a40ed3dSBarry Smith PetscFunctionBegin; 7033ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7042205254eSKarl Rupp 7053ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7063ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7073ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7083ea6fe3dSLisandro Dalcin nz = A->nz; 709416022c9SBarry Smith 7103ea6fe3dSLisandro Dalcin /* write matrix header */ 7113ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7123ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7133ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 714416022c9SBarry Smith 7153ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7163ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7173ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7183ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7193ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7203ea6fe3dSLisandro Dalcin /* store column indices */ 7213ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 722416022c9SBarry Smith /* store nonzero values */ 7233ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 724b37d52dbSMark F. Adams 7253ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7263ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7273a40ed3dSBarry Smith PetscFunctionReturn(0); 72817ab2063SBarry Smith } 729416022c9SBarry Smith 7307dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7317dc0baabSHong Zhang { 7327dc0baabSHong Zhang PetscErrorCode ierr; 7337dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7347dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7357dc0baabSHong Zhang 7367dc0baabSHong Zhang PetscFunctionBegin; 7377dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7387dc0baabSHong Zhang for (i=0; i<m; i++) { 7397dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7407dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7417dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7427dc0baabSHong Zhang } 7437dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7447dc0baabSHong Zhang } 7457dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7467dc0baabSHong Zhang PetscFunctionReturn(0); 7477dc0baabSHong Zhang } 7487dc0baabSHong Zhang 74909573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 750cd155464SBarry Smith 751dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 752416022c9SBarry Smith { 753416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 754dfbe8321SBarry Smith PetscErrorCode ierr; 75560e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 756e060cb09SBarry Smith const char *name; 757f3ef73ceSBarry Smith PetscViewerFormat format; 75817ab2063SBarry Smith 7593a40ed3dSBarry Smith PetscFunctionBegin; 7607dc0baabSHong Zhang if (A->structure_only) { 7617dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7627dc0baabSHong Zhang PetscFunctionReturn(0); 7637dc0baabSHong Zhang } 76443e49210SHong Zhang 765b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 76671c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 76797f1f81fSBarry Smith PetscInt nofinalvalue = 0; 76860e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 769c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 770d00d2cf4SBarry Smith nofinalvalue = 1; 771d00d2cf4SBarry Smith } 772d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 773d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 77477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 775fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 776fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 777fbfe6fa7SJed Brown #else 77877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 779fbfe6fa7SJed Brown #endif 780b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 78117ab2063SBarry Smith 78217ab2063SBarry Smith for (i=0; i<m; i++) { 78360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 784aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 785a9bf72d8SJed 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); 78617ab2063SBarry Smith #else 78760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 78817ab2063SBarry Smith #endif 78917ab2063SBarry Smith } 79017ab2063SBarry Smith } 791d00d2cf4SBarry Smith if (nofinalvalue) { 792c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 793c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 794c337ccceSJed Brown #else 795d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 796c337ccceSJed Brown #endif 797d00d2cf4SBarry Smith } 798317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 799fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 800d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8012950ac48SStefano Zampini } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 802cd155464SBarry Smith PetscFunctionReturn(0); 803fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 804d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 80544cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 80677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 80760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 808aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 80936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 81060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 81136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 81260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 81336db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 81460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8156831982aSBarry Smith } 81644cd7ae7SLois Curfman McInnes #else 81760e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 81844cd7ae7SLois Curfman McInnes #endif 81944cd7ae7SLois Curfman McInnes } 820b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 82144cd7ae7SLois Curfman McInnes } 822d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 823fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 82497f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 825d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 826854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 827496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 828496be53dSLois Curfman McInnes sptr[i] = nzd+1; 82960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 830496be53dSLois Curfman McInnes if (a->j[j] >= i) { 831aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 83236db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 833496be53dSLois Curfman McInnes #else 834496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 835496be53dSLois Curfman McInnes #endif 836496be53dSLois Curfman McInnes } 837496be53dSLois Curfman McInnes } 838496be53dSLois Curfman McInnes } 8392e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 84077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8412e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8422205254eSKarl Rupp if (i+4<m) { 8432205254eSKarl 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); 8442205254eSKarl Rupp } else if (i+3<m) { 8452205254eSKarl 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); 8462205254eSKarl Rupp } else if (i+2<m) { 8472205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8482205254eSKarl Rupp } else if (i+1<m) { 8492205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8502205254eSKarl Rupp } else if (i<m) { 8512205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8522205254eSKarl Rupp } else { 8532205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8542205254eSKarl Rupp } 855496be53dSLois Curfman McInnes } 856b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 857606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 858496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 85960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 86077431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 861496be53dSLois Curfman McInnes } 862b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 863496be53dSLois Curfman McInnes } 864b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 865496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 86660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 867496be53dSLois Curfman McInnes if (a->j[j] >= i) { 868aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 86936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 87060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8716831982aSBarry Smith } 872496be53dSLois Curfman McInnes #else 87360e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 874496be53dSLois Curfman McInnes #endif 875496be53dSLois Curfman McInnes } 876496be53dSLois Curfman McInnes } 877b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 878496be53dSLois Curfman McInnes } 879d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 880fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 88197f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 88287828ca2SBarry Smith PetscScalar value; 88368f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 88468f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 88568f1ed48SBarry Smith 88668f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 88768f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 88868f1ed48SBarry Smith realonly = PETSC_FALSE; 88968f1ed48SBarry Smith break; 89068f1ed48SBarry Smith } 89168f1ed48SBarry Smith } 89268f1ed48SBarry Smith #endif 89302594712SBarry Smith 894d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 89502594712SBarry Smith for (i=0; i<m; i++) { 89602594712SBarry Smith jcnt = 0; 897d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 898e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 89902594712SBarry Smith value = a->a[cnt++]; 900e24b481bSBarry Smith jcnt++; 90102594712SBarry Smith } else { 90202594712SBarry Smith value = 0.0; 90302594712SBarry Smith } 904aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 90568f1ed48SBarry Smith if (realonly) { 90660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 90768f1ed48SBarry Smith } else { 90860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 90968f1ed48SBarry Smith } 91002594712SBarry Smith #else 91160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 91202594712SBarry Smith #endif 91302594712SBarry Smith } 914b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 91502594712SBarry Smith } 916d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9173c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 918150b93efSMatthew G. Knepley PetscInt fshift=1; 919d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9203c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 92119303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9223c215bfdSMatthew Knepley #else 92319303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9243c215bfdSMatthew Knepley #endif 925d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9263c215bfdSMatthew Knepley for (i=0; i<m; i++) { 92760e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9283c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 929a9a0e077SKarl 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); 9303c215bfdSMatthew Knepley #else 931150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9323c215bfdSMatthew Knepley #endif 9333c215bfdSMatthew Knepley } 9343c215bfdSMatthew Knepley } 935d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9363a40ed3dSBarry Smith } else { 937d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 938d5f3da31SBarry Smith if (A->factortype) { 93916cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 94016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 94116cd7e1dSShri Abhyankar /* L part */ 94260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 94316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 94416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 94560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 94616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9476712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 94816cd7e1dSShri Abhyankar } else { 94960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 95016cd7e1dSShri Abhyankar } 95116cd7e1dSShri Abhyankar #else 95260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 95316cd7e1dSShri Abhyankar #endif 95416cd7e1dSShri Abhyankar } 95516cd7e1dSShri Abhyankar /* diagonal */ 95616cd7e1dSShri Abhyankar j = a->diag[i]; 95716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 95816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 95960e0710aSBarry 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); 96016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9616712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr); 96216cd7e1dSShri Abhyankar } else { 96360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 96416cd7e1dSShri Abhyankar } 96516cd7e1dSShri Abhyankar #else 96660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 96716cd7e1dSShri Abhyankar #endif 96816cd7e1dSShri Abhyankar 96916cd7e1dSShri Abhyankar /* U part */ 97060e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 97116cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97216cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 97360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 97416cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 97522ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 97616cd7e1dSShri Abhyankar } else { 97760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 97816cd7e1dSShri Abhyankar } 97916cd7e1dSShri Abhyankar #else 98060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 98116cd7e1dSShri Abhyankar #endif 98216cd7e1dSShri Abhyankar } 98316cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 98416cd7e1dSShri Abhyankar } 98516cd7e1dSShri Abhyankar } else { 98617ab2063SBarry Smith for (i=0; i<m; i++) { 98777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 98860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 989aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 99036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 99160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 99236db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 99360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 9943a40ed3dSBarry Smith } else { 99560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 99617ab2063SBarry Smith } 99717ab2063SBarry Smith #else 99860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 99917ab2063SBarry Smith #endif 100017ab2063SBarry Smith } 1001b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 100217ab2063SBarry Smith } 100316cd7e1dSShri Abhyankar } 1004d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 100517ab2063SBarry Smith } 1006b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10073a40ed3dSBarry Smith PetscFunctionReturn(0); 1008416022c9SBarry Smith } 1009416022c9SBarry Smith 10109804daf3SBarry Smith #include <petscdraw.h> 1011dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1012416022c9SBarry Smith { 1013480ef9eaSBarry Smith Mat A = (Mat) Aa; 1014416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1015dfbe8321SBarry Smith PetscErrorCode ierr; 1016383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1017383922c3SLisandro Dalcin int color; 1018b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1019b0a32e0cSBarry Smith PetscViewer viewer; 1020f3ef73ceSBarry Smith PetscViewerFormat format; 1021cddf8d76SBarry Smith 10223a40ed3dSBarry Smith PetscFunctionBegin; 1023480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1024b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1025b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1026383922c3SLisandro Dalcin 1027416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10280513a670SBarry Smith 1029fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1030383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10310513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1032b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1033416022c9SBarry Smith for (i=0; i<m; i++) { 1034cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1035bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1036bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 103736db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 1038b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1039cddf8d76SBarry Smith } 1040cddf8d76SBarry Smith } 1041b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1042cddf8d76SBarry Smith for (i=0; i<m; i++) { 1043cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1044bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1045bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1046cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 1047b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1048cddf8d76SBarry Smith } 1049cddf8d76SBarry Smith } 1050b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1051cddf8d76SBarry Smith for (i=0; i<m; i++) { 1052cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1053bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1054bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 105536db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 1056b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1057416022c9SBarry Smith } 1058416022c9SBarry Smith } 1059383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10600513a670SBarry Smith } else { 10610513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10620513a670SBarry Smith /* first determine max of all nonzero values */ 1063b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1064383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1065b0a32e0cSBarry Smith PetscDraw popup; 10660513a670SBarry Smith 10670513a670SBarry Smith for (i=0; i<nz; i++) { 10680513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 10690513a670SBarry Smith } 1070383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1071b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 107245f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1073383922c3SLisandro Dalcin 1074383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10750513a670SBarry Smith for (i=0; i<m; i++) { 1076383922c3SLisandro Dalcin y_l = m - i - 1.0; 1077383922c3SLisandro Dalcin y_r = y_l + 1.0; 1078bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1079383922c3SLisandro Dalcin x_l = a->j[j]; 1080383922c3SLisandro Dalcin x_r = x_l + 1.0; 1081b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 1082b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 10830513a670SBarry Smith count++; 10840513a670SBarry Smith } 10850513a670SBarry Smith } 1086383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10870513a670SBarry Smith } 1088480ef9eaSBarry Smith PetscFunctionReturn(0); 1089480ef9eaSBarry Smith } 1090cddf8d76SBarry Smith 10919804daf3SBarry Smith #include <petscdraw.h> 1092dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1093480ef9eaSBarry Smith { 1094dfbe8321SBarry Smith PetscErrorCode ierr; 1095b0a32e0cSBarry Smith PetscDraw draw; 109636db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1097ace3abfcSBarry Smith PetscBool isnull; 1098480ef9eaSBarry Smith 1099480ef9eaSBarry Smith PetscFunctionBegin; 1100b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1101b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1102480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1103480ef9eaSBarry Smith 1104d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1105480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1106b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1107832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1108b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11090298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1110832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11113a40ed3dSBarry Smith PetscFunctionReturn(0); 1112416022c9SBarry Smith } 1113416022c9SBarry Smith 1114dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1115416022c9SBarry Smith { 1116dfbe8321SBarry Smith PetscErrorCode ierr; 1117ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1118416022c9SBarry Smith 11193a40ed3dSBarry Smith PetscFunctionBegin; 1120251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1121251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1122251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1123c45a1595SBarry Smith if (iascii) { 11243a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11250f5bd95cSBarry Smith } else if (isbinary) { 11263a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11270f5bd95cSBarry Smith } else if (isdraw) { 11283a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 112911aeaf0aSBarry Smith } 11304108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11313a40ed3dSBarry Smith PetscFunctionReturn(0); 113217ab2063SBarry Smith } 113319bcc07fSBarry Smith 1134dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 113517ab2063SBarry Smith { 1136416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11376849ba73SBarry Smith PetscErrorCode ierr; 1138580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1139d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 114054f21887SBarry Smith MatScalar *aa = a->a,*ap; 11413447b6efSHong Zhang PetscReal ratio = 0.6; 114217ab2063SBarry Smith 11433a40ed3dSBarry Smith PetscFunctionBegin; 11443a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1145071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1146071fcb05SBarry Smith if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) PetscFunctionReturn(0); 114717ab2063SBarry Smith 114843ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 114917ab2063SBarry Smith for (i=1; i<m; i++) { 1150416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 115117ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 115294a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 115317ab2063SBarry Smith if (fshift) { 1154bfeeae90SHong Zhang ip = aj + ai[i]; 1155bfeeae90SHong Zhang ap = aa + ai[i]; 115617ab2063SBarry Smith N = ailen[i]; 1157580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1158580bdb30SBarry Smith if (!A->structure_only) { 1159580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 116017ab2063SBarry Smith } 116117ab2063SBarry Smith } 116217ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 116317ab2063SBarry Smith } 116417ab2063SBarry Smith if (m) { 116517ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 116617ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 116717ab2063SBarry Smith } 11687b083b7cSBarry Smith 116917ab2063SBarry Smith /* reset ilen and imax for each row */ 11707b083b7cSBarry Smith a->nonzerorowcnt = 0; 1171396832f4SHong Zhang if (A->structure_only) { 1172071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1173071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1174396832f4SHong Zhang } else { /* !A->structure_only */ 117517ab2063SBarry Smith for (i=0; i<m; i++) { 117617ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 11777b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 117817ab2063SBarry Smith } 1179396832f4SHong Zhang } 1180bfeeae90SHong Zhang a->nz = ai[m]; 118165e19b50SBarry 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); 118217ab2063SBarry Smith 118309f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1184d0f46423SBarry 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); 1185ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1186ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 11872205254eSKarl Rupp 11888e58a170SBarry Smith A->info.mallocs += a->reallocs; 1189dd5f02e7SSatish Balay a->reallocs = 0; 11906712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 119136db0b34SBarry Smith a->rmax = rmax; 11924e220ebcSLois Curfman McInnes 1193396832f4SHong Zhang if (!A->structure_only) { 119411e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1195396832f4SHong Zhang } 11964108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 11973a40ed3dSBarry Smith PetscFunctionReturn(0); 119817ab2063SBarry Smith } 119917ab2063SBarry Smith 120099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 120199cafbc1SBarry Smith { 120299cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 120399cafbc1SBarry Smith PetscInt i,nz = a->nz; 120454f21887SBarry Smith MatScalar *aa = a->a; 1205acf2f550SJed Brown PetscErrorCode ierr; 120699cafbc1SBarry Smith 120799cafbc1SBarry Smith PetscFunctionBegin; 120899cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1209acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12108c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1211c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1212e2cf4d64SStefano Zampini #endif 121399cafbc1SBarry Smith PetscFunctionReturn(0); 121499cafbc1SBarry Smith } 121599cafbc1SBarry Smith 121699cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 121799cafbc1SBarry Smith { 121899cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 121999cafbc1SBarry Smith PetscInt i,nz = a->nz; 122054f21887SBarry Smith MatScalar *aa = a->a; 1221acf2f550SJed Brown PetscErrorCode ierr; 122299cafbc1SBarry Smith 122399cafbc1SBarry Smith PetscFunctionBegin; 122499cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1225acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12268c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1227c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1228e2cf4d64SStefano Zampini #endif 122999cafbc1SBarry Smith PetscFunctionReturn(0); 123099cafbc1SBarry Smith } 123199cafbc1SBarry Smith 1232dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 123317ab2063SBarry Smith { 1234416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1235dfbe8321SBarry Smith PetscErrorCode ierr; 12363a40ed3dSBarry Smith 12373a40ed3dSBarry Smith PetscFunctionBegin; 1238580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1239acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12408c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1241c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1242e2cf4d64SStefano Zampini #endif 12433a40ed3dSBarry Smith PetscFunctionReturn(0); 124417ab2063SBarry Smith } 1245416022c9SBarry Smith 1246dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 124717ab2063SBarry Smith { 1248416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1249dfbe8321SBarry Smith PetscErrorCode ierr; 1250d5d45c9bSBarry Smith 12513a40ed3dSBarry Smith PetscFunctionBegin; 1252aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1253d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 125417ab2063SBarry Smith #endif 1255e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12566bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12576bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 125805b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1259d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1260071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1261071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1262846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 126371f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 126405b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12656bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 126605b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1267cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1268a30b2313SHong Zhang 12694108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1270bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1271901853e0SKris Buschelman 12726718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 12736718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 12746718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 12756718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 12766718818eSStefano Zampini due to different matrix sizes */ 12776718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 12786718818eSStefano Zampini 1279f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1280bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1281bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1282bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1283bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1284bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1285bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 12864222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 12874222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1288e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 12894222ddf1SHong Zhang #endif 1290*3d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 1291*3d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 1292*3d0639e7SStefano Zampini #endif 12934222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1294af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1295af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1296af8000cdSHong Zhang #endif 1297d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1298d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1299d24d4204SJose E. Roman #endif 130063c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 130163c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13024222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 130363c07aadSStefano Zampini #endif 1304b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1305c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1306c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1307bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1308bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1309846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1310bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1311bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13124222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13134222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13144222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 13153a40ed3dSBarry Smith PetscFunctionReturn(0); 131617ab2063SBarry Smith } 131717ab2063SBarry Smith 1318ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 131917ab2063SBarry Smith { 1320416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13214846f1f5SKris Buschelman PetscErrorCode ierr; 13223a40ed3dSBarry Smith 13233a40ed3dSBarry Smith PetscFunctionBegin; 1324a65d3064SKris Buschelman switch (op) { 1325a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13264e0d8c25SBarry Smith a->roworiented = flg; 1327a65d3064SKris Buschelman break; 1328a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1329a9817697SBarry Smith a->keepnonzeropattern = flg; 1330a65d3064SKris Buschelman break; 1331512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1332512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1333a65d3064SKris Buschelman break; 1334a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13354e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1336a65d3064SKris Buschelman break; 1337a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13384e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1339a65d3064SKris Buschelman break; 134028b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 134128b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 134228b2fa4aSMatthew Knepley break; 1343a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13444e0d8c25SBarry Smith a->ignorezeroentries = flg; 13450df259c2SBarry Smith break; 13463d472b54SHong Zhang case MAT_SPD: 1347b1646e73SJed Brown case MAT_SYMMETRIC: 1348b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1349b1646e73SJed Brown case MAT_HERMITIAN: 1350b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1351957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13525021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13535021d80fSJed Brown break; 13544e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1355a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1356a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1357290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1358a65d3064SKris Buschelman break; 1359b87ac2d8SJed Brown case MAT_USE_INODES: 1360b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1361b87ac2d8SJed Brown break; 1362c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1363c10200c1SHong Zhang A->submat_singleis = flg; 1364c10200c1SHong Zhang break; 1365071fcb05SBarry Smith case MAT_SORTED_FULL: 1366071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1367071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1368071fcb05SBarry Smith break; 1369a65d3064SKris Buschelman default: 1370e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1371a65d3064SKris Buschelman } 13724108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 13733a40ed3dSBarry Smith PetscFunctionReturn(0); 137417ab2063SBarry Smith } 137517ab2063SBarry Smith 1376dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 137717ab2063SBarry Smith { 1378416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13796849ba73SBarry Smith PetscErrorCode ierr; 1380fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1381fdc842d1SBarry Smith PetscScalar *aa=a->a,*x; 138217ab2063SBarry Smith 13833a40ed3dSBarry Smith PetscFunctionBegin; 1384d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1385e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 138635e7444dSHong Zhang 1387d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1388d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1389fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 13902c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1391fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 139235e7444dSHong Zhang PetscFunctionReturn(0); 139335e7444dSHong Zhang } 139435e7444dSHong Zhang 1395fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 139635e7444dSHong Zhang for (i=0; i<n; i++) { 1397fdc842d1SBarry Smith x[i] = 0.0; 139835e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 139935e7444dSHong Zhang if (aj[j] == i) { 140035e7444dSHong Zhang x[i] = aa[j]; 140117ab2063SBarry Smith break; 140217ab2063SBarry Smith } 140317ab2063SBarry Smith } 140417ab2063SBarry Smith } 1405fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 14063a40ed3dSBarry Smith PetscFunctionReturn(0); 140717ab2063SBarry Smith } 140817ab2063SBarry Smith 1409c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1410dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 141117ab2063SBarry Smith { 1412416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1413d9ca1df4SBarry Smith PetscScalar *y; 1414d9ca1df4SBarry Smith const PetscScalar *x; 1415dfbe8321SBarry Smith PetscErrorCode ierr; 1416d0f46423SBarry Smith PetscInt m = A->rmap->n; 14175c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1418d9ca1df4SBarry Smith const MatScalar *v; 1419a77337e4SBarry Smith PetscScalar alpha; 1420d9ca1df4SBarry Smith PetscInt n,i,j; 1421d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14223447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1423ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14245c897100SBarry Smith #endif 142517ab2063SBarry Smith 14263a40ed3dSBarry Smith PetscFunctionBegin; 14272e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1428d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14291ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14305c897100SBarry Smith 14315c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1432bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 14335c897100SBarry Smith #else 14343447b6efSHong Zhang if (usecprow) { 14353447b6efSHong Zhang m = cprow.nrows; 14363447b6efSHong Zhang ii = cprow.i; 14377b2bb3b9SHong Zhang ridx = cprow.rindex; 14383447b6efSHong Zhang } else { 14393447b6efSHong Zhang ii = a->i; 14403447b6efSHong Zhang } 144117ab2063SBarry Smith for (i=0; i<m; i++) { 14423447b6efSHong Zhang idx = a->j + ii[i]; 14433447b6efSHong Zhang v = a->a + ii[i]; 14443447b6efSHong Zhang n = ii[i+1] - ii[i]; 14453447b6efSHong Zhang if (usecprow) { 14467b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14473447b6efSHong Zhang } else { 144817ab2063SBarry Smith alpha = x[i]; 14493447b6efSHong Zhang } 145004fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 145117ab2063SBarry Smith } 14525c897100SBarry Smith #endif 1453dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1454d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14551ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14563a40ed3dSBarry Smith PetscFunctionReturn(0); 145717ab2063SBarry Smith } 145817ab2063SBarry Smith 1459dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14605c897100SBarry Smith { 1461dfbe8321SBarry Smith PetscErrorCode ierr; 14625c897100SBarry Smith 14635c897100SBarry Smith PetscFunctionBegin; 1464170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 14655c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 14665c897100SBarry Smith PetscFunctionReturn(0); 14675c897100SBarry Smith } 14685c897100SBarry Smith 1469c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 147078b84d54SShri Abhyankar 1471dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 147217ab2063SBarry Smith { 1473416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1474d9fead3dSBarry Smith PetscScalar *y; 147554f21887SBarry Smith const PetscScalar *x; 147654f21887SBarry Smith const MatScalar *aa; 1477dfbe8321SBarry Smith PetscErrorCode ierr; 1478003131ecSBarry Smith PetscInt m=A->rmap->n; 14790298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 14807b083b7cSBarry Smith PetscInt n,i; 1481362ced78SSatish Balay PetscScalar sum; 1482ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 148317ab2063SBarry Smith 1484b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 148597952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1486fee21e36SBarry Smith #endif 1487fee21e36SBarry Smith 14883a40ed3dSBarry Smith PetscFunctionBegin; 14893649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14901ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1491416022c9SBarry Smith ii = a->i; 14924eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1493580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 149497952fefSHong Zhang m = a->compressedrow.nrows; 149597952fefSHong Zhang ii = a->compressedrow.i; 149697952fefSHong Zhang ridx = a->compressedrow.rindex; 149797952fefSHong Zhang for (i=0; i<m; i++) { 149897952fefSHong Zhang n = ii[i+1] - ii[i]; 149997952fefSHong Zhang aj = a->j + ii[i]; 150097952fefSHong Zhang aa = a->a + ii[i]; 150197952fefSHong Zhang sum = 0.0; 1502003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1503003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 150497952fefSHong Zhang y[*ridx++] = sum; 150597952fefSHong Zhang } 150697952fefSHong Zhang } else { /* do not use compressed row format */ 1507b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15083d3eaba7SBarry Smith aj = a->j; 15093d3eaba7SBarry Smith aa = a->a; 1510b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1511b05257ddSBarry Smith #else 151217ab2063SBarry Smith for (i=0; i<m; i++) { 1513003131ecSBarry Smith n = ii[i+1] - ii[i]; 1514003131ecSBarry Smith aj = a->j + ii[i]; 1515003131ecSBarry Smith aa = a->a + ii[i]; 151617ab2063SBarry Smith sum = 0.0; 1517003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 151817ab2063SBarry Smith y[i] = sum; 151917ab2063SBarry Smith } 15208d195f9aSBarry Smith #endif 1521b05257ddSBarry Smith } 15227b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15233649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15241ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15253a40ed3dSBarry Smith PetscFunctionReturn(0); 152617ab2063SBarry Smith } 152717ab2063SBarry Smith 1528b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1529b434eb95SMatthew G. Knepley { 1530b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1531b434eb95SMatthew G. Knepley PetscScalar *y; 1532b434eb95SMatthew G. Knepley const PetscScalar *x; 1533b434eb95SMatthew G. Knepley const MatScalar *aa; 1534b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1535b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1536b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1537b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1538b434eb95SMatthew G. Knepley PetscScalar sum; 1539b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1540b434eb95SMatthew G. Knepley 1541b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1542b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1543b434eb95SMatthew G. Knepley #endif 1544b434eb95SMatthew G. Knepley 1545b434eb95SMatthew G. Knepley PetscFunctionBegin; 1546b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1547b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1548b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1549b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1550b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1551b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1552b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1553b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1554b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1555b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1556b434eb95SMatthew G. Knepley sum = 0.0; 1557b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1558b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1559b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1560b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1561b434eb95SMatthew G. Knepley } 1562b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15633d3eaba7SBarry Smith ii = a->i; 1564b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1565b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1566b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1567b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1568b434eb95SMatthew G. Knepley sum = 0.0; 1569b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1570b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1571b434eb95SMatthew G. Knepley y[i] = sum; 1572b434eb95SMatthew G. Knepley } 1573b434eb95SMatthew G. Knepley } 1574b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1575b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1576b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1577b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1578b434eb95SMatthew G. Knepley } 1579b434eb95SMatthew G. Knepley 1580b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1581b434eb95SMatthew G. Knepley { 1582b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1583b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1584b434eb95SMatthew G. Knepley const PetscScalar *x; 1585b434eb95SMatthew G. Knepley const MatScalar *aa; 1586b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1587b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1588b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1589b434eb95SMatthew G. Knepley PetscScalar sum; 1590b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1591b434eb95SMatthew G. Knepley 1592b434eb95SMatthew G. Knepley PetscFunctionBegin; 1593b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1594d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1595b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1596b434eb95SMatthew G. Knepley if (zz != yy) { 1597580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1598b434eb95SMatthew G. Knepley } 1599b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1600b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1601b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1602b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1603b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1604b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1605b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1606b434eb95SMatthew G. Knepley sum = y[*ridx]; 1607b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1608b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1609b434eb95SMatthew G. Knepley } 1610b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16113d3eaba7SBarry Smith ii = a->i; 1612b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1613b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1614b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1615b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1616b434eb95SMatthew G. Knepley sum = y[i]; 1617b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1618b434eb95SMatthew G. Knepley z[i] = sum; 1619b434eb95SMatthew G. Knepley } 1620b434eb95SMatthew G. Knepley } 1621b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1622b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1623d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1624b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1625b434eb95SMatthew G. Knepley } 1626b434eb95SMatthew G. Knepley 1627c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1628dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 162917ab2063SBarry Smith { 1630416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1631f15663dcSBarry Smith PetscScalar *y,*z; 1632f15663dcSBarry Smith const PetscScalar *x; 163354f21887SBarry Smith const MatScalar *aa; 1634dfbe8321SBarry Smith PetscErrorCode ierr; 1635d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1636d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1637362ced78SSatish Balay PetscScalar sum; 1638ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16399ea0dfa2SSatish Balay 16403a40ed3dSBarry Smith PetscFunctionBegin; 1641f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1642d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16434eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16444eb6d288SHong Zhang if (zz != yy) { 1645580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16464eb6d288SHong Zhang } 164797952fefSHong Zhang m = a->compressedrow.nrows; 164897952fefSHong Zhang ii = a->compressedrow.i; 164997952fefSHong Zhang ridx = a->compressedrow.rindex; 165097952fefSHong Zhang for (i=0; i<m; i++) { 165197952fefSHong Zhang n = ii[i+1] - ii[i]; 165297952fefSHong Zhang aj = a->j + ii[i]; 165397952fefSHong Zhang aa = a->a + ii[i]; 165497952fefSHong Zhang sum = y[*ridx]; 1655f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 165697952fefSHong Zhang z[*ridx++] = sum; 165797952fefSHong Zhang } 165897952fefSHong Zhang } else { /* do not use compressed row format */ 16593d3eaba7SBarry Smith ii = a->i; 1660f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 16613d3eaba7SBarry Smith aj = a->j; 16623d3eaba7SBarry Smith aa = a->a; 1663f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1664f15663dcSBarry Smith #else 166517ab2063SBarry Smith for (i=0; i<m; i++) { 1666f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1667f15663dcSBarry Smith aj = a->j + ii[i]; 1668f15663dcSBarry Smith aa = a->a + ii[i]; 166917ab2063SBarry Smith sum = y[i]; 1670f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 167117ab2063SBarry Smith z[i] = sum; 167217ab2063SBarry Smith } 167302ab625aSSatish Balay #endif 1674f15663dcSBarry Smith } 1675dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1676f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1677d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16783a40ed3dSBarry Smith PetscFunctionReturn(0); 167917ab2063SBarry Smith } 168017ab2063SBarry Smith 168117ab2063SBarry Smith /* 168217ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 168317ab2063SBarry Smith */ 1684dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 168517ab2063SBarry Smith { 1686416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 16876849ba73SBarry Smith PetscErrorCode ierr; 1688d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 168917ab2063SBarry Smith 16903a40ed3dSBarry Smith PetscFunctionBegin; 169109f38230SBarry Smith if (!a->diag) { 1692785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 16933bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 169409f38230SBarry Smith } 1695d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 169609f38230SBarry Smith a->diag[i] = a->i[i+1]; 1697bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1698bfeeae90SHong Zhang if (a->j[j] == i) { 169909f38230SBarry Smith a->diag[i] = j; 170017ab2063SBarry Smith break; 170117ab2063SBarry Smith } 170217ab2063SBarry Smith } 170317ab2063SBarry Smith } 17043a40ed3dSBarry Smith PetscFunctionReturn(0); 170517ab2063SBarry Smith } 170617ab2063SBarry Smith 170761ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 170861ecd0c6SBarry Smith { 170961ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 171061ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 171161ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 171261ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 171361ecd0c6SBarry Smith PetscErrorCode ierr; 171461ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 171561ecd0c6SBarry Smith 171661ecd0c6SBarry Smith PetscFunctionBegin; 171761ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 171861ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 171961ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 172061ecd0c6SBarry Smith PetscFunctionReturn(0); 172161ecd0c6SBarry Smith } 172261ecd0c6SBarry Smith 172361ecd0c6SBarry Smith if (a->diagonaldense) { 172461ecd0c6SBarry Smith cnt = 0; 172561ecd0c6SBarry Smith } else { 172661ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 172761ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 172861ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 172961ecd0c6SBarry Smith cnt++; 173061ecd0c6SBarry Smith mdiag[i] = 1; 173161ecd0c6SBarry Smith } 173261ecd0c6SBarry Smith } 173361ecd0c6SBarry Smith } 173461ecd0c6SBarry Smith if (!cnt) { 173561ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 173661ecd0c6SBarry Smith } else { 1737b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1738b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 173961ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 174061ecd0c6SBarry Smith 174161ecd0c6SBarry Smith a->a = NULL; 174261ecd0c6SBarry Smith a->j = NULL; 174361ecd0c6SBarry Smith a->i = NULL; 174461ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 174561ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 174661ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1747447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 174861ecd0c6SBarry Smith } 174961ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 175061ecd0c6SBarry Smith 175161ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 175261ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 175361ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1754447d62f5SStefano Zampini if (i < A->cmap->n) { 175561ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 175661ecd0c6SBarry Smith } 1757447d62f5SStefano Zampini } 175861ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 175961ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 176061ecd0c6SBarry Smith if (singlemalloc) { 176161ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 176261ecd0c6SBarry Smith } else { 176361ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 176461ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 176561ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 176661ecd0c6SBarry Smith } 176761ecd0c6SBarry Smith } 176861ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 176961ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 177061ecd0c6SBarry Smith PetscFunctionReturn(0); 177161ecd0c6SBarry Smith } 177261ecd0c6SBarry Smith 1773be5855fcSBarry Smith /* 1774be5855fcSBarry Smith Checks for missing diagonals 1775be5855fcSBarry Smith */ 1776ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1777be5855fcSBarry Smith { 1778be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17797734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1780994fe344SLisandro Dalcin PetscErrorCode ierr; 1781be5855fcSBarry Smith 1782be5855fcSBarry Smith PetscFunctionBegin; 178309f38230SBarry Smith *missing = PETSC_FALSE; 17847734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 178509f38230SBarry Smith *missing = PETSC_TRUE; 178609f38230SBarry Smith if (d) *d = 0; 1787994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 178809f38230SBarry Smith } else { 178901445905SHong Zhang PetscInt n; 179001445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1791f1e2ffcdSBarry Smith diag = a->diag; 179201445905SHong Zhang for (i=0; i<n; i++) { 17937734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 179409f38230SBarry Smith *missing = PETSC_TRUE; 179509f38230SBarry Smith if (d) *d = i; 1796994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1797358d2f5dSShri Abhyankar break; 179809f38230SBarry Smith } 1799be5855fcSBarry Smith } 1800be5855fcSBarry Smith } 1801be5855fcSBarry Smith PetscFunctionReturn(0); 1802be5855fcSBarry Smith } 1803be5855fcSBarry Smith 18040da83c2eSBarry Smith #include <petscblaslapack.h> 18050da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18060da83c2eSBarry Smith 18070da83c2eSBarry Smith /* 18080da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18090da83c2eSBarry Smith */ 18100da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18110da83c2eSBarry Smith { 18120da83c2eSBarry Smith PetscErrorCode ierr; 18130da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18140da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18150da83c2eSBarry Smith const PetscReal shift = 0.0; 18160da83c2eSBarry Smith PetscInt ipvt[5]; 18170da83c2eSBarry Smith PetscScalar work[25],*v_work; 18180da83c2eSBarry Smith 18190da83c2eSBarry Smith PetscFunctionBegin; 18200da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18210da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18220da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18230da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18240da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18250da83c2eSBarry Smith } 18260da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18270da83c2eSBarry Smith if (bsizemax > 7) { 18280da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18290da83c2eSBarry Smith } 18300da83c2eSBarry Smith ncnt = 0; 18310da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18320da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18330da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18340da83c2eSBarry Smith switch (bsizes[i]) { 18350da83c2eSBarry Smith case 1: 18360da83c2eSBarry Smith *diag = 1.0/(*diag); 18370da83c2eSBarry Smith break; 18380da83c2eSBarry Smith case 2: 18390da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18400da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18410da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18420da83c2eSBarry Smith break; 18430da83c2eSBarry Smith case 3: 18440da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18450da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18460da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18470da83c2eSBarry Smith break; 18480da83c2eSBarry Smith case 4: 18490da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18500da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18510da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 18520da83c2eSBarry Smith break; 18530da83c2eSBarry Smith case 5: 18540da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18550da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18560da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 18570da83c2eSBarry Smith break; 18580da83c2eSBarry Smith case 6: 18590da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18600da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18610da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 18620da83c2eSBarry Smith break; 18630da83c2eSBarry Smith case 7: 18640da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18650da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18660da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 18670da83c2eSBarry Smith break; 18680da83c2eSBarry Smith default: 18690da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18700da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18710da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 18720da83c2eSBarry Smith } 18730da83c2eSBarry Smith ncnt += bsizes[i]; 18740da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 18750da83c2eSBarry Smith } 18760da83c2eSBarry Smith if (bsizemax > 7) { 18770da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 18780da83c2eSBarry Smith } 18790da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 18800da83c2eSBarry Smith PetscFunctionReturn(0); 18810da83c2eSBarry Smith } 18820da83c2eSBarry Smith 1883422a814eSBarry Smith /* 1884422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1885422a814eSBarry Smith */ 18867087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 188771f1c65dSBarry Smith { 188871f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 188971f1c65dSBarry Smith PetscErrorCode ierr; 1890d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 189154f21887SBarry Smith MatScalar *v = a->a; 189254f21887SBarry Smith PetscScalar *idiag,*mdiag; 189371f1c65dSBarry Smith 189471f1c65dSBarry Smith PetscFunctionBegin; 189571f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 189671f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 189771f1c65dSBarry Smith diag = a->diag; 189871f1c65dSBarry Smith if (!a->idiag) { 1899dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19003bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 190171f1c65dSBarry Smith v = a->a; 190271f1c65dSBarry Smith } 190371f1c65dSBarry Smith mdiag = a->mdiag; 190471f1c65dSBarry Smith idiag = a->idiag; 190571f1c65dSBarry Smith 1906422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 190771f1c65dSBarry Smith for (i=0; i<m; i++) { 190871f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1909899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1910899639b0SHong Zhang if (PetscRealPart(fshift)) { 1911899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19127b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19137b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19147b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1915a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1916899639b0SHong Zhang } 191771f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 191871f1c65dSBarry Smith } 191971f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 192071f1c65dSBarry Smith } else { 192171f1c65dSBarry Smith for (i=0; i<m; i++) { 192271f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 192371f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 192471f1c65dSBarry Smith } 1925dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 192671f1c65dSBarry Smith } 192771f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 192871f1c65dSBarry Smith PetscFunctionReturn(0); 192971f1c65dSBarry Smith } 193071f1c65dSBarry Smith 1931c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 193241f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 193317ab2063SBarry Smith { 1934416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1935e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1936f4259b30SLisandro Dalcin const MatScalar *v,*idiag=NULL,*mdiag; 193754f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1938dfbe8321SBarry Smith PetscErrorCode ierr; 19393d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 194097f1f81fSBarry Smith const PetscInt *idx,*diag; 194117ab2063SBarry Smith 19423a40ed3dSBarry Smith PetscFunctionBegin; 1943b965ef7fSBarry Smith its = its*lits; 194491723122SBarry Smith 194571f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 194671f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 194771f1c65dSBarry Smith a->fshift = fshift; 194871f1c65dSBarry Smith a->omega = omega; 1949ed480e8bSBarry Smith 195071f1c65dSBarry Smith diag = a->diag; 195171f1c65dSBarry Smith t = a->ssor_work; 1952ed480e8bSBarry Smith idiag = a->idiag; 195371f1c65dSBarry Smith mdiag = a->mdiag; 1954ed480e8bSBarry Smith 19551ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 19563649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1957ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 195817ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 195917ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1960ed480e8bSBarry Smith bs = b; 196117ab2063SBarry Smith for (i=0; i<m; i++) { 196271f1c65dSBarry Smith d = fshift + mdiag[i]; 1963416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1964ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1965ed480e8bSBarry Smith v = a->a + diag[i] + 1; 196617ab2063SBarry Smith sum = b[i]*d/omega; 1967003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 196817ab2063SBarry Smith x[i] = sum; 196917ab2063SBarry Smith } 19701ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19713649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1972efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 19733a40ed3dSBarry Smith PetscFunctionReturn(0); 197417ab2063SBarry Smith } 1975c783ea89SBarry Smith 19762205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 19772205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 19784c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 1979887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 198017ab2063SBarry Smith 198117ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 198217ab2063SBarry Smith 1983887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 198417ab2063SBarry Smith */ 198517ab2063SBarry Smith scale = (2.0/omega) - 1.0; 198617ab2063SBarry Smith 198717ab2063SBarry Smith /* x = (E + U)^{-1} b */ 198817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1989416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1990ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1991ed480e8bSBarry Smith v = a->a + diag[i] + 1; 199217ab2063SBarry Smith sum = b[i]; 1993e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1994ed480e8bSBarry Smith x[i] = sum*idiag[i]; 199517ab2063SBarry Smith } 199617ab2063SBarry Smith 199717ab2063SBarry Smith /* t = b - (2*E - D)x */ 1998416022c9SBarry Smith v = a->a; 19992205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 200017ab2063SBarry Smith 200117ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2002ed480e8bSBarry Smith ts = t; 2003416022c9SBarry Smith diag = a->diag; 200417ab2063SBarry Smith for (i=0; i<m; i++) { 2005416022c9SBarry Smith n = diag[i] - a->i[i]; 2006ed480e8bSBarry Smith idx = a->j + a->i[i]; 2007ed480e8bSBarry Smith v = a->a + a->i[i]; 200817ab2063SBarry Smith sum = t[i]; 2009003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2010ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2011733d66baSBarry Smith /* x = x + t */ 2012733d66baSBarry Smith x[i] += t[i]; 201317ab2063SBarry Smith } 201417ab2063SBarry Smith 2015dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20161ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20173649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20183a40ed3dSBarry Smith PetscFunctionReturn(0); 201917ab2063SBarry Smith } 202017ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 202117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 202217ab2063SBarry Smith for (i=0; i<m; i++) { 2023416022c9SBarry Smith n = diag[i] - a->i[i]; 2024ed480e8bSBarry Smith idx = a->j + a->i[i]; 2025ed480e8bSBarry Smith v = a->a + a->i[i]; 202617ab2063SBarry Smith sum = b[i]; 2027e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20285c99c7daSBarry Smith t[i] = sum; 2029ed480e8bSBarry Smith x[i] = sum*idiag[i]; 203017ab2063SBarry Smith } 20315c99c7daSBarry Smith xb = t; 2032efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20333a40ed3dSBarry Smith } else xb = b; 203417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 203517ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2036416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2037ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 2038ed480e8bSBarry Smith v = a->a + diag[i] + 1; 203917ab2063SBarry Smith sum = xb[i]; 2040e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20415c99c7daSBarry Smith if (xb == b) { 2042ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20435c99c7daSBarry Smith } else { 2044b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 204517ab2063SBarry Smith } 20465c99c7daSBarry Smith } 2047b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 204817ab2063SBarry Smith } 204917ab2063SBarry Smith its--; 205017ab2063SBarry Smith } 205117ab2063SBarry Smith while (its--) { 205217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 205317ab2063SBarry Smith for (i=0; i<m; i++) { 2054b19a5dc2SMark Adams /* lower */ 2055b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2056ed480e8bSBarry Smith idx = a->j + a->i[i]; 2057ed480e8bSBarry Smith v = a->a + a->i[i]; 205817ab2063SBarry Smith sum = b[i]; 2059e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2060b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2061b19a5dc2SMark Adams /* upper */ 2062b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2063b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 2064b19a5dc2SMark Adams v = a->a + diag[i] + 1; 2065b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2066b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 206717ab2063SBarry Smith } 2068b19a5dc2SMark Adams xb = t; 20699f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2070b19a5dc2SMark Adams } else xb = b; 207117ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 207217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2073b19a5dc2SMark Adams sum = xb[i]; 2074b19a5dc2SMark Adams if (xb == b) { 2075b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2076416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2077ed480e8bSBarry Smith idx = a->j + a->i[i]; 2078ed480e8bSBarry Smith v = a->a + a->i[i]; 2079e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2080ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2081b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2082b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2083b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 2084b19a5dc2SMark Adams v = a->a + diag[i] + 1; 2085b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2086b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 208717ab2063SBarry Smith } 2088b19a5dc2SMark Adams } 2089b19a5dc2SMark Adams if (xb == b) { 20909f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2091b19a5dc2SMark Adams } else { 2092b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2093b19a5dc2SMark Adams } 209417ab2063SBarry Smith } 209517ab2063SBarry Smith } 20961ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20973649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2098365a8a9eSBarry Smith PetscFunctionReturn(0); 209917ab2063SBarry Smith } 210017ab2063SBarry Smith 21012af78befSBarry Smith 2102dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 210317ab2063SBarry Smith { 2104416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21054e220ebcSLois Curfman McInnes 21063a40ed3dSBarry Smith PetscFunctionBegin; 21074e220ebcSLois Curfman McInnes info->block_size = 1.0; 21083966268fSBarry Smith info->nz_allocated = a->maxnz; 21093966268fSBarry Smith info->nz_used = a->nz; 21103966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21113966268fSBarry Smith info->assemblies = A->num_ass; 21123966268fSBarry Smith info->mallocs = A->info.mallocs; 21137adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2114d5f3da31SBarry Smith if (A->factortype) { 21154e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21164e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21174e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21184e220ebcSLois Curfman McInnes } else { 21194e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21204e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21214e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21224e220ebcSLois Curfman McInnes } 21233a40ed3dSBarry Smith PetscFunctionReturn(0); 212417ab2063SBarry Smith } 212517ab2063SBarry Smith 21262b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 212717ab2063SBarry Smith { 2128416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2129c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21306849ba73SBarry Smith PetscErrorCode ierr; 213197b48c8fSBarry Smith const PetscScalar *xx; 213297b48c8fSBarry Smith PetscScalar *bb; 2133c7da8527SEric Chamberland PetscInt d = 0; 213417ab2063SBarry Smith 21353a40ed3dSBarry Smith PetscFunctionBegin; 213697b48c8fSBarry Smith if (x && b) { 213797b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 213897b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 213997b48c8fSBarry Smith for (i=0; i<N; i++) { 214097b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2141447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 214297b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 214397b48c8fSBarry Smith } 214497b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 214597b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 214697b48c8fSBarry Smith } 214797b48c8fSBarry Smith 2148a9817697SBarry Smith if (a->keepnonzeropattern) { 2149f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2150e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2151580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2152f1e2ffcdSBarry Smith } 2153f4df32b1SMatthew Knepley if (diag != 0.0) { 2154c7da8527SEric Chamberland for (i=0; i<N; i++) { 2155c7da8527SEric Chamberland d = rows[i]; 2156447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2157c7da8527SEric 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); 2158c7da8527SEric Chamberland } 2159f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2160447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2161f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 2162f1e2ffcdSBarry Smith } 2163f1e2ffcdSBarry Smith } 2164f1e2ffcdSBarry Smith } else { 2165f4df32b1SMatthew Knepley if (diag != 0.0) { 216617ab2063SBarry Smith for (i=0; i<N; i++) { 2167e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 21687ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2169447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2170447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2171447d62f5SStefano Zampini } else { 2172416022c9SBarry Smith a->ilen[rows[i]] = 1; 2173f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 2174bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2175447d62f5SStefano Zampini } 2176447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2177f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 217817ab2063SBarry Smith } 217917ab2063SBarry Smith } 21803a40ed3dSBarry Smith } else { 218117ab2063SBarry Smith for (i=0; i<N; i++) { 2182e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2183416022c9SBarry Smith a->ilen[rows[i]] = 0; 218417ab2063SBarry Smith } 218517ab2063SBarry Smith } 2186e56f5c9eSBarry Smith A->nonzerostate++; 2187f1e2ffcdSBarry Smith } 21888c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2189c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2190e2cf4d64SStefano Zampini #endif 21914099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21923a40ed3dSBarry Smith PetscFunctionReturn(0); 219317ab2063SBarry Smith } 219417ab2063SBarry Smith 21956e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 21966e169961SBarry Smith { 21976e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21986e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 21996e169961SBarry Smith PetscErrorCode ierr; 22002b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22016e169961SBarry Smith const PetscScalar *xx; 22026e169961SBarry Smith PetscScalar *bb; 22036e169961SBarry Smith 22046e169961SBarry Smith PetscFunctionBegin; 22056e169961SBarry Smith if (x && b) { 22066e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22076e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22082b40b63fSBarry Smith vecs = PETSC_TRUE; 22096e169961SBarry Smith } 22101795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22116e169961SBarry Smith for (i=0; i<N; i++) { 22126e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2213580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22142205254eSKarl Rupp 22156e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22166e169961SBarry Smith } 22176e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22186e169961SBarry Smith if (!zeroed[i]) { 22196e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22204cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22212b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 22226e169961SBarry Smith a->a[j] = 0.0; 22236e169961SBarry Smith } 22246e169961SBarry Smith } 22254cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22266e169961SBarry Smith } 22276e169961SBarry Smith if (x && b) { 22286e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22296e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22306e169961SBarry Smith } 22316e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22326e169961SBarry Smith if (diag != 0.0) { 22336e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22341d5a398dSstefano_zampini if (missing) { 22351d5a398dSstefano_zampini for (i=0; i<N; i++) { 22364cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22374cf107fdSStefano 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]); 22381d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 22391d5a398dSstefano_zampini } 22401d5a398dSstefano_zampini } else { 22416e169961SBarry Smith for (i=0; i<N; i++) { 22426e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 22436e169961SBarry Smith } 22446e169961SBarry Smith } 22451d5a398dSstefano_zampini } 22468c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2247c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2248e2cf4d64SStefano Zampini #endif 22494099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22506e169961SBarry Smith PetscFunctionReturn(0); 22516e169961SBarry Smith } 22526e169961SBarry Smith 2253a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 225417ab2063SBarry Smith { 2255416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 225697f1f81fSBarry Smith PetscInt *itmp; 225717ab2063SBarry Smith 22583a40ed3dSBarry Smith PetscFunctionBegin; 2259e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 226017ab2063SBarry Smith 2261416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 2262bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 226317ab2063SBarry Smith if (idx) { 2264bfeeae90SHong Zhang itmp = a->j + a->i[row]; 226526fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2266f4259b30SLisandro Dalcin else *idx = NULL; 226717ab2063SBarry Smith } 22683a40ed3dSBarry Smith PetscFunctionReturn(0); 226917ab2063SBarry Smith } 227017ab2063SBarry Smith 2271bfeeae90SHong Zhang /* remove this function? */ 2272a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 227317ab2063SBarry Smith { 22743a40ed3dSBarry Smith PetscFunctionBegin; 22753a40ed3dSBarry Smith PetscFunctionReturn(0); 227617ab2063SBarry Smith } 227717ab2063SBarry Smith 2278dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 227917ab2063SBarry Smith { 2280416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 228154f21887SBarry Smith MatScalar *v = a->a; 228236db0b34SBarry Smith PetscReal sum = 0.0; 22836849ba73SBarry Smith PetscErrorCode ierr; 228497f1f81fSBarry Smith PetscInt i,j; 228517ab2063SBarry Smith 22863a40ed3dSBarry Smith PetscFunctionBegin; 228717ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2288570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2289570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 2290570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 2291570b7f6dSBarry Smith #else 2292416022c9SBarry Smith for (i=0; i<a->nz; i++) { 229336db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 229417ab2063SBarry Smith } 22958f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2296570b7f6dSBarry Smith #endif 2297ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 22983a40ed3dSBarry Smith } else if (type == NORM_1) { 229936db0b34SBarry Smith PetscReal *tmp; 230097f1f81fSBarry Smith PetscInt *jj = a->j; 23011795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2302064f8208SBarry Smith *nrm = 0.0; 2303416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2304bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 230517ab2063SBarry Smith } 2306d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2307064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 230817ab2063SBarry Smith } 2309606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 231051f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23113a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2312064f8208SBarry Smith *nrm = 0.0; 2313d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2314bfeeae90SHong Zhang v = a->a + a->i[j]; 231517ab2063SBarry Smith sum = 0.0; 2316416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2317cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 231817ab2063SBarry Smith } 2319064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 232017ab2063SBarry Smith } 232151f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2322f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23233a40ed3dSBarry Smith PetscFunctionReturn(0); 232417ab2063SBarry Smith } 232517ab2063SBarry Smith 23264e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 23274e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 23284e938277SHong Zhang { 23294e938277SHong Zhang PetscErrorCode ierr; 23304e938277SHong Zhang PetscInt i,j,anzj; 23314e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 23324e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 23334e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 23344e938277SHong Zhang 23354e938277SHong Zhang PetscFunctionBegin; 23364e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2337854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2338785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2339785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 23404e938277SHong Zhang 23414e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 23424e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 234326fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 23444e938277SHong Zhang /* Form ati for csr format of A^T. */ 234526fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 23464e938277SHong Zhang 23474e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2348580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 23494e938277SHong Zhang 23504e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 23514e938277SHong Zhang for (i=0;i<am;i++) { 23524e938277SHong Zhang anzj = ai[i+1] - ai[i]; 23534e938277SHong Zhang for (j=0;j<anzj;j++) { 23544e938277SHong Zhang atj[atfill[*aj]] = i; 23554e938277SHong Zhang atfill[*aj++] += 1; 23564e938277SHong Zhang } 23574e938277SHong Zhang } 23584e938277SHong Zhang 23594e938277SHong Zhang /* Clean up temporary space and complete requests. */ 23604e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2361ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 236233d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2363b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2364a2f3521dSMark F. Adams 23654e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 23664e938277SHong Zhang b->free_a = PETSC_FALSE; 23674e938277SHong Zhang b->free_ij = PETSC_TRUE; 23684e938277SHong Zhang b->nonew = 0; 23694e938277SHong Zhang PetscFunctionReturn(0); 23704e938277SHong Zhang } 23714e938277SHong Zhang 23727087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2373cd0d46ebSvictorle { 23743d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 237554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 237654f21887SBarry Smith MatScalar *va,*vb; 23776849ba73SBarry Smith PetscErrorCode ierr; 237897f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2379cd0d46ebSvictorle 2380cd0d46ebSvictorle PetscFunctionBegin; 2381cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2382cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 23835485867bSBarry Smith if (ma!=nb || na!=mb) { 23845485867bSBarry Smith *f = PETSC_FALSE; 23855485867bSBarry Smith PetscFunctionReturn(0); 23865485867bSBarry Smith } 2387cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2388cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2389cd0d46ebSvictorle va = aij->a; vb = bij->a; 2390785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2391785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2392cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2393cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2394cd0d46ebSvictorle 2395cd0d46ebSvictorle *f = PETSC_TRUE; 2396cd0d46ebSvictorle for (i=0; i<ma; i++) { 2397cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 239897f1f81fSBarry Smith PetscInt idc,idr; 23995485867bSBarry Smith PetscScalar vc,vr; 2400cd0d46ebSvictorle /* column/row index/value */ 24015485867bSBarry Smith idc = adx[aptr[i]]; 24025485867bSBarry Smith idr = bdx[bptr[idc]]; 24035485867bSBarry Smith vc = va[aptr[i]]; 24045485867bSBarry Smith vr = vb[bptr[idc]]; 24055485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24065485867bSBarry Smith *f = PETSC_FALSE; 24075485867bSBarry Smith goto done; 2408cd0d46ebSvictorle } else { 24095485867bSBarry Smith aptr[i]++; 24105485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2411cd0d46ebSvictorle } 2412cd0d46ebSvictorle } 2413cd0d46ebSvictorle } 2414cd0d46ebSvictorle done: 2415cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24163aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2417cd0d46ebSvictorle PetscFunctionReturn(0); 2418cd0d46ebSvictorle } 2419cd0d46ebSvictorle 24207087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24211cbb95d3SBarry Smith { 24223d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 242354f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 242454f21887SBarry Smith MatScalar *va,*vb; 24251cbb95d3SBarry Smith PetscErrorCode ierr; 24261cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 24271cbb95d3SBarry Smith 24281cbb95d3SBarry Smith PetscFunctionBegin; 24291cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 24301cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24311cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 24321cbb95d3SBarry Smith *f = PETSC_FALSE; 24331cbb95d3SBarry Smith PetscFunctionReturn(0); 24341cbb95d3SBarry Smith } 24351cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 24361cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 24371cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2438785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2439785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 24401cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 24411cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 24421cbb95d3SBarry Smith 24431cbb95d3SBarry Smith *f = PETSC_TRUE; 24441cbb95d3SBarry Smith for (i=0; i<ma; i++) { 24451cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 24461cbb95d3SBarry Smith PetscInt idc,idr; 24471cbb95d3SBarry Smith PetscScalar vc,vr; 24481cbb95d3SBarry Smith /* column/row index/value */ 24491cbb95d3SBarry Smith idc = adx[aptr[i]]; 24501cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 24511cbb95d3SBarry Smith vc = va[aptr[i]]; 24521cbb95d3SBarry Smith vr = vb[bptr[idc]]; 24531cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 24541cbb95d3SBarry Smith *f = PETSC_FALSE; 24551cbb95d3SBarry Smith goto done; 24561cbb95d3SBarry Smith } else { 24571cbb95d3SBarry Smith aptr[i]++; 24581cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 24591cbb95d3SBarry Smith } 24601cbb95d3SBarry Smith } 24611cbb95d3SBarry Smith } 24621cbb95d3SBarry Smith done: 24631cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 24641cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 24651cbb95d3SBarry Smith PetscFunctionReturn(0); 24661cbb95d3SBarry Smith } 24671cbb95d3SBarry Smith 2468ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24699e29f15eSvictorle { 2470dfbe8321SBarry Smith PetscErrorCode ierr; 24716e111a19SKarl Rupp 24729e29f15eSvictorle PetscFunctionBegin; 24735485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 24749e29f15eSvictorle PetscFunctionReturn(0); 24759e29f15eSvictorle } 24769e29f15eSvictorle 2477ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24781cbb95d3SBarry Smith { 24791cbb95d3SBarry Smith PetscErrorCode ierr; 24806e111a19SKarl Rupp 24811cbb95d3SBarry Smith PetscFunctionBegin; 24821cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 24831cbb95d3SBarry Smith PetscFunctionReturn(0); 24841cbb95d3SBarry Smith } 24851cbb95d3SBarry Smith 2486dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 248717ab2063SBarry Smith { 2488416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2489fff8e43fSBarry Smith const PetscScalar *l,*r; 2490fff8e43fSBarry Smith PetscScalar x; 249154f21887SBarry Smith MatScalar *v; 2492dfbe8321SBarry Smith PetscErrorCode ierr; 2493fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2494fff8e43fSBarry Smith const PetscInt *jj; 249517ab2063SBarry Smith 24963a40ed3dSBarry Smith PetscFunctionBegin; 249717ab2063SBarry Smith if (ll) { 24983ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 24993ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2500e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2501e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2502fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 2503416022c9SBarry Smith v = a->a; 250417ab2063SBarry Smith for (i=0; i<m; i++) { 250517ab2063SBarry Smith x = l[i]; 2506416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25072205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 250817ab2063SBarry Smith } 2509fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2510efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 251117ab2063SBarry Smith } 251217ab2063SBarry Smith if (rr) { 2513e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2514e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2515fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 2516416022c9SBarry Smith v = a->a; jj = a->j; 25172205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 2518fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2519efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 252017ab2063SBarry Smith } 2521acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 25228c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2523c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2524e2cf4d64SStefano Zampini #endif 25253a40ed3dSBarry Smith PetscFunctionReturn(0); 252617ab2063SBarry Smith } 252717ab2063SBarry Smith 25287dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 252917ab2063SBarry Smith { 2530db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 25316849ba73SBarry Smith PetscErrorCode ierr; 2532d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 253397f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 25345d0c19d7SBarry Smith const PetscInt *irow,*icol; 25355d0c19d7SBarry Smith PetscInt nrows,ncols; 253697f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 253754f21887SBarry Smith MatScalar *a_new,*mat_a; 2538416022c9SBarry Smith Mat C; 2539cdc6f3adSToby Isaac PetscBool stride; 254017ab2063SBarry Smith 25413a40ed3dSBarry Smith PetscFunctionBegin; 254299141d43SSatish Balay 254317ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2544b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2545b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 254617ab2063SBarry Smith 2547251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2548ff718158SBarry Smith if (stride) { 2549ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2550ff718158SBarry Smith } else { 2551ff718158SBarry Smith first = 0; 2552ff718158SBarry Smith step = 0; 2553ff718158SBarry Smith } 2554fee21e36SBarry Smith if (stride && step == 1) { 255502834360SBarry Smith /* special case of contiguous rows */ 2556dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 255702834360SBarry Smith /* loop over new rows determining lens and starting points */ 255802834360SBarry Smith for (i=0; i<nrows; i++) { 2559bfeeae90SHong Zhang kstart = ai[irow[i]]; 2560a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2561a91a9bebSLisandro Dalcin starts[i] = kstart; 256202834360SBarry Smith for (k=kstart; k<kend; k++) { 2563bfeeae90SHong Zhang if (aj[k] >= first) { 256402834360SBarry Smith starts[i] = k; 256502834360SBarry Smith break; 256602834360SBarry Smith } 256702834360SBarry Smith } 2568a2744918SBarry Smith sum = 0; 256902834360SBarry Smith while (k < kend) { 2570bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2571a2744918SBarry Smith sum++; 257202834360SBarry Smith } 2573a2744918SBarry Smith lens[i] = sum; 257402834360SBarry Smith } 257502834360SBarry Smith /* create submatrix */ 2576cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 257797f1f81fSBarry Smith PetscInt n_cols,n_rows; 257808480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2579e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2580d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 258108480c60SBarry Smith C = *B; 25823a40ed3dSBarry Smith } else { 25833bef6203SJed Brown PetscInt rbs,cbs; 2584ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2585f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 25863bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 25873bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 25883bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 25897adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2590ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 259108480c60SBarry Smith } 2592db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2593db02288aSLois Curfman McInnes 259402834360SBarry Smith /* loop over rows inserting into submatrix */ 2595db02288aSLois Curfman McInnes a_new = c->a; 2596db02288aSLois Curfman McInnes j_new = c->j; 2597db02288aSLois Curfman McInnes i_new = c->i; 2598bfeeae90SHong Zhang 259902834360SBarry Smith for (i=0; i<nrows; i++) { 2600a2744918SBarry Smith ii = starts[i]; 2601a2744918SBarry Smith lensi = lens[i]; 2602a2744918SBarry Smith for (k=0; k<lensi; k++) { 2603a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 260402834360SBarry Smith } 2605580bdb30SBarry Smith ierr = PetscArraycpy(a_new,a->a + starts[i],lensi);CHKERRQ(ierr); 2606a2744918SBarry Smith a_new += lensi; 2607a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2608a2744918SBarry Smith c->ilen[i] = lensi; 260902834360SBarry Smith } 26100e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26113a40ed3dSBarry Smith } else { 261202834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 26131795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2614854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 26154dcab191SBarry Smith for (i=0; i<ncols; i++) { 2616d9ef940eSSatish 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); 26174dcab191SBarry Smith smap[icol[i]] = i+1; 26184dcab191SBarry Smith } 26194dcab191SBarry Smith 262002834360SBarry Smith /* determine lens of each row */ 262102834360SBarry Smith for (i=0; i<nrows; i++) { 2622bfeeae90SHong Zhang kstart = ai[irow[i]]; 262302834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 262402834360SBarry Smith lens[i] = 0; 262502834360SBarry Smith for (k=kstart; k<kend; k++) { 2626bfeeae90SHong Zhang if (smap[aj[k]]) { 262702834360SBarry Smith lens[i]++; 262802834360SBarry Smith } 262902834360SBarry Smith } 263002834360SBarry Smith } 263117ab2063SBarry Smith /* Create and fill new matrix */ 2632a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2633ace3abfcSBarry Smith PetscBool equal; 26340f5bd95cSBarry Smith 263599141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2636e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2637580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2638f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2639580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 264008480c60SBarry Smith C = *B; 26413a40ed3dSBarry Smith } else { 26423bef6203SJed Brown PetscInt rbs,cbs; 2643ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2644f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26453bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26463bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26473bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26487adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2649ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 265008480c60SBarry Smith } 265199141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 265217ab2063SBarry Smith for (i=0; i<nrows; i++) { 265399141d43SSatish Balay row = irow[i]; 2654bfeeae90SHong Zhang kstart = ai[row]; 265599141d43SSatish Balay kend = kstart + a->ilen[row]; 2656bfeeae90SHong Zhang mat_i = c->i[i]; 265799141d43SSatish Balay mat_j = c->j + mat_i; 265899141d43SSatish Balay mat_a = c->a + mat_i; 265999141d43SSatish Balay mat_ilen = c->ilen + i; 266017ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2661bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2662ed480e8bSBarry Smith *mat_j++ = tcol - 1; 266399141d43SSatish Balay *mat_a++ = a->a[k]; 266499141d43SSatish Balay (*mat_ilen)++; 266599141d43SSatish Balay 266617ab2063SBarry Smith } 266717ab2063SBarry Smith } 266817ab2063SBarry Smith } 266902834360SBarry Smith /* Free work space */ 267002834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2671606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2672606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2673cdc6f3adSToby Isaac /* sort */ 2674cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2675cdc6f3adSToby Isaac PetscInt ilen; 2676cdc6f3adSToby Isaac 2677cdc6f3adSToby Isaac mat_i = c->i[i]; 2678cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2679cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2680cdc6f3adSToby Isaac ilen = c->ilen[i]; 2681390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2682cdc6f3adSToby Isaac } 268302834360SBarry Smith } 26848c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2685b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2686305c6ccfSStefano Zampini #endif 26876d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26886d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 268917ab2063SBarry Smith 269017ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2691416022c9SBarry Smith *B = C; 26923a40ed3dSBarry Smith PetscFunctionReturn(0); 269317ab2063SBarry Smith } 269417ab2063SBarry Smith 2695fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 269682d44351SHong Zhang { 269782d44351SHong Zhang PetscErrorCode ierr; 269882d44351SHong Zhang Mat B; 269982d44351SHong Zhang 270082d44351SHong Zhang PetscFunctionBegin; 2701c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 270282d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 270382d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 270433d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 270582d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 270682d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 270782d44351SHong Zhang *subMat = B; 2708c2d650bdSHong Zhang } else { 2709c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2710c2d650bdSHong Zhang } 271182d44351SHong Zhang PetscFunctionReturn(0); 271282d44351SHong Zhang } 271382d44351SHong Zhang 27149a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2715a871dcd8SBarry Smith { 271663b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2717dfbe8321SBarry Smith PetscErrorCode ierr; 271863b91edcSBarry Smith Mat outA; 2719ace3abfcSBarry Smith PetscBool row_identity,col_identity; 272063b91edcSBarry Smith 27213a40ed3dSBarry Smith PetscFunctionBegin; 2722e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 27231df811f5SHong Zhang 2724b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2725b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2726a871dcd8SBarry Smith 272763b91edcSBarry Smith outA = inA; 2728d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2729f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2730f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 27312205254eSKarl Rupp 2732c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 27336bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 27342205254eSKarl Rupp 2735c3122656SLisandro Dalcin a->row = row; 27362205254eSKarl Rupp 2737c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 27386bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 27392205254eSKarl Rupp 2740c3122656SLisandro Dalcin a->col = col; 274163b91edcSBarry Smith 274236db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 27436bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 27444c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 27453bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2746f0ec6fceSSatish Balay 274794a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2748854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 27493bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 275094a9d846SBarry Smith } 275163b91edcSBarry Smith 2752f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2753137fb511SHong Zhang if (row_identity && col_identity) { 2754ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2755137fb511SHong Zhang } else { 2756719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2757137fb511SHong Zhang } 27583a40ed3dSBarry Smith PetscFunctionReturn(0); 2759a871dcd8SBarry Smith } 2760a871dcd8SBarry Smith 2761f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2762f0b747eeSBarry Smith { 2763f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2764f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2765efee365bSSatish Balay PetscErrorCode ierr; 2766c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 27673a40ed3dSBarry Smith 27683a40ed3dSBarry Smith PetscFunctionBegin; 2769c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 27708b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2771efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2772acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 27738c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2774c70f7ee4SJunchao Zhang if (inA->offloadmask != PETSC_OFFLOAD_UNALLOCATED) inA->offloadmask = PETSC_OFFLOAD_CPU; 2775e2cf4d64SStefano Zampini #endif 27763a40ed3dSBarry Smith PetscFunctionReturn(0); 2777f0b747eeSBarry Smith } 2778f0b747eeSBarry Smith 2779f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 278016b64355SHong Zhang { 278116b64355SHong Zhang PetscErrorCode ierr; 278216b64355SHong Zhang PetscInt i; 278316b64355SHong Zhang 278416b64355SHong Zhang PetscFunctionBegin; 278516b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 278616b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 278716b64355SHong Zhang 278816b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 278916b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 279016b64355SHong Zhang } 279116b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 279216b64355SHong Zhang 279316b64355SHong Zhang if (submatj->rbuf1) { 279416b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 279516b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 279616b64355SHong Zhang } 279716b64355SHong Zhang 279816b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 279916b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 280016b64355SHong Zhang } 280116b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 280216b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 280316b64355SHong Zhang } 280416b64355SHong Zhang 280516b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 280616b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 280716b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 280816b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 280916b64355SHong Zhang #else 281016b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 281116b64355SHong Zhang #endif 281216b64355SHong Zhang 281316b64355SHong Zhang if (!submatj->allcolumns) { 281416b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 281516b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 281616b64355SHong Zhang #else 281716b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 281816b64355SHong Zhang #endif 281916b64355SHong Zhang } 282016b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 282116b64355SHong Zhang 282216b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 282316b64355SHong Zhang PetscFunctionReturn(0); 282416b64355SHong Zhang } 282516b64355SHong Zhang 28260fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 282716b64355SHong Zhang { 282816b64355SHong Zhang PetscErrorCode ierr; 282916b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 28305c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 283116b64355SHong Zhang 283216b64355SHong Zhang PetscFunctionBegin; 283334136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2834f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 283516b64355SHong Zhang PetscFunctionReturn(0); 283616b64355SHong Zhang } 283716b64355SHong Zhang 28382d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 28392d033e1fSHong Zhang { 28402d033e1fSHong Zhang PetscErrorCode ierr; 28412d033e1fSHong Zhang PetscInt i; 28420fb991dcSHong Zhang Mat C; 28430fb991dcSHong Zhang Mat_SeqAIJ *c; 28440fb991dcSHong Zhang Mat_SubSppt *submatj; 28452d033e1fSHong Zhang 28462d033e1fSHong Zhang PetscFunctionBegin; 28472d033e1fSHong Zhang for (i=0; i<n; i++) { 28480fb991dcSHong Zhang C = (*mat)[i]; 28490fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 28500fb991dcSHong Zhang submatj = c->submatis1; 28512d033e1fSHong Zhang if (submatj) { 2852682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 285334136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2854f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 285534136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 28562d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 28572d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 28582d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2859682e4c99SStefano Zampini } 28602d033e1fSHong Zhang } else { 28612d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 28622d033e1fSHong Zhang } 28632d033e1fSHong Zhang } 286486e85357SHong Zhang 286563a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 286663a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 286763a75b2aSHong Zhang 28682d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 28692d033e1fSHong Zhang PetscFunctionReturn(0); 28702d033e1fSHong Zhang } 28712d033e1fSHong Zhang 28727dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2873cddf8d76SBarry Smith { 2874dfbe8321SBarry Smith PetscErrorCode ierr; 287597f1f81fSBarry Smith PetscInt i; 2876cddf8d76SBarry Smith 28773a40ed3dSBarry Smith PetscFunctionBegin; 2878cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2879df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2880cddf8d76SBarry Smith } 2881cddf8d76SBarry Smith 2882cddf8d76SBarry Smith for (i=0; i<n; i++) { 28837dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2884cddf8d76SBarry Smith } 28853a40ed3dSBarry Smith PetscFunctionReturn(0); 2886cddf8d76SBarry Smith } 2887cddf8d76SBarry Smith 288897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 28894dcbc457SBarry Smith { 2890e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 28916849ba73SBarry Smith PetscErrorCode ierr; 28925d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 28935d0c19d7SBarry Smith const PetscInt *idx; 289497f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2895f1af5d2fSBarry Smith PetscBT table; 2896bbd702dbSSatish Balay 28973a40ed3dSBarry Smith PetscFunctionBegin; 2898d0f46423SBarry Smith m = A->rmap->n; 2899e4d965acSSatish Balay ai = a->i; 2900bfeeae90SHong Zhang aj = a->j; 29018a047759SSatish Balay 2902e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 290306763907SSatish Balay 2904854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 290553b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 290606763907SSatish Balay 2907e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2908b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2909e4d965acSSatish Balay isz = 0; 29106831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2911e4d965acSSatish Balay 2912e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29134dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2914b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2915e4d965acSSatish Balay 2916dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2917e4d965acSSatish Balay for (j=0; j<n; ++j) { 29182205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 29194dcbc457SBarry Smith } 292006763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 29216bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2922e4d965acSSatish Balay 292304a348a9SBarry Smith k = 0; 292404a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 292504a348a9SBarry Smith n = isz; 292606763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2927e4d965acSSatish Balay row = nidx[k]; 2928e4d965acSSatish Balay start = ai[row]; 2929e4d965acSSatish Balay end = ai[row+1]; 293004a348a9SBarry Smith for (l = start; l<end; l++) { 2931efb16452SHong Zhang val = aj[l]; 29322205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2933e4d965acSSatish Balay } 2934e4d965acSSatish Balay } 2935e4d965acSSatish Balay } 293670b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2937e4d965acSSatish Balay } 293894bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2939606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 29403a40ed3dSBarry Smith PetscFunctionReturn(0); 29414dcbc457SBarry Smith } 294217ab2063SBarry Smith 29430513a670SBarry Smith /* -------------------------------------------------------------- */ 2944dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 29450513a670SBarry Smith { 29460513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29476849ba73SBarry Smith PetscErrorCode ierr; 29483b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 29495d0c19d7SBarry Smith const PetscInt *row,*col; 29505d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 295156cd22aeSBarry Smith IS icolp,irowp; 29520298fd71SBarry Smith PetscInt *cwork = NULL; 29530298fd71SBarry Smith PetscScalar *vwork = NULL; 29540513a670SBarry Smith 29553a40ed3dSBarry Smith PetscFunctionBegin; 29564c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 295756cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 29584c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 295956cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 29600513a670SBarry Smith 29610513a670SBarry Smith /* determine lengths of permuted rows */ 2962854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 29632205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2964ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2965f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 296633d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 29677adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2968ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2969606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 29700513a670SBarry Smith 2971785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 29720513a670SBarry Smith for (i=0; i<m; i++) { 297332ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 29742205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2975cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 297632ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 29770513a670SBarry Smith } 2978606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 29792205254eSKarl Rupp 29803c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 29812205254eSKarl Rupp 29828c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2983b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 29849fe5e383SStefano Zampini #endif 29850513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29860513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 298756cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 298856cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 29896bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 29906bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 29916768869dSprj- if (rowp == colp) { 29926768869dSprj- if (A->symmetric) { 29936768869dSprj- ierr = MatSetOption(*B,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 29946768869dSprj- } 29956768869dSprj- if (A->hermitian) { 29966768869dSprj- ierr = MatSetOption(*B,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 29976768869dSprj- } 29986768869dSprj- } 29993a40ed3dSBarry Smith PetscFunctionReturn(0); 30000513a670SBarry Smith } 30010513a670SBarry Smith 3002dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3003cb5b572fSBarry Smith { 3004dfbe8321SBarry Smith PetscErrorCode ierr; 3005cb5b572fSBarry Smith 3006cb5b572fSBarry Smith PetscFunctionBegin; 300733f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 300833f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3009be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3010be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 3011be6bf707SBarry Smith 30124d805d7cSStefano 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]); 3013580bdb30SBarry Smith ierr = PetscArraycpy(b->a,a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 3014cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3015cb5b572fSBarry Smith } else { 3016cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3017cb5b572fSBarry Smith } 3018cb5b572fSBarry Smith PetscFunctionReturn(0); 3019cb5b572fSBarry Smith } 3020cb5b572fSBarry Smith 30214994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3022273d9f13SBarry Smith { 3023dfbe8321SBarry Smith PetscErrorCode ierr; 3024273d9f13SBarry Smith 3025273d9f13SBarry Smith PetscFunctionBegin; 3026f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3027273d9f13SBarry Smith PetscFunctionReturn(0); 3028273d9f13SBarry Smith } 3029273d9f13SBarry Smith 3030f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 30316c0721eeSBarry Smith { 30326c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30336e111a19SKarl Rupp 30346c0721eeSBarry Smith PetscFunctionBegin; 30356c0721eeSBarry Smith *array = a->a; 30366c0721eeSBarry Smith PetscFunctionReturn(0); 30376c0721eeSBarry Smith } 30386c0721eeSBarry Smith 3039f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 30406c0721eeSBarry Smith { 30416c0721eeSBarry Smith PetscFunctionBegin; 3042f38c1e66SStefano Zampini *array = NULL; 30436c0721eeSBarry Smith PetscFunctionReturn(0); 30446c0721eeSBarry Smith } 3045273d9f13SBarry Smith 30468229c054SShri Abhyankar /* 30478229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 30488229c054SShri Abhyankar have different nonzero structure. 30498229c054SShri Abhyankar */ 3050b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3051ec7775f6SShri Abhyankar { 3052b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3053ec7775f6SShri Abhyankar 3054ec7775f6SShri Abhyankar PetscFunctionBegin; 3055ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3056ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3057b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3058b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3059b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 30608af7cee1SJed Brown nnz[i] = 0; 30618af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3062b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3063b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 30648af7cee1SJed Brown nnz[i]++; 30658af7cee1SJed Brown } 30668af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3067ec7775f6SShri Abhyankar } 3068ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3069ec7775f6SShri Abhyankar } 3070ec7775f6SShri Abhyankar 3071b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3072b264fe52SHong Zhang { 3073b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3074b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3075b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3076b264fe52SHong Zhang PetscErrorCode ierr; 3077b264fe52SHong Zhang 3078b264fe52SHong Zhang PetscFunctionBegin; 3079b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3080b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3081b264fe52SHong Zhang PetscFunctionReturn(0); 3082b264fe52SHong Zhang } 3083b264fe52SHong Zhang 3084f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3085ac90fabeSBarry Smith { 3086dfbe8321SBarry Smith PetscErrorCode ierr; 3087ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3088ac90fabeSBarry Smith 3089ac90fabeSBarry Smith PetscFunctionBegin; 309081fa06acSBarry Smith if (str == DIFFERENT_NONZERO_PATTERN) { 309181fa06acSBarry Smith if (x->nz == y->nz) { 309281fa06acSBarry Smith PetscBool e; 309381fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 309481fa06acSBarry Smith if (e) { 309581fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 309681fa06acSBarry Smith if (e) { 309781fa06acSBarry Smith str = SAME_NONZERO_PATTERN; 309881fa06acSBarry Smith } 309981fa06acSBarry Smith } 310081fa06acSBarry Smith } 310181fa06acSBarry Smith } 3102ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 3103f4df32b1SMatthew Knepley PetscScalar alpha = a; 310481fa06acSBarry Smith PetscBLASInt one = 1,bnz; 310581fa06acSBarry Smith 310681fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31078b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 3108acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3109a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 311081fa06acSBarry Smith /* the MatAXPY_Basic* subroutines calls MatAssembly, so the matrix on the GPU will be updated */ 31118c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3112c70f7ee4SJunchao Zhang if (Y->offloadmask != PETSC_OFFLOAD_UNALLOCATED) { 3113c70f7ee4SJunchao Zhang Y->offloadmask = PETSC_OFFLOAD_CPU; 3114e2cf4d64SStefano Zampini } 3115e2cf4d64SStefano Zampini #endif 3116ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3117ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3118ac90fabeSBarry Smith } else { 31198229c054SShri Abhyankar Mat B; 31208229c054SShri Abhyankar PetscInt *nnz; 3121785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3122ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3123bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 312481fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 3125176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 31268229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3127ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3128ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 312928be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 31308229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3131ac90fabeSBarry Smith } 3132ac90fabeSBarry Smith PetscFunctionReturn(0); 3133ac90fabeSBarry Smith } 3134ac90fabeSBarry Smith 31357087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3136354c94deSBarry Smith { 3137354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3138354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3139354c94deSBarry Smith PetscInt i,nz; 3140354c94deSBarry Smith PetscScalar *a; 3141354c94deSBarry Smith 3142354c94deSBarry Smith PetscFunctionBegin; 3143354c94deSBarry Smith nz = aij->nz; 3144354c94deSBarry Smith a = aij->a; 31452205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 31468c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3147c70f7ee4SJunchao Zhang if (mat->offloadmask != PETSC_OFFLOAD_UNALLOCATED) mat->offloadmask = PETSC_OFFLOAD_CPU; 3148e2cf4d64SStefano Zampini #endif 3149354c94deSBarry Smith #else 3150354c94deSBarry Smith PetscFunctionBegin; 3151354c94deSBarry Smith #endif 3152354c94deSBarry Smith PetscFunctionReturn(0); 3153354c94deSBarry Smith } 3154354c94deSBarry Smith 3155985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3156e34fafa9SBarry Smith { 3157e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3158e34fafa9SBarry Smith PetscErrorCode ierr; 3159d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3160e34fafa9SBarry Smith PetscReal atmp; 3161985db425SBarry Smith PetscScalar *x; 3162e34fafa9SBarry Smith MatScalar *aa; 3163e34fafa9SBarry Smith 3164e34fafa9SBarry Smith PetscFunctionBegin; 3165e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3166e34fafa9SBarry Smith aa = a->a; 3167e34fafa9SBarry Smith ai = a->i; 3168e34fafa9SBarry Smith aj = a->j; 3169e34fafa9SBarry Smith 3170985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3171475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3172e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3173e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3174e34fafa9SBarry Smith for (i=0; i<m; i++) { 3175e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3176e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3177985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3178985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3179985db425SBarry Smith aa++; aj++; 3180985db425SBarry Smith } 3181985db425SBarry Smith } 3182475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3183985db425SBarry Smith PetscFunctionReturn(0); 3184985db425SBarry Smith } 3185985db425SBarry Smith 3186985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3187985db425SBarry Smith { 3188985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3189985db425SBarry Smith PetscErrorCode ierr; 3190d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3191985db425SBarry Smith PetscScalar *x; 3192985db425SBarry Smith MatScalar *aa; 3193985db425SBarry Smith 3194985db425SBarry Smith PetscFunctionBegin; 3195e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3196985db425SBarry Smith aa = a->a; 3197985db425SBarry Smith ai = a->i; 3198985db425SBarry Smith aj = a->j; 3199985db425SBarry Smith 3200985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3201fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3202985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3203e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3204985db425SBarry Smith for (i=0; i<m; i++) { 3205985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3206d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3207985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3208985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3209985db425SBarry Smith x[i] = 0.0; 3210985db425SBarry Smith if (idx) { 3211985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3212985db425SBarry Smith if (aj[j] > j) { 3213985db425SBarry Smith idx[i] = j; 3214985db425SBarry Smith break; 3215985db425SBarry Smith } 3216985db425SBarry Smith } 32171a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 32181a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3219985db425SBarry Smith } 3220985db425SBarry Smith } 3221985db425SBarry Smith for (j=0; j<ncols; j++) { 3222985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3223985db425SBarry Smith aa++; aj++; 3224985db425SBarry Smith } 3225985db425SBarry Smith } 3226fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3227985db425SBarry Smith PetscFunctionReturn(0); 3228985db425SBarry Smith } 3229985db425SBarry Smith 3230c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3231c87e5d42SMatthew Knepley { 3232c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3233c87e5d42SMatthew Knepley PetscErrorCode ierr; 3234c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 32354e879edeSHong Zhang PetscScalar *x,*aa; 3236c87e5d42SMatthew Knepley 3237c87e5d42SMatthew Knepley PetscFunctionBegin; 3238c87e5d42SMatthew Knepley aa = a->a; 3239c87e5d42SMatthew Knepley ai = a->i; 3240c87e5d42SMatthew Knepley aj = a->j; 3241c87e5d42SMatthew Knepley 3242c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3243f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3244c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3245f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3246c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3247c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3248f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3249f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3250f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3251f07e67edSHong Zhang x[i] = 0.0; 3252f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3253289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3254f07e67edSHong Zhang if (aj[j] > j) { 3255f07e67edSHong Zhang idx[i] = j; 32562205254eSKarl Rupp break; 32572205254eSKarl Rupp } 3258289a08f5SMatthew Knepley } 3259f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3260f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3261f07e67edSHong Zhang } 3262289a08f5SMatthew Knepley } 3263c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3264f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3265c87e5d42SMatthew Knepley aa++; aj++; 3266c87e5d42SMatthew Knepley } 3267c87e5d42SMatthew Knepley } 3268f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3269c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3270c87e5d42SMatthew Knepley } 3271c87e5d42SMatthew Knepley 3272985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3273985db425SBarry Smith { 3274985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3275985db425SBarry Smith PetscErrorCode ierr; 3276d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3277d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3278985db425SBarry Smith PetscScalar *x; 3279d9ca1df4SBarry Smith const MatScalar *aa; 3280985db425SBarry Smith 3281985db425SBarry Smith PetscFunctionBegin; 3282e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3283985db425SBarry Smith aa = a->a; 3284985db425SBarry Smith ai = a->i; 3285985db425SBarry Smith aj = a->j; 3286985db425SBarry Smith 3287985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3288fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3289985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3290f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3291985db425SBarry Smith for (i=0; i<m; i++) { 3292985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3293d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3294985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3295985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3296985db425SBarry Smith x[i] = 0.0; 3297985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3298985db425SBarry Smith for (j=0; j<ncols; j++) { 3299985db425SBarry Smith if (aj[j] > j) { 3300985db425SBarry Smith idx[i] = j; 3301985db425SBarry Smith break; 3302985db425SBarry Smith } 3303985db425SBarry Smith } 3304fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3305fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3306985db425SBarry Smith } 3307985db425SBarry Smith } 3308985db425SBarry Smith for (j=0; j<ncols; j++) { 3309985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3310985db425SBarry Smith aa++; aj++; 3311e34fafa9SBarry Smith } 3312e34fafa9SBarry Smith } 3313fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3314e34fafa9SBarry Smith PetscFunctionReturn(0); 3315e34fafa9SBarry Smith } 3316bbead8a2SBarry Smith 3317713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3318bbead8a2SBarry Smith { 3319bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3320bbead8a2SBarry Smith PetscErrorCode ierr; 332133d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3322bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 33230da83c2eSBarry Smith const PetscReal shift = 0.0; 33241a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3325bbead8a2SBarry Smith 3326bbead8a2SBarry Smith PetscFunctionBegin; 3327a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 33284a0d0026SBarry Smith if (a->ibdiagvalid) { 33294a0d0026SBarry Smith if (values) *values = a->ibdiag; 33304a0d0026SBarry Smith PetscFunctionReturn(0); 33314a0d0026SBarry Smith } 3332bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3333bbead8a2SBarry Smith if (!a->ibdiag) { 3334785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 33353bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3336bbead8a2SBarry Smith } 3337bbead8a2SBarry Smith diag = a->ibdiag; 3338bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3339bbead8a2SBarry Smith /* factor and invert each block */ 3340bbead8a2SBarry Smith switch (bs) { 3341bbead8a2SBarry Smith case 1: 3342bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3343bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3344ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3345ec1892c8SHong Zhang if (allowzeropivot) { 33467b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33477b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 33487b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 33497b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 33507b6c816cSBarry 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); 3351ec1892c8SHong Zhang } 3352bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3353bbead8a2SBarry Smith } 3354bbead8a2SBarry Smith break; 3355bbead8a2SBarry Smith case 2: 3356bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3357bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3358bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3359a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33607b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 336196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3362bbead8a2SBarry Smith diag += 4; 3363bbead8a2SBarry Smith } 3364bbead8a2SBarry Smith break; 3365bbead8a2SBarry Smith case 3: 3366bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3367bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3368bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3369a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33707b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 337196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3372bbead8a2SBarry Smith diag += 9; 3373bbead8a2SBarry Smith } 3374bbead8a2SBarry Smith break; 3375bbead8a2SBarry Smith case 4: 3376bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3377bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3378bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3379a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33807b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 338196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3382bbead8a2SBarry Smith diag += 16; 3383bbead8a2SBarry Smith } 3384bbead8a2SBarry Smith break; 3385bbead8a2SBarry Smith case 5: 3386bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3387bbead8a2SBarry 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; 3388bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3389a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33907b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 339196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3392bbead8a2SBarry Smith diag += 25; 3393bbead8a2SBarry Smith } 3394bbead8a2SBarry Smith break; 3395bbead8a2SBarry Smith case 6: 3396bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3397bbead8a2SBarry 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; 3398bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3399a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34007b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 340196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3402bbead8a2SBarry Smith diag += 36; 3403bbead8a2SBarry Smith } 3404bbead8a2SBarry Smith break; 3405bbead8a2SBarry Smith case 7: 3406bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3407bbead8a2SBarry 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; 3408bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3409a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34107b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 341196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3412bbead8a2SBarry Smith diag += 49; 3413bbead8a2SBarry Smith } 3414bbead8a2SBarry Smith break; 3415bbead8a2SBarry Smith default: 3416dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3417bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3418bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3419bbead8a2SBarry Smith IJ[j] = bs*i + j; 3420bbead8a2SBarry Smith } 3421bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 34225f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34237b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 342496b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3425bbead8a2SBarry Smith diag += bs2; 3426bbead8a2SBarry Smith } 3427bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3428bbead8a2SBarry Smith } 3429bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3430bbead8a2SBarry Smith PetscFunctionReturn(0); 3431bbead8a2SBarry Smith } 3432bbead8a2SBarry Smith 343373a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 343473a71a0fSBarry Smith { 343573a71a0fSBarry Smith PetscErrorCode ierr; 343673a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 343773a71a0fSBarry Smith PetscScalar a; 343873a71a0fSBarry Smith PetscInt m,n,i,j,col; 343973a71a0fSBarry Smith 344073a71a0fSBarry Smith PetscFunctionBegin; 344173a71a0fSBarry Smith if (!x->assembled) { 344273a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 344373a71a0fSBarry Smith for (i=0; i<m; i++) { 344473a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 344573a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 344673a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 344773a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 344873a71a0fSBarry Smith } 344973a71a0fSBarry Smith } 3450e2ce353bSJunchao Zhang } else { 3451e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3452e2ce353bSJunchao Zhang } 345373a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 345473a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 345573a71a0fSBarry Smith PetscFunctionReturn(0); 345673a71a0fSBarry Smith } 345773a71a0fSBarry Smith 3458679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3459679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3460679944adSJunchao Zhang { 3461679944adSJunchao Zhang PetscErrorCode ierr; 3462679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3463679944adSJunchao Zhang PetscScalar a; 3464679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3465679944adSJunchao Zhang 3466679944adSJunchao Zhang PetscFunctionBegin; 3467679944adSJunchao Zhang nskip = high - low; 3468679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3469679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3470679944adSJunchao Zhang for (i=0; i<m; i++) { 3471679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3472679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3473679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3474679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3475679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3476679944adSJunchao Zhang } 3477e2ce353bSJunchao Zhang } 3478679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3479679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3480679944adSJunchao Zhang PetscFunctionReturn(0); 3481679944adSJunchao Zhang } 3482679944adSJunchao Zhang 3483679944adSJunchao Zhang 3484682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 34850a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3486cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3487cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3488cb5b572fSBarry Smith MatMult_SeqAIJ, 348997304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 34907c922b88SBarry Smith MatMultTranspose_SeqAIJ, 34917c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3492f4259b30SLisandro Dalcin NULL, 3493f4259b30SLisandro Dalcin NULL, 3494f4259b30SLisandro Dalcin NULL, 3495f4259b30SLisandro Dalcin /* 10*/ NULL, 3496cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3497f4259b30SLisandro Dalcin NULL, 349841f059aeSBarry Smith MatSOR_SeqAIJ, 349991e9d3e2SHong Zhang MatTranspose_SeqAIJ, 350097304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3501cb5b572fSBarry Smith MatEqual_SeqAIJ, 3502cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3503cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3504cb5b572fSBarry Smith MatNorm_SeqAIJ, 3505f4259b30SLisandro Dalcin /* 20*/ NULL, 3506cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3507cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3508cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3509d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3510f4259b30SLisandro Dalcin NULL, 3511f4259b30SLisandro Dalcin NULL, 3512f4259b30SLisandro Dalcin NULL, 3513f4259b30SLisandro Dalcin NULL, 35144994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3515f4259b30SLisandro Dalcin NULL, 3516f4259b30SLisandro Dalcin NULL, 3517f4259b30SLisandro Dalcin NULL, 3518f4259b30SLisandro Dalcin NULL, 3519d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3520f4259b30SLisandro Dalcin NULL, 3521f4259b30SLisandro Dalcin NULL, 3522cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3523f4259b30SLisandro Dalcin NULL, 3524d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 35257dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3526cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3527cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3528cb5b572fSBarry Smith MatCopy_SeqAIJ, 3529d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3530cb5b572fSBarry Smith MatScale_SeqAIJ, 35317d68702bSBarry Smith MatShift_SeqAIJ, 353279299369SBarry Smith MatDiagonalSet_SeqAIJ, 35336e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 353473a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 35353b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 35363b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 35373b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3538a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 353993dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3540f4259b30SLisandro Dalcin NULL, 3541f4259b30SLisandro Dalcin NULL, 3542cda55fadSBarry Smith MatPermute_SeqAIJ, 3543f4259b30SLisandro Dalcin NULL, 3544f4259b30SLisandro Dalcin /* 59*/ NULL, 3545b9b97703SBarry Smith MatDestroy_SeqAIJ, 3546b9b97703SBarry Smith MatView_SeqAIJ, 3547f4259b30SLisandro Dalcin NULL, 3548f4259b30SLisandro Dalcin NULL, 3549f4259b30SLisandro Dalcin /* 64*/ NULL, 3550321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3551f4259b30SLisandro Dalcin NULL, 3552f4259b30SLisandro Dalcin NULL, 3553f4259b30SLisandro Dalcin NULL, 3554d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3555c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3556f4259b30SLisandro Dalcin NULL, 3557f4259b30SLisandro Dalcin NULL, 3558f4259b30SLisandro Dalcin NULL, 3559f4259b30SLisandro Dalcin /* 74*/ NULL, 35603acb8795SBarry Smith MatFDColoringApply_AIJ, 3561f4259b30SLisandro Dalcin NULL, 3562f4259b30SLisandro Dalcin NULL, 3563f4259b30SLisandro Dalcin NULL, 35646ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3565f4259b30SLisandro Dalcin NULL, 3566f4259b30SLisandro Dalcin NULL, 3567f4259b30SLisandro Dalcin NULL, 3568bc011b1eSHong Zhang MatLoad_SeqAIJ, 3569d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 35701cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3571f4259b30SLisandro Dalcin NULL, 3572f4259b30SLisandro Dalcin NULL, 3573f4259b30SLisandro Dalcin NULL, 3574f4259b30SLisandro Dalcin /* 89*/ NULL, 3575f4259b30SLisandro Dalcin NULL, 357626be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3577f4259b30SLisandro Dalcin NULL, 3578f4259b30SLisandro Dalcin NULL, 35798fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3580f4259b30SLisandro Dalcin NULL, 3581f4259b30SLisandro Dalcin NULL, 35826fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3583f4259b30SLisandro Dalcin NULL, 35844222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3585f4259b30SLisandro Dalcin NULL, 3586f4259b30SLisandro Dalcin NULL, 358787d4246cSBarry Smith MatConjugate_SeqAIJ, 3588f4259b30SLisandro Dalcin NULL, 3589d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 359099cafbc1SBarry Smith MatRealPart_SeqAIJ, 3591f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3592f4259b30SLisandro Dalcin NULL, 3593f4259b30SLisandro Dalcin NULL, 3594cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3595f4259b30SLisandro Dalcin NULL, 35962af78befSBarry Smith MatGetRowMin_SeqAIJ, 3597f4259b30SLisandro Dalcin NULL, 3598599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3599f4259b30SLisandro Dalcin /*114*/ NULL, 3600f4259b30SLisandro Dalcin NULL, 3601f4259b30SLisandro Dalcin NULL, 3602f4259b30SLisandro Dalcin NULL, 3603f4259b30SLisandro Dalcin NULL, 3604f4259b30SLisandro Dalcin /*119*/ NULL, 3605f4259b30SLisandro Dalcin NULL, 3606f4259b30SLisandro Dalcin NULL, 3607f4259b30SLisandro Dalcin NULL, 3608b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 36090716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3610bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 361137868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 36120da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3613f4259b30SLisandro Dalcin NULL, 3614f4259b30SLisandro Dalcin /*129*/ NULL, 3615f4259b30SLisandro Dalcin NULL, 3616f4259b30SLisandro Dalcin NULL, 361775648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3618b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3619b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 36202b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3621f4259b30SLisandro Dalcin NULL, 3622f4259b30SLisandro Dalcin NULL, 36233964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3624f4259b30SLisandro Dalcin /*139*/NULL, 3625f4259b30SLisandro Dalcin NULL, 3626f4259b30SLisandro Dalcin NULL, 36273a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 36289c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 36294222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 36304222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3631f4259b30SLisandro Dalcin NULL, 3632f4259b30SLisandro Dalcin NULL 36339e29f15eSvictorle }; 363417ab2063SBarry Smith 36357087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3636bef8e0ddSBarry Smith { 3637bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 363897f1f81fSBarry Smith PetscInt i,nz,n; 3639bef8e0ddSBarry Smith 3640bef8e0ddSBarry Smith PetscFunctionBegin; 3641bef8e0ddSBarry Smith nz = aij->maxnz; 3642d0f46423SBarry Smith n = mat->rmap->n; 3643bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3644bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3645bef8e0ddSBarry Smith } 3646bef8e0ddSBarry Smith aij->nz = nz; 3647bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3648bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3649bef8e0ddSBarry Smith } 3650bef8e0ddSBarry Smith PetscFunctionReturn(0); 3651bef8e0ddSBarry Smith } 3652bef8e0ddSBarry Smith 3653a3bb6f32SFande Kong /* 3654e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3655a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3656a3bb6f32SFande Kong * */ 3657a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3658a3bb6f32SFande Kong { 3659a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3660a3bb6f32SFande Kong PetscTable gid1_lid1; 3661a3bb6f32SFande Kong PetscTablePosition tpos; 3662a3bb6f32SFande Kong PetscInt gid,lid,i,j,ncols,ec; 3663a3bb6f32SFande Kong PetscInt *garray; 3664a3bb6f32SFande Kong PetscErrorCode ierr; 3665a3bb6f32SFande Kong 3666a3bb6f32SFande Kong PetscFunctionBegin; 3667a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3668a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3669a3bb6f32SFande Kong /* use a table */ 3670a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3671a3bb6f32SFande Kong ec = 0; 3672a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3673a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3674a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3675a3bb6f32SFande Kong PetscInt data,gid1 = aij->j[aij->i[i] + j] + 1; 3676a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3677a3bb6f32SFande Kong if (!data) { 3678a3bb6f32SFande Kong /* one based table */ 3679a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3680a3bb6f32SFande Kong } 3681a3bb6f32SFande Kong } 3682a3bb6f32SFande Kong } 3683a3bb6f32SFande Kong /* form array of columns we need */ 3684a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3685a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3686a3bb6f32SFande Kong while (tpos) { 3687a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3688a3bb6f32SFande Kong gid--; 3689a3bb6f32SFande Kong lid--; 3690a3bb6f32SFande Kong garray[lid] = gid; 3691a3bb6f32SFande Kong } 3692a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3693a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3694a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3695a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3696a3bb6f32SFande Kong } 3697a3bb6f32SFande Kong /* compact out the extra columns in B */ 3698a3bb6f32SFande Kong for (i=0; i<mat->rmap->n; i++) { 3699a3bb6f32SFande Kong ncols = aij->i[i+1] - aij->i[i]; 3700a3bb6f32SFande Kong for (j=0; j<ncols; j++) { 3701a3bb6f32SFande Kong PetscInt gid1 = aij->j[aij->i[i] + j] + 1; 3702a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3703a3bb6f32SFande Kong lid--; 3704a3bb6f32SFande Kong aij->j[aij->i[i] + j] = lid; 3705a3bb6f32SFande Kong } 3706a3bb6f32SFande Kong } 3707ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3708ca5434daSLawrence Mitchell ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3709a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 3710a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3711a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3712a3bb6f32SFande Kong PetscFunctionReturn(0); 3713a3bb6f32SFande Kong } 3714a3bb6f32SFande Kong 3715bef8e0ddSBarry Smith /*@ 3716bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3717bef8e0ddSBarry Smith in the matrix. 3718bef8e0ddSBarry Smith 3719bef8e0ddSBarry Smith Input Parameters: 3720bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3721bef8e0ddSBarry Smith - indices - the column indices 3722bef8e0ddSBarry Smith 372315091d37SBarry Smith Level: advanced 372415091d37SBarry Smith 3725bef8e0ddSBarry Smith Notes: 3726bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3727bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3728bef8e0ddSBarry Smith of the MatSetValues() operation. 3729bef8e0ddSBarry Smith 3730bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3731d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3732bef8e0ddSBarry Smith 3733bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3734bef8e0ddSBarry Smith 3735b9617806SBarry Smith The indices should start with zero, not one. 3736b9617806SBarry Smith 3737bef8e0ddSBarry Smith @*/ 37387087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3739bef8e0ddSBarry Smith { 37404ac538c5SBarry Smith PetscErrorCode ierr; 3741bef8e0ddSBarry Smith 3742bef8e0ddSBarry Smith PetscFunctionBegin; 37430700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 37444482741eSBarry Smith PetscValidPointer(indices,2); 37454ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3746bef8e0ddSBarry Smith PetscFunctionReturn(0); 3747bef8e0ddSBarry Smith } 3748bef8e0ddSBarry Smith 3749be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3750be6bf707SBarry Smith 37517087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3752be6bf707SBarry Smith { 3753be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 37546849ba73SBarry Smith PetscErrorCode ierr; 3755d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3756be6bf707SBarry Smith 3757be6bf707SBarry Smith PetscFunctionBegin; 3758169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3759be6bf707SBarry Smith 3760be6bf707SBarry Smith /* allocate space for values if not already there */ 3761be6bf707SBarry Smith if (!aij->saved_values) { 3762854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 37633bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3764be6bf707SBarry Smith } 3765be6bf707SBarry Smith 3766be6bf707SBarry Smith /* copy values over */ 3767580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3768be6bf707SBarry Smith PetscFunctionReturn(0); 3769be6bf707SBarry Smith } 3770be6bf707SBarry Smith 3771be6bf707SBarry Smith /*@ 3772be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3773be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3774be6bf707SBarry Smith nonlinear portion. 3775be6bf707SBarry Smith 3776be6bf707SBarry Smith Collect on Mat 3777be6bf707SBarry Smith 3778be6bf707SBarry Smith Input Parameters: 37790e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3780be6bf707SBarry Smith 378115091d37SBarry Smith Level: advanced 378215091d37SBarry Smith 3783be6bf707SBarry Smith Common Usage, with SNESSolve(): 3784be6bf707SBarry Smith $ Create Jacobian matrix 3785be6bf707SBarry Smith $ Set linear terms into matrix 3786be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3787be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3788be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3789512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3790be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3791be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3792be6bf707SBarry Smith $ In your Jacobian routine 3793be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3794be6bf707SBarry Smith $ Set nonlinear terms in matrix 3795be6bf707SBarry Smith 3796be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3797be6bf707SBarry Smith $ // build linear portion of Jacobian 3798512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3799be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3800be6bf707SBarry Smith $ loop over nonlinear iterations 3801be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3802be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3803be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3804be6bf707SBarry Smith $ Solve linear system with Jacobian 3805be6bf707SBarry Smith $ endloop 3806be6bf707SBarry Smith 3807be6bf707SBarry Smith Notes: 3808be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3809512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3810be6bf707SBarry Smith calling this routine. 3811be6bf707SBarry Smith 38120c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 38130c468ba9SBarry Smith and does not allocated additional space. 38140c468ba9SBarry Smith 3815be6bf707SBarry Smith .seealso: MatRetrieveValues() 3816be6bf707SBarry Smith 3817be6bf707SBarry Smith @*/ 38187087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3819be6bf707SBarry Smith { 38204ac538c5SBarry Smith PetscErrorCode ierr; 3821be6bf707SBarry Smith 3822be6bf707SBarry Smith PetscFunctionBegin; 38230700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3824e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3825e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38264ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3827be6bf707SBarry Smith PetscFunctionReturn(0); 3828be6bf707SBarry Smith } 3829be6bf707SBarry Smith 38307087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3831be6bf707SBarry Smith { 3832be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38336849ba73SBarry Smith PetscErrorCode ierr; 3834d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3835be6bf707SBarry Smith 3836be6bf707SBarry Smith PetscFunctionBegin; 3837169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3838f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3839be6bf707SBarry Smith /* copy values over */ 3840580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3841be6bf707SBarry Smith PetscFunctionReturn(0); 3842be6bf707SBarry Smith } 3843be6bf707SBarry Smith 3844be6bf707SBarry Smith /*@ 3845be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3846be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3847be6bf707SBarry Smith nonlinear portion. 3848be6bf707SBarry Smith 3849be6bf707SBarry Smith Collect on Mat 3850be6bf707SBarry Smith 3851be6bf707SBarry Smith Input Parameters: 3852386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3853be6bf707SBarry Smith 385415091d37SBarry Smith Level: advanced 385515091d37SBarry Smith 3856be6bf707SBarry Smith .seealso: MatStoreValues() 3857be6bf707SBarry Smith 3858be6bf707SBarry Smith @*/ 38597087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3860be6bf707SBarry Smith { 38614ac538c5SBarry Smith PetscErrorCode ierr; 3862be6bf707SBarry Smith 3863be6bf707SBarry Smith PetscFunctionBegin; 38640700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3865e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3866e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38674ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3868be6bf707SBarry Smith PetscFunctionReturn(0); 3869be6bf707SBarry Smith } 3870be6bf707SBarry Smith 3871f83d6046SBarry Smith 3872be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 387317ab2063SBarry Smith /*@C 3874682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 38750d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 38766e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 387751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 38782bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 387917ab2063SBarry Smith 3880d083f849SBarry Smith Collective 3881db81eaa0SLois Curfman McInnes 388217ab2063SBarry Smith Input Parameters: 3883db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 388417ab2063SBarry Smith . m - number of rows 388517ab2063SBarry Smith . n - number of columns 388617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 388751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 38880298fd71SBarry Smith (possibly different for each row) or NULL 388917ab2063SBarry Smith 389017ab2063SBarry Smith Output Parameter: 3891416022c9SBarry Smith . A - the matrix 389217ab2063SBarry Smith 3893175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3894f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3895175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3896175b88e8SBarry Smith 3897b259b22eSLois Curfman McInnes Notes: 389849a6f317SBarry Smith If nnz is given then nz is ignored 389949a6f317SBarry Smith 390017ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 390117ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39020002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 390344cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 390417ab2063SBarry Smith 390517ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39060298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39073d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39086da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 390917ab2063SBarry Smith 3910682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 39114fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3912682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 39136c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 39146c7ebb05SLois Curfman McInnes 39156c7ebb05SLois Curfman McInnes Options Database Keys: 3916698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 39179db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 391817ab2063SBarry Smith 3919027ccd11SLois Curfman McInnes Level: intermediate 3920027ccd11SLois Curfman McInnes 392169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 392236db0b34SBarry Smith 392317ab2063SBarry Smith @*/ 39247087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 392517ab2063SBarry Smith { 3926dfbe8321SBarry Smith PetscErrorCode ierr; 39276945ee14SBarry Smith 39283a40ed3dSBarry Smith PetscFunctionBegin; 3929f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3930117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3931c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3932d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3933273d9f13SBarry Smith PetscFunctionReturn(0); 3934273d9f13SBarry Smith } 3935273d9f13SBarry Smith 3936273d9f13SBarry Smith /*@C 3937273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3938273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3939273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3940273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3941273d9f13SBarry Smith 3942d083f849SBarry Smith Collective 3943273d9f13SBarry Smith 3944273d9f13SBarry Smith Input Parameters: 39451c4f3114SJed Brown + B - The matrix 3946273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3947273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39480298fd71SBarry Smith (possibly different for each row) or NULL 3949273d9f13SBarry Smith 3950273d9f13SBarry Smith Notes: 395149a6f317SBarry Smith If nnz is given then nz is ignored 395249a6f317SBarry Smith 3953273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3954273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3955273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3956273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3957273d9f13SBarry Smith 3958273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39590298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3960273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3961273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3962273d9f13SBarry Smith 3963aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3964aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3965aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3966aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3967aa95bbe8SBarry Smith 3968a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3969a96a251dSBarry Smith entries or columns indices 3970a96a251dSBarry Smith 3971273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3972273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3973273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3974273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3975273d9f13SBarry Smith 3976273d9f13SBarry Smith Options Database Keys: 3977698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 397847b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3979273d9f13SBarry Smith 3980273d9f13SBarry Smith Level: intermediate 3981273d9f13SBarry Smith 398219b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 398319b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 3984273d9f13SBarry Smith 3985273d9f13SBarry Smith @*/ 39867087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3987273d9f13SBarry Smith { 39884ac538c5SBarry Smith PetscErrorCode ierr; 3989a23d5eceSKris Buschelman 3990a23d5eceSKris Buschelman PetscFunctionBegin; 39916ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 39926ba663aaSJed Brown PetscValidType(B,1); 39934ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3994a23d5eceSKris Buschelman PetscFunctionReturn(0); 3995a23d5eceSKris Buschelman } 3996a23d5eceSKris Buschelman 39977087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3998a23d5eceSKris Buschelman { 3999273d9f13SBarry Smith Mat_SeqAIJ *b; 40002576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40016849ba73SBarry Smith PetscErrorCode ierr; 400297f1f81fSBarry Smith PetscInt i; 4003273d9f13SBarry Smith 4004273d9f13SBarry Smith PetscFunctionBegin; 40052576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4006a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4007c461c341SBarry Smith skipallocation = PETSC_TRUE; 4008c461c341SBarry Smith nz = 0; 4009c461c341SBarry Smith } 401026283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 401126283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4012899cda47SBarry Smith 4013435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 401460e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4015cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4016d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 401760e0710aSBarry 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]); 401860e0710aSBarry 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); 4019b73539f3SBarry Smith } 4020b73539f3SBarry Smith } 4021b73539f3SBarry Smith 4022273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 40232205254eSKarl Rupp 4024273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4025273d9f13SBarry Smith 4026ab93d7beSBarry Smith if (!skipallocation) { 40272ee49352SLisandro Dalcin if (!b->imax) { 4028071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4029071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4030071fcb05SBarry Smith } 4031071fcb05SBarry Smith if (!b->ilen) { 4032071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4033071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4034071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4035071fcb05SBarry Smith } else { 4036071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 40372ee49352SLisandro Dalcin } 4038846b4da1SFande Kong if (!b->ipre) { 4039846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4040846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4041846b4da1SFande Kong } 4042273d9f13SBarry Smith if (!nnz) { 4043435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4044c62bd62aSJed Brown else if (nz < 0) nz = 1; 40455d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4046d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4047d0f46423SBarry Smith nz = nz*B->rmap->n; 4048273d9f13SBarry Smith } else { 4049c73702f5SBarry Smith PetscInt64 nz64 = 0; 4050c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4051c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4052273d9f13SBarry Smith } 4053ab93d7beSBarry Smith 4054273d9f13SBarry Smith /* allocate the matrix space */ 405553dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 40562ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4057396832f4SHong Zhang if (B->structure_only) { 40585848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 40595848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4060396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4061396832f4SHong Zhang } else { 4062dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 40633bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4064396832f4SHong Zhang } 4065bfeeae90SHong Zhang b->i[0] = 0; 4066d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 40675da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 40685da197adSKris Buschelman } 4069396832f4SHong Zhang if (B->structure_only) { 4070396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4071396832f4SHong Zhang b->free_a = PETSC_FALSE; 4072396832f4SHong Zhang } else { 4073273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4074e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4075396832f4SHong Zhang } 4076e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4077c461c341SBarry Smith } else { 4078e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4079e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4080c461c341SBarry Smith } 4081273d9f13SBarry Smith 4082846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4083846b4da1SFande Kong /* reserve user-requested sparsity */ 4084580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4085846b4da1SFande Kong } 4086846b4da1SFande Kong 4087846b4da1SFande Kong 4088273d9f13SBarry Smith b->nz = 0; 4089273d9f13SBarry Smith b->maxnz = nz; 4090273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 40912205254eSKarl Rupp if (realalloc) { 40922205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 40932205254eSKarl Rupp } 4094cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4095cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4096273d9f13SBarry Smith PetscFunctionReturn(0); 4097273d9f13SBarry Smith } 4098273d9f13SBarry Smith 4099846b4da1SFande Kong 4100846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4101846b4da1SFande Kong { 4102846b4da1SFande Kong Mat_SeqAIJ *a; 4103a5bbaf83SFande Kong PetscInt i; 4104846b4da1SFande Kong PetscErrorCode ierr; 4105846b4da1SFande Kong 4106846b4da1SFande Kong PetscFunctionBegin; 4107846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 410814d0e64fSAlex Lindsay 410914d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 411014d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 411114d0e64fSAlex Lindsay 4112846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 41132c814fdeSFande Kong /* if no saved info, we error out */ 4114fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 41152c814fdeSFande Kong 4116fb4dc15dSAlex 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"); 41172c814fdeSFande Kong 4118580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4119580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4120846b4da1SFande Kong a->i[0] = 0; 4121846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4122846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4123846b4da1SFande Kong } 4124846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4125846b4da1SFande Kong a->nz = 0; 4126846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4127846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4128846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4129846b4da1SFande Kong A->assembled = PETSC_FALSE; 4130846b4da1SFande Kong PetscFunctionReturn(0); 4131846b4da1SFande Kong } 4132846b4da1SFande Kong 413358d36128SBarry Smith /*@ 4134a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4135a1661176SMatthew Knepley 4136a1661176SMatthew Knepley Input Parameters: 4137a1661176SMatthew Knepley + B - the matrix 4138a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4139a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4140a1661176SMatthew Knepley - v - optional values in the matrix 4141a1661176SMatthew Knepley 4142a1661176SMatthew Knepley Level: developer 4143a1661176SMatthew Knepley 41446a9b8d82SBarry Smith Notes: 414558d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 414658d36128SBarry Smith 41476a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 41486a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 41496a9b8d82SBarry Smith 41506a9b8d82SBarry Smith Developer Notes: 41516a9b8d82SBarry 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 41526a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 41536a9b8d82SBarry Smith 41546a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 41556a9b8d82SBarry Smith 41566a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4157a1661176SMatthew Knepley @*/ 4158a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4159a1661176SMatthew Knepley { 4160a1661176SMatthew Knepley PetscErrorCode ierr; 4161a1661176SMatthew Knepley 4162a1661176SMatthew Knepley PetscFunctionBegin; 41630700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 41646ba663aaSJed Brown PetscValidType(B,1); 41654ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4166a1661176SMatthew Knepley PetscFunctionReturn(0); 4167a1661176SMatthew Knepley } 4168a1661176SMatthew Knepley 41697087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4170a1661176SMatthew Knepley { 4171a1661176SMatthew Knepley PetscInt i; 4172a1661176SMatthew Knepley PetscInt m,n; 4173a1661176SMatthew Knepley PetscInt nz; 41746a9b8d82SBarry Smith PetscInt *nnz; 4175a1661176SMatthew Knepley PetscErrorCode ierr; 4176a1661176SMatthew Knepley 4177a1661176SMatthew Knepley PetscFunctionBegin; 417865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4179779a8d59SSatish Balay 4180779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4181779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4182779a8d59SSatish Balay 4183779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4184854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4185a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4186b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 418765e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4188a1661176SMatthew Knepley nnz[i] = nz; 4189a1661176SMatthew Knepley } 4190a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4191a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4192a1661176SMatthew Knepley 4193a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4194071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4195a1661176SMatthew Knepley } 4196a1661176SMatthew Knepley 4197a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4198a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4199a1661176SMatthew Knepley 42007827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4201a1661176SMatthew Knepley PetscFunctionReturn(0); 4202a1661176SMatthew Knepley } 4203a1661176SMatthew Knepley 4204c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4205af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4206170fe5c8SBarry Smith 4207170fe5c8SBarry Smith /* 4208170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4209170fe5c8SBarry Smith 4210170fe5c8SBarry Smith n p p 42112da392ccSBarry Smith [ ] [ ] [ ] 42122da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 42132da392ccSBarry Smith [ ] [ ] [ ] 4214170fe5c8SBarry Smith 4215170fe5c8SBarry Smith */ 4216170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4217170fe5c8SBarry Smith { 4218170fe5c8SBarry Smith PetscErrorCode ierr; 4219170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4220170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4221170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 422286214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4223170fe5c8SBarry Smith const PetscInt *ii,*idx; 4224170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4225170fe5c8SBarry Smith PetscScalar *c,*c_q; 422686214ceeSStefano Zampini PetscInt clda = sub_c->lda; 422786214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4228170fe5c8SBarry Smith 4229170fe5c8SBarry Smith PetscFunctionBegin; 4230d0f46423SBarry Smith m = A->rmap->n; 4231d0f46423SBarry Smith n = A->cmap->n; 4232d0f46423SBarry Smith p = B->cmap->n; 4233170fe5c8SBarry Smith a = sub_a->v; 4234170fe5c8SBarry Smith b = sub_b->a; 4235170fe5c8SBarry Smith c = sub_c->v; 423686214ceeSStefano Zampini if (clda == m) { 4237580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 423886214ceeSStefano Zampini } else { 423986214ceeSStefano Zampini for (j=0;j<p;j++) 424086214ceeSStefano Zampini for (i=0;i<m;i++) 424186214ceeSStefano Zampini c[j*clda + i] = 0.0; 424286214ceeSStefano Zampini } 4243170fe5c8SBarry Smith ii = sub_b->i; 4244170fe5c8SBarry Smith idx = sub_b->j; 4245170fe5c8SBarry Smith for (i=0; i<n; i++) { 4246170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4247170fe5c8SBarry Smith while (q-->0) { 424886214ceeSStefano Zampini c_q = c + clda*(*idx); 424986214ceeSStefano Zampini a_q = a + alda*i; 4250854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4251170fe5c8SBarry Smith idx++; 4252170fe5c8SBarry Smith b++; 4253170fe5c8SBarry Smith } 4254170fe5c8SBarry Smith } 4255170fe5c8SBarry Smith PetscFunctionReturn(0); 4256170fe5c8SBarry Smith } 4257170fe5c8SBarry Smith 42584222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4259170fe5c8SBarry Smith { 4260170fe5c8SBarry Smith PetscErrorCode ierr; 4261d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 426286214ceeSStefano Zampini PetscBool cisdense; 4263170fe5c8SBarry Smith 4264170fe5c8SBarry Smith PetscFunctionBegin; 426560e0710aSBarry 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); 42664222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 42674222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 426886214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 426986214ceeSStefano Zampini if (!cisdense) { 427086214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 427186214ceeSStefano Zampini } 427286214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4273d73949e8SHong Zhang 42744222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4275170fe5c8SBarry Smith PetscFunctionReturn(0); 4276170fe5c8SBarry Smith } 4277170fe5c8SBarry Smith 4278170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 42790bad9183SKris Buschelman /*MC 4280fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 42810bad9183SKris Buschelman based on compressed sparse row format. 42820bad9183SKris Buschelman 42830bad9183SKris Buschelman Options Database Keys: 42840bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 42850bad9183SKris Buschelman 42860bad9183SKris Buschelman Level: beginner 42870bad9183SKris Buschelman 42880cd7f59aSBarry Smith Notes: 42890cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 42900cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 42910cd7f59aSBarry Smith in the matrix 42920cd7f59aSBarry Smith 42930cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 42940cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 42950cd7f59aSBarry Smith 42960cd7f59aSBarry Smith Developer Notes: 42970cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 42980cd7f59aSBarry Smith 4299f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 43000bad9183SKris Buschelman M*/ 43010bad9183SKris Buschelman 4302ccd284c7SBarry Smith /*MC 4303ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4304ccd284c7SBarry Smith 4305ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4306ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 43070cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4308ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4309ccd284c7SBarry Smith the above preallocation routines for simplicity. 4310ccd284c7SBarry Smith 4311ccd284c7SBarry Smith Options Database Keys: 4312ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4313ccd284c7SBarry Smith 431495452b02SPatrick Sanan Developer Notes: 4315ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4316ccd284c7SBarry Smith enough exist. 4317ccd284c7SBarry Smith 4318ccd284c7SBarry Smith Level: beginner 4319ccd284c7SBarry Smith 4320ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4321ccd284c7SBarry Smith M*/ 4322ccd284c7SBarry Smith 4323ccd284c7SBarry Smith /*MC 4324ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4325ccd284c7SBarry Smith 4326ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4327ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4328ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4329ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4330ccd284c7SBarry Smith the above preallocation routines for simplicity. 4331ccd284c7SBarry Smith 4332ccd284c7SBarry Smith Options Database Keys: 4333ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4334ccd284c7SBarry Smith 4335ccd284c7SBarry Smith Level: beginner 4336ccd284c7SBarry Smith 4337ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4338ccd284c7SBarry Smith M*/ 4339ccd284c7SBarry Smith 43407906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 43417906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 43427906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 43437906f579SHong Zhang #endif 4344d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4345d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4346d24d4204SJose E. Roman #endif 43477906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 43487906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 43497906f579SHong Zhang #endif 43507906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 43517906f579SHong Zhang 4352d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4353c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 43544222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 43557906f579SHong Zhang 43568c778c55SBarry Smith /*@C 43578f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 43588c778c55SBarry Smith 43598c778c55SBarry Smith Not Collective 43608c778c55SBarry Smith 43618c778c55SBarry Smith Input Parameter: 4362579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 43638c778c55SBarry Smith 43648c778c55SBarry Smith Output Parameter: 43658c778c55SBarry Smith . array - pointer to the data 43668c778c55SBarry Smith 43678c778c55SBarry Smith Level: intermediate 43688c778c55SBarry Smith 4369774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 43708c778c55SBarry Smith @*/ 43718c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 43728c778c55SBarry Smith { 43738c778c55SBarry Smith PetscErrorCode ierr; 43748c778c55SBarry Smith 43758c778c55SBarry Smith PetscFunctionBegin; 43768c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 43778c778c55SBarry Smith PetscFunctionReturn(0); 43788c778c55SBarry Smith } 43798c778c55SBarry Smith 438021e72a00SBarry Smith /*@C 43818f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 43828f1ea47aSStefano Zampini 43838f1ea47aSStefano Zampini Not Collective 43848f1ea47aSStefano Zampini 43858f1ea47aSStefano Zampini Input Parameter: 43868f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 43878f1ea47aSStefano Zampini 43888f1ea47aSStefano Zampini Output Parameter: 43898f1ea47aSStefano Zampini . array - pointer to the data 43908f1ea47aSStefano Zampini 43918f1ea47aSStefano Zampini Level: intermediate 43928f1ea47aSStefano Zampini 43938f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 43948f1ea47aSStefano Zampini @*/ 43958f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 43968f1ea47aSStefano Zampini { 43978c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4398c70f7ee4SJunchao Zhang PetscOffloadMask oval; 43998f1ea47aSStefano Zampini #endif 44008f1ea47aSStefano Zampini PetscErrorCode ierr; 44018f1ea47aSStefano Zampini 44028f1ea47aSStefano Zampini PetscFunctionBegin; 44038c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4404c70f7ee4SJunchao Zhang oval = A->offloadmask; 44058f1ea47aSStefano Zampini #endif 44068f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44078c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4408c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 44098f1ea47aSStefano Zampini #endif 44108f1ea47aSStefano Zampini PetscFunctionReturn(0); 44118f1ea47aSStefano Zampini } 44128f1ea47aSStefano Zampini 44138f1ea47aSStefano Zampini /*@C 44148f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 44158f1ea47aSStefano Zampini 44168f1ea47aSStefano Zampini Not Collective 44178f1ea47aSStefano Zampini 44188f1ea47aSStefano Zampini Input Parameter: 44198f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44208f1ea47aSStefano Zampini 44218f1ea47aSStefano Zampini Output Parameter: 44228f1ea47aSStefano Zampini . array - pointer to the data 44238f1ea47aSStefano Zampini 44248f1ea47aSStefano Zampini Level: intermediate 44258f1ea47aSStefano Zampini 44268f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 44278f1ea47aSStefano Zampini @*/ 44288f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 44298f1ea47aSStefano Zampini { 44308c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4431c70f7ee4SJunchao Zhang PetscOffloadMask oval; 44328f1ea47aSStefano Zampini #endif 44338f1ea47aSStefano Zampini PetscErrorCode ierr; 44348f1ea47aSStefano Zampini 44358f1ea47aSStefano Zampini PetscFunctionBegin; 44368c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4437c70f7ee4SJunchao Zhang oval = A->offloadmask; 44388f1ea47aSStefano Zampini #endif 44398f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44408c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4441c70f7ee4SJunchao Zhang A->offloadmask = oval; 44428f1ea47aSStefano Zampini #endif 44438f1ea47aSStefano Zampini PetscFunctionReturn(0); 44448f1ea47aSStefano Zampini } 44458f1ea47aSStefano Zampini 44468f1ea47aSStefano Zampini /*@C 444721e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 444821e72a00SBarry Smith 444921e72a00SBarry Smith Not Collective 445021e72a00SBarry Smith 445121e72a00SBarry Smith Input Parameter: 4452579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 445321e72a00SBarry Smith 445421e72a00SBarry Smith Output Parameter: 445521e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 445621e72a00SBarry Smith 445721e72a00SBarry Smith Level: intermediate 445821e72a00SBarry Smith 445921e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 446021e72a00SBarry Smith @*/ 446121e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 446221e72a00SBarry Smith { 446321e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 446421e72a00SBarry Smith 446521e72a00SBarry Smith PetscFunctionBegin; 446621e72a00SBarry Smith *nz = aij->rmax; 446721e72a00SBarry Smith PetscFunctionReturn(0); 446821e72a00SBarry Smith } 446921e72a00SBarry Smith 44708c778c55SBarry Smith /*@C 4471579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 44728c778c55SBarry Smith 44738c778c55SBarry Smith Not Collective 44748c778c55SBarry Smith 44758c778c55SBarry Smith Input Parameters: 4476a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4477a2b725a8SWilliam Gropp - array - pointer to the data 44788c778c55SBarry Smith 44798c778c55SBarry Smith Level: intermediate 44808c778c55SBarry Smith 4481774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 44828c778c55SBarry Smith @*/ 44838c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 44848c778c55SBarry Smith { 44858c778c55SBarry Smith PetscErrorCode ierr; 44868c778c55SBarry Smith 44878c778c55SBarry Smith PetscFunctionBegin; 44888c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 44898c778c55SBarry Smith PetscFunctionReturn(0); 44908c778c55SBarry Smith } 44918c778c55SBarry Smith 449234b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 44930ce8acdeSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 449402fe1965SBarry Smith #endif 4495*3d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 4496*3d0639e7SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat); 4497*3d0639e7SStefano Zampini #endif 449802fe1965SBarry Smith 44998cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4500273d9f13SBarry Smith { 4501273d9f13SBarry Smith Mat_SeqAIJ *b; 4502dfbe8321SBarry Smith PetscErrorCode ierr; 450338baddfdSBarry Smith PetscMPIInt size; 4504273d9f13SBarry Smith 4505273d9f13SBarry Smith PetscFunctionBegin; 4506ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 4507e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4508273d9f13SBarry Smith 4509b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 45102205254eSKarl Rupp 4511b0a32e0cSBarry Smith B->data = (void*)b; 45122205254eSKarl Rupp 4513549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4514071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 45152205254eSKarl Rupp 4516f4259b30SLisandro Dalcin b->row = NULL; 4517f4259b30SLisandro Dalcin b->col = NULL; 4518f4259b30SLisandro Dalcin b->icol = NULL; 4519b810aeb4SBarry Smith b->reallocs = 0; 452036db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4521f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4522416022c9SBarry Smith b->nonew = 0; 4523f4259b30SLisandro Dalcin b->diag = NULL; 4524f4259b30SLisandro Dalcin b->solve_work = NULL; 4525f4259b30SLisandro Dalcin B->spptr = NULL; 4526f4259b30SLisandro Dalcin b->saved_values = NULL; 4527f4259b30SLisandro Dalcin b->idiag = NULL; 4528f4259b30SLisandro Dalcin b->mdiag = NULL; 4529f4259b30SLisandro Dalcin b->ssor_work = NULL; 453071f1c65dSBarry Smith b->omega = 1.0; 453171f1c65dSBarry Smith b->fshift = 0.0; 453271f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4533bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4534a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 453517ab2063SBarry Smith 453635d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4537bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4538bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 45398c778c55SBarry Smith 4540b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4541bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4542bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4543b3866ffcSBarry Smith #endif 454417f1a0eaSHong Zhang 4545bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4546bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4547bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4548bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4549bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4550bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 45514dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 45529779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 45534a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4554191b95cbSRichard Tran Mills #endif 455534b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 455602fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 45574222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 455802fe1965SBarry Smith #endif 4559*3d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 4560*3d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 4561*3d0639e7SStefano Zampini #endif 4562bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4563af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4564af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4565af8000cdSHong Zhang #endif 4566d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4567d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4568d24d4204SJose E. Roman #endif 456963c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 457063c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 45714222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 457263c07aadSStefano Zampini #endif 4573b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4574d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4575c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4576bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4577bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4578bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4579846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4580bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4581bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 45824222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 45834222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 45844222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 45854108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 458617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 45874099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 45883a40ed3dSBarry Smith PetscFunctionReturn(0); 458917ab2063SBarry Smith } 459017ab2063SBarry Smith 4591b24902e0SBarry Smith /* 4592b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4593b24902e0SBarry Smith */ 4594ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 459517ab2063SBarry Smith { 45962a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 45976849ba73SBarry Smith PetscErrorCode ierr; 4598071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 459917ab2063SBarry Smith 46003a40ed3dSBarry Smith PetscFunctionBegin; 4601ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4602273d9f13SBarry Smith 4603d5f3da31SBarry Smith C->factortype = A->factortype; 4604f4259b30SLisandro Dalcin c->row = NULL; 4605f4259b30SLisandro Dalcin c->col = NULL; 4606f4259b30SLisandro Dalcin c->icol = NULL; 46076ad4291fSHong Zhang c->reallocs = 0; 460817ab2063SBarry Smith 46096ad4291fSHong Zhang C->assembled = PETSC_TRUE; 461017ab2063SBarry Smith 4611aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4612aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4613eec197d1SBarry Smith 4614071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4615071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4616071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4617071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 46183bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 461917ab2063SBarry Smith 462017ab2063SBarry Smith /* allocate the matrix space */ 4621f77e22a1SHong Zhang if (mallocmatspace) { 4622dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 46233bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 46242205254eSKarl Rupp 4625f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 46262205254eSKarl Rupp 4627580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 462817ab2063SBarry Smith if (m > 0) { 4629580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4630be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4631580bdb30SBarry Smith ierr = PetscArraycpy(c->a,a->a,a->i[m]);CHKERRQ(ierr); 4632be6bf707SBarry Smith } else { 4633580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 463417ab2063SBarry Smith } 463508480c60SBarry Smith } 4636f77e22a1SHong Zhang } 463717ab2063SBarry Smith 46386ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4639416022c9SBarry Smith c->roworiented = a->roworiented; 4640416022c9SBarry Smith c->nonew = a->nonew; 4641416022c9SBarry Smith if (a->diag) { 4642854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4643071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 46443bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4645071fcb05SBarry Smith } else c->diag = NULL; 46462205254eSKarl Rupp 4647f4259b30SLisandro Dalcin c->solve_work = NULL; 4648f4259b30SLisandro Dalcin c->saved_values = NULL; 4649f4259b30SLisandro Dalcin c->idiag = NULL; 4650f4259b30SLisandro Dalcin c->ssor_work = NULL; 4651a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4652e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4653e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 46546ad4291fSHong Zhang 4655893ad86cSHong Zhang c->rmax = a->rmax; 4656416022c9SBarry Smith c->nz = a->nz; 46578ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4658273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4659754ec7b1SSatish Balay 46606ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 46616ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4662cd6b891eSBarry Smith if (a->compressedrow.use) { 46636ad4291fSHong Zhang i = a->compressedrow.nrows; 4664dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4665580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4666580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 466727ea64f8SHong Zhang } else { 466827ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 46690298fd71SBarry Smith c->compressedrow.i = NULL; 46700298fd71SBarry Smith c->compressedrow.rindex = NULL; 46716ad4291fSHong Zhang } 4672ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4673e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 46744846f1f5SKris Buschelman 46752205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4676140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 46773a40ed3dSBarry Smith PetscFunctionReturn(0); 467817ab2063SBarry Smith } 467917ab2063SBarry Smith 4680b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4681b24902e0SBarry Smith { 4682b24902e0SBarry Smith PetscErrorCode ierr; 4683b24902e0SBarry Smith 4684b24902e0SBarry Smith PetscFunctionBegin; 4685ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 46864b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4687cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 468833d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4689cfd3f464SBarry Smith } 4690a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4691f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4692b24902e0SBarry Smith PetscFunctionReturn(0); 4693b24902e0SBarry Smith } 4694b24902e0SBarry Smith 4695112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4696fbdbba38SShri Abhyankar { 469752f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 469852f91c60SVaclav Hapla PetscErrorCode ierr; 469952f91c60SVaclav Hapla 470052f91c60SVaclav Hapla PetscFunctionBegin; 470152f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 470252f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4703c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4704c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 470552f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 470652f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 470752f91c60SVaclav Hapla if (isbinary) { 470852f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 470952f91c60SVaclav Hapla } else if (ishdf5) { 471052f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 471152f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 471252f91c60SVaclav Hapla #else 471352f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 471452f91c60SVaclav Hapla #endif 471552f91c60SVaclav Hapla } else { 471652f91c60SVaclav 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); 471752f91c60SVaclav Hapla } 471852f91c60SVaclav Hapla PetscFunctionReturn(0); 471952f91c60SVaclav Hapla } 472052f91c60SVaclav Hapla 47213ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 472252f91c60SVaclav Hapla { 47233ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4724fbdbba38SShri Abhyankar PetscErrorCode ierr; 47253ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4726fbdbba38SShri Abhyankar 4727fbdbba38SShri Abhyankar PetscFunctionBegin; 47283ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4729bbead8a2SBarry Smith 47303ea6fe3dSLisandro Dalcin /* read in matrix header */ 47313ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 47323ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4733fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 47343ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 47353ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4736bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4737fbdbba38SShri Abhyankar 47383ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 47393ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 47403ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 47413ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 47423ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 47433ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 47443ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 47453ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 47463ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 47473ea6fe3dSLisandro Dalcin 47483ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 47493ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 47503ea6fe3dSLisandro 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); 47513ea6fe3dSLisandro Dalcin 4752fbdbba38SShri Abhyankar /* read in row lengths */ 47533ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 47543ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 47553ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 47563ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 47573ea6fe3dSLisandro 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); 47583ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 47593ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 47603ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 476160e0710aSBarry 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); 47623ea6fe3dSLisandro Dalcin /* store row lengths */ 47633ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 47643ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4765fbdbba38SShri Abhyankar 47663ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 47673ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 47683ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 47693ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 47703ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 47713ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4772fbdbba38SShri Abhyankar 47733ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47743ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4775fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4776fbdbba38SShri Abhyankar } 4777fbdbba38SShri Abhyankar 4778ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 47797264ac53SSatish Balay { 47807264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4781dfbe8321SBarry Smith PetscErrorCode ierr; 4782eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4783eeffb40dSHong Zhang PetscInt k; 4784eeffb40dSHong Zhang #endif 47857264ac53SSatish Balay 47863a40ed3dSBarry Smith PetscFunctionBegin; 4787bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4788d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4789ca44d042SBarry Smith *flg = PETSC_FALSE; 4790ca44d042SBarry Smith PetscFunctionReturn(0); 4791bcd2baecSBarry Smith } 47927264ac53SSatish Balay 47937264ac53SSatish Balay /* if the a->i are the same */ 4794580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4795abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 47967264ac53SSatish Balay 47977264ac53SSatish Balay /* if a->j are the same */ 4798580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4799abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4800bcd2baecSBarry Smith 4801bcd2baecSBarry Smith /* if a->a are the same */ 4802eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4803eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4804eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4805eeffb40dSHong Zhang *flg = PETSC_FALSE; 48063a40ed3dSBarry Smith PetscFunctionReturn(0); 4807eeffb40dSHong Zhang } 4808eeffb40dSHong Zhang } 4809eeffb40dSHong Zhang #else 4810580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4811eeffb40dSHong Zhang #endif 4812eeffb40dSHong Zhang PetscFunctionReturn(0); 48137264ac53SSatish Balay } 481436db0b34SBarry Smith 481505869f15SSatish Balay /*@ 481636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 481736db0b34SBarry Smith provided by the user. 481836db0b34SBarry Smith 4819d083f849SBarry Smith Collective 482036db0b34SBarry Smith 482136db0b34SBarry Smith Input Parameters: 482236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 482336db0b34SBarry Smith . m - number of rows 482436db0b34SBarry Smith . n - number of columns 4825483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 482636db0b34SBarry Smith . j - column indices 482736db0b34SBarry Smith - a - matrix values 482836db0b34SBarry Smith 482936db0b34SBarry Smith Output Parameter: 483036db0b34SBarry Smith . mat - the matrix 483136db0b34SBarry Smith 483236db0b34SBarry Smith Level: intermediate 483336db0b34SBarry Smith 483436db0b34SBarry Smith Notes: 48350551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4836292fb18eSBarry Smith once the matrix is destroyed and not before 483736db0b34SBarry Smith 483836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 483936db0b34SBarry Smith 4840bfeeae90SHong Zhang The i and j indices are 0 based 484136db0b34SBarry Smith 4842a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4843a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 48448eef79e4SBarry Smith as shown 4845a4552177SSatish Balay 48468eef79e4SBarry Smith $ 1 0 0 48478eef79e4SBarry Smith $ 2 0 3 48488eef79e4SBarry Smith $ 4 5 6 48498eef79e4SBarry Smith $ 48508eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 48518eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 48528eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4853a4552177SSatish Balay 48549985e31cSBarry Smith 485569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 485636db0b34SBarry Smith 485736db0b34SBarry Smith @*/ 4858c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 485936db0b34SBarry Smith { 4860dfbe8321SBarry Smith PetscErrorCode ierr; 4861cbcfb4deSHong Zhang PetscInt ii; 486236db0b34SBarry Smith Mat_SeqAIJ *aij; 4863cbcfb4deSHong Zhang PetscInt jj; 486436db0b34SBarry Smith 486536db0b34SBarry Smith PetscFunctionBegin; 486641096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4867f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4868f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4869a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4870ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4871f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 4872ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4873071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4874071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4875ab93d7beSBarry Smith 487636db0b34SBarry Smith aij->i = i; 487736db0b34SBarry Smith aij->j = j; 487836db0b34SBarry Smith aij->a = a; 487936db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 488036db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4881e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4882e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 488336db0b34SBarry Smith 488436db0b34SBarry Smith for (ii=0; ii<m; ii++) { 488536db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 488676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 488760e0710aSBarry 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]); 48889985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4889a061629eSStefano 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); 4890a061629eSStefano 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); 48919985e31cSBarry Smith } 489236db0b34SBarry Smith } 489376bd3646SJed Brown } 489476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 489536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 489660e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 489760e0710aSBarry 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]); 489836db0b34SBarry Smith } 489976bd3646SJed Brown } 490036db0b34SBarry Smith 4901b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4902b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 490336db0b34SBarry Smith PetscFunctionReturn(0); 490436db0b34SBarry Smith } 490580ef6e79SMatthew G Knepley /*@C 4906d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 49078a0b0e6bSVictor Minden provided by the user. 49088a0b0e6bSVictor Minden 4909d083f849SBarry Smith Collective 49108a0b0e6bSVictor Minden 49118a0b0e6bSVictor Minden Input Parameters: 49128a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 49138a0b0e6bSVictor Minden . m - number of rows 49148a0b0e6bSVictor Minden . n - number of columns 49158a0b0e6bSVictor Minden . i - row indices 49168a0b0e6bSVictor Minden . j - column indices 49171230e6d1SVictor Minden . a - matrix values 49181230e6d1SVictor Minden . nz - number of nonzeros 49191230e6d1SVictor Minden - idx - 0 or 1 based 49208a0b0e6bSVictor Minden 49218a0b0e6bSVictor Minden Output Parameter: 49228a0b0e6bSVictor Minden . mat - the matrix 49238a0b0e6bSVictor Minden 49248a0b0e6bSVictor Minden Level: intermediate 49258a0b0e6bSVictor Minden 49268a0b0e6bSVictor Minden Notes: 49278a0b0e6bSVictor Minden The i and j indices are 0 based 49288a0b0e6bSVictor Minden 49298a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 49308a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 49318a0b0e6bSVictor Minden as shown: 49328a0b0e6bSVictor Minden 49338a0b0e6bSVictor Minden 1 0 0 49348a0b0e6bSVictor Minden 2 0 3 49358a0b0e6bSVictor Minden 4 5 6 49368a0b0e6bSVictor Minden 49378a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 49388a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 49398a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 49408a0b0e6bSVictor Minden 49418a0b0e6bSVictor Minden 494269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 49438a0b0e6bSVictor Minden 49448a0b0e6bSVictor Minden @*/ 4945c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 49468a0b0e6bSVictor Minden { 49478a0b0e6bSVictor Minden PetscErrorCode ierr; 4948d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 49498a0b0e6bSVictor Minden 49508a0b0e6bSVictor Minden 49518a0b0e6bSVictor Minden PetscFunctionBegin; 49521795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 49531230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4954c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 49551230e6d1SVictor Minden } 49568a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 49578a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 49588a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 49591230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 49601230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 49611230e6d1SVictor Minden if (idx) { 49621230e6d1SVictor Minden row = i[ii] - 1; 49631230e6d1SVictor Minden col = j[ii] - 1; 49641230e6d1SVictor Minden } else { 49651230e6d1SVictor Minden row = i[ii]; 49661230e6d1SVictor Minden col = j[ii]; 49678a0b0e6bSVictor Minden } 49681230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 49698a0b0e6bSVictor Minden } 49708a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49718a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4972d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 49738a0b0e6bSVictor Minden PetscFunctionReturn(0); 49748a0b0e6bSVictor Minden } 497536db0b34SBarry Smith 4976acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4977acf2f550SJed Brown { 4978acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4979acf2f550SJed Brown PetscErrorCode ierr; 4980acf2f550SJed Brown 4981acf2f550SJed Brown PetscFunctionBegin; 4982acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4983acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 49842205254eSKarl Rupp 4985acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4986acf2f550SJed Brown PetscFunctionReturn(0); 4987acf2f550SJed Brown } 4988acf2f550SJed Brown 49899c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 49909c8f2541SHong Zhang { 49919c8f2541SHong Zhang PetscErrorCode ierr; 49928761c3d6SHong Zhang PetscMPIInt size; 49939c8f2541SHong Zhang 49949c8f2541SHong Zhang PetscFunctionBegin; 49958761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 49967bbdc51dSHong Zhang if (size == 1) { 49977bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 49987bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 49997bbdc51dSHong Zhang } else { 50008761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 50017bbdc51dSHong Zhang } 50028761c3d6SHong Zhang } else { 50039c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 50048761c3d6SHong Zhang } 50059c8f2541SHong Zhang PetscFunctionReturn(0); 50069c8f2541SHong Zhang } 50079c8f2541SHong Zhang 500881824310SBarry Smith /* 500953dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 501053dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 501153dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 501253dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 501353dd7562SDmitry Karpeev */ 501453dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 501553dd7562SDmitry Karpeev { 501653dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 501753dd7562SDmitry Karpeev PetscErrorCode ierr; 501853dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 501953dd7562SDmitry Karpeev PetscBool seqaij; 502053dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 502153dd7562SDmitry Karpeev PetscScalar v; 502253dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 502353dd7562SDmitry Karpeev 502453dd7562SDmitry Karpeev PetscFunctionBegin; 502553dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 502653dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 50274099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 502853dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 502953dd7562SDmitry Karpeev if (rowemb) { 503053dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 503153dd7562SDmitry 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); 503253dd7562SDmitry Karpeev } else { 50336c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 503453dd7562SDmitry Karpeev } 503553dd7562SDmitry Karpeev if (colemb) { 503653dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 503753dd7562SDmitry 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); 503853dd7562SDmitry Karpeev } else { 503953dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 504053dd7562SDmitry Karpeev } 504153dd7562SDmitry Karpeev 504253dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 504353dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 504453dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 504553dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 504653dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 504753dd7562SDmitry Karpeev } 504853dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 504953dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 505053dd7562SDmitry Karpeev } 505153dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 505253dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 505353dd7562SDmitry Karpeev } 505453dd7562SDmitry Karpeev count = 0; 505553dd7562SDmitry Karpeev rowindices = NULL; 505653dd7562SDmitry Karpeev colindices = NULL; 505753dd7562SDmitry Karpeev if (rowemb) { 505853dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 505953dd7562SDmitry Karpeev } 506053dd7562SDmitry Karpeev if (colemb) { 506153dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 506253dd7562SDmitry Karpeev } 506353dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 506453dd7562SDmitry Karpeev PetscInt row; 506553dd7562SDmitry Karpeev row = i; 506653dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 506753dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 506853dd7562SDmitry Karpeev PetscInt col; 506953dd7562SDmitry Karpeev col = Baij->j[count]; 507053dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 507153dd7562SDmitry Karpeev v = Baij->a[count]; 507253dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 507353dd7562SDmitry Karpeev ++count; 507453dd7562SDmitry Karpeev } 507553dd7562SDmitry Karpeev } 507653dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 507753dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 507853dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 507953dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 508053dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 508153dd7562SDmitry Karpeev PetscFunctionReturn(0); 508253dd7562SDmitry Karpeev } 508353dd7562SDmitry Karpeev 50844099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 50854099cc6bSBarry Smith 50864099cc6bSBarry Smith /*@C 50874099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 50884099cc6bSBarry Smith 50894099cc6bSBarry Smith Collective on Mat 50904099cc6bSBarry Smith 50914099cc6bSBarry Smith Input Parameters: 50924099cc6bSBarry Smith + mat - the matrix object 50934099cc6bSBarry Smith - matype - matrix type 50944099cc6bSBarry Smith 50954099cc6bSBarry Smith Options Database Key: 50964099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 50974099cc6bSBarry Smith 50984099cc6bSBarry Smith 50994099cc6bSBarry Smith Level: intermediate 51004099cc6bSBarry Smith 51014099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 51024099cc6bSBarry Smith @*/ 51034099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 51044099cc6bSBarry Smith { 5105fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 51064099cc6bSBarry Smith PetscBool sametype; 51074099cc6bSBarry Smith 51084099cc6bSBarry Smith PetscFunctionBegin; 51094099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 51104099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 51114099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 51124099cc6bSBarry Smith 51134099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 51144099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 51154099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 51164099cc6bSBarry Smith PetscFunctionReturn(0); 51174099cc6bSBarry Smith } 51184099cc6bSBarry Smith 51194099cc6bSBarry Smith 51204099cc6bSBarry Smith /*@C 51214099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 51224099cc6bSBarry Smith 51234099cc6bSBarry Smith Not Collective 51244099cc6bSBarry Smith 51254099cc6bSBarry Smith Input Parameters: 51264099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 51274099cc6bSBarry Smith - function - routine to convert to subtype 51284099cc6bSBarry Smith 51294099cc6bSBarry Smith Notes: 51304099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 51314099cc6bSBarry Smith 51324099cc6bSBarry Smith 51334099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 51344099cc6bSBarry Smith $ -mat_seqaij_type my_mat 51354099cc6bSBarry Smith 51364099cc6bSBarry Smith Level: advanced 51374099cc6bSBarry Smith 51384099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 51394099cc6bSBarry Smith 51404099cc6bSBarry Smith 51414099cc6bSBarry Smith Level: advanced 51424099cc6bSBarry Smith @*/ 5143388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 51444099cc6bSBarry Smith { 51454099cc6bSBarry Smith PetscErrorCode ierr; 51464099cc6bSBarry Smith 51474099cc6bSBarry Smith PetscFunctionBegin; 51489cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 51494099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 51504099cc6bSBarry Smith PetscFunctionReturn(0); 51514099cc6bSBarry Smith } 51524099cc6bSBarry Smith 51534099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 51544099cc6bSBarry Smith 51554099cc6bSBarry Smith /*@C 51564099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 51574099cc6bSBarry Smith 51584099cc6bSBarry Smith Not Collective 51594099cc6bSBarry Smith 51604099cc6bSBarry Smith Level: advanced 51614099cc6bSBarry Smith 51624099cc6bSBarry Smith Developers Note: CUSP and CUSPARSE do not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 51634099cc6bSBarry Smith 51644099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 51654099cc6bSBarry Smith @*/ 51664099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 51674099cc6bSBarry Smith { 51684099cc6bSBarry Smith PetscErrorCode ierr; 51694099cc6bSBarry Smith 51704099cc6bSBarry Smith PetscFunctionBegin; 51714099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 51724099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 51734099cc6bSBarry Smith 51744099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 51754099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 51764dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 51779779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 51786b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5179485f9817SRichard Tran Mills #endif 51804099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 51814099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 51824099cc6bSBarry Smith #endif 51834099cc6bSBarry Smith PetscFunctionReturn(0); 51844099cc6bSBarry Smith } 518553dd7562SDmitry Karpeev 518653dd7562SDmitry Karpeev /* 518781824310SBarry Smith Special version for direct calls from Fortran 518881824310SBarry Smith */ 5189af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 519081824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 519181824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 519281824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 519381824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 519481824310SBarry Smith #endif 519581824310SBarry Smith 519681824310SBarry Smith /* Change these macros so can be used in void function */ 519781824310SBarry Smith #undef CHKERRQ 5198ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 519981824310SBarry Smith #undef SETERRQ2 5200e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 52014994cf47SJed Brown #undef SETERRQ3 52024994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 520381824310SBarry Smith 520419caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 520581824310SBarry Smith { 520681824310SBarry Smith Mat A = *AA; 520781824310SBarry Smith PetscInt m = *mm, n = *nn; 520881824310SBarry Smith InsertMode is = *isis; 520981824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 521081824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 521181824310SBarry Smith PetscInt *imax,*ai,*ailen; 521281824310SBarry Smith PetscErrorCode ierr; 521381824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 521454f21887SBarry Smith MatScalar *ap,value,*aa; 5215ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5216ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 521781824310SBarry Smith 521881824310SBarry Smith PetscFunctionBegin; 52194994cf47SJed Brown MatCheckPreallocated(A,1); 522081824310SBarry Smith imax = a->imax; 522181824310SBarry Smith ai = a->i; 522281824310SBarry Smith ailen = a->ilen; 522381824310SBarry Smith aj = a->j; 522481824310SBarry Smith aa = a->a; 522581824310SBarry Smith 522681824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 522781824310SBarry Smith row = im[k]; 522881824310SBarry Smith if (row < 0) continue; 5229cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 523081824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 523181824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 523281824310SBarry Smith low = 0; 523381824310SBarry Smith high = nrow; 523481824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 523581824310SBarry Smith if (in[l] < 0) continue; 5236cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 523781824310SBarry Smith col = in[l]; 52382205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 52392205254eSKarl Rupp else value = v[k + l*m]; 52402205254eSKarl Rupp 524181824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 524281824310SBarry Smith 52432205254eSKarl Rupp if (col <= lastcol) low = 0; 52442205254eSKarl Rupp else high = nrow; 524581824310SBarry Smith lastcol = col; 524681824310SBarry Smith while (high-low > 5) { 524781824310SBarry Smith t = (low+high)/2; 524881824310SBarry Smith if (rp[t] > col) high = t; 524981824310SBarry Smith else low = t; 525081824310SBarry Smith } 525181824310SBarry Smith for (i=low; i<high; i++) { 525281824310SBarry Smith if (rp[i] > col) break; 525381824310SBarry Smith if (rp[i] == col) { 525481824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 525581824310SBarry Smith else ap[i] = value; 525681824310SBarry Smith goto noinsert; 525781824310SBarry Smith } 525881824310SBarry Smith } 525981824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 526081824310SBarry Smith if (nonew == 1) goto noinsert; 5261ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5262fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 526381824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 526481824310SBarry Smith /* shift up all the later entries in this row */ 526581824310SBarry Smith for (ii=N; ii>=i; ii--) { 526681824310SBarry Smith rp[ii+1] = rp[ii]; 526781824310SBarry Smith ap[ii+1] = ap[ii]; 526881824310SBarry Smith } 526981824310SBarry Smith rp[i] = col; 527081824310SBarry Smith ap[i] = value; 5271e56f5c9eSBarry Smith A->nonzerostate++; 527281824310SBarry Smith noinsert:; 527381824310SBarry Smith low = i + 1; 527481824310SBarry Smith } 527581824310SBarry Smith ailen[row] = nrow; 527681824310SBarry Smith } 527781824310SBarry Smith PetscFunctionReturnVoid(); 527881824310SBarry Smith } 5279