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; 698c898d852SStefano Zampini const PetscScalar *av; 6993ea6fe3dSLisandro Dalcin PetscInt header[4],M,N,m,nz,i; 7003ea6fe3dSLisandro Dalcin PetscInt *rowlens; 7016849ba73SBarry Smith PetscErrorCode ierr; 70217ab2063SBarry Smith 7033a40ed3dSBarry Smith PetscFunctionBegin; 7043ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 7052205254eSKarl Rupp 7063ea6fe3dSLisandro Dalcin M = mat->rmap->N; 7073ea6fe3dSLisandro Dalcin N = mat->cmap->N; 7083ea6fe3dSLisandro Dalcin m = mat->rmap->n; 7093ea6fe3dSLisandro Dalcin nz = A->nz; 710416022c9SBarry Smith 7113ea6fe3dSLisandro Dalcin /* write matrix header */ 7123ea6fe3dSLisandro Dalcin header[0] = MAT_FILE_CLASSID; 7133ea6fe3dSLisandro Dalcin header[1] = M; header[2] = N; header[3] = nz; 7143ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,header,4,PETSC_INT);CHKERRQ(ierr); 715416022c9SBarry Smith 7163ea6fe3dSLisandro Dalcin /* fill in and store row lengths */ 7173ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(m,&rowlens);CHKERRQ(ierr); 7183ea6fe3dSLisandro Dalcin for (i=0; i<m; i++) rowlens[i] = A->i[i+1] - A->i[i]; 7193ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,rowlens,m,PETSC_INT);CHKERRQ(ierr); 7203ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 7213ea6fe3dSLisandro Dalcin /* store column indices */ 7223ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryWrite(viewer,A->j,nz,PETSC_INT);CHKERRQ(ierr); 723416022c9SBarry Smith /* store nonzero values */ 724c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(mat,&av);CHKERRQ(ierr); 725c898d852SStefano Zampini ierr = PetscViewerBinaryWrite(viewer,av,nz,PETSC_SCALAR);CHKERRQ(ierr); 726c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(mat,&av);CHKERRQ(ierr); 727b37d52dbSMark F. Adams 7283ea6fe3dSLisandro Dalcin /* write block size option to the viewer's .info file */ 7293ea6fe3dSLisandro Dalcin ierr = MatView_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 7303a40ed3dSBarry Smith PetscFunctionReturn(0); 73117ab2063SBarry Smith } 732416022c9SBarry Smith 7337dc0baabSHong Zhang static PetscErrorCode MatView_SeqAIJ_ASCII_structonly(Mat A,PetscViewer viewer) 7347dc0baabSHong Zhang { 7357dc0baabSHong Zhang PetscErrorCode ierr; 7367dc0baabSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7377dc0baabSHong Zhang PetscInt i,k,m=A->rmap->N; 7387dc0baabSHong Zhang 7397dc0baabSHong Zhang PetscFunctionBegin; 7407dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7417dc0baabSHong Zhang for (i=0; i<m; i++) { 7427dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 7437dc0baabSHong Zhang for (k=a->i[i]; k<a->i[i+1]; k++) { 7447dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D) ",a->j[k]);CHKERRQ(ierr); 7457dc0baabSHong Zhang } 7467dc0baabSHong Zhang ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 7477dc0baabSHong Zhang } 7487dc0baabSHong Zhang ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7497dc0baabSHong Zhang PetscFunctionReturn(0); 7507dc0baabSHong Zhang } 7517dc0baabSHong Zhang 75209573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 753cd155464SBarry Smith 754dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 755416022c9SBarry Smith { 756416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 757c898d852SStefano Zampini const PetscScalar *av; 758dfbe8321SBarry Smith PetscErrorCode ierr; 75960e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 760e060cb09SBarry Smith const char *name; 761f3ef73ceSBarry Smith PetscViewerFormat format; 76217ab2063SBarry Smith 7633a40ed3dSBarry Smith PetscFunctionBegin; 7647dc0baabSHong Zhang if (A->structure_only) { 7657dc0baabSHong Zhang ierr = MatView_SeqAIJ_ASCII_structonly(A,viewer);CHKERRQ(ierr); 7667dc0baabSHong Zhang PetscFunctionReturn(0); 7677dc0baabSHong Zhang } 76843e49210SHong Zhang 769b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 770c898d852SStefano Zampini /* trigger copy to CPU if needed */ 771c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&av);CHKERRQ(ierr); 772c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&av);CHKERRQ(ierr); 77371c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 77497f1f81fSBarry Smith PetscInt nofinalvalue = 0; 77560e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 776c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 777d00d2cf4SBarry Smith nofinalvalue = 1; 778d00d2cf4SBarry Smith } 779d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 780d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 78177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 782fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 783fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 784fbfe6fa7SJed Brown #else 78577431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 786fbfe6fa7SJed Brown #endif 787b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 78817ab2063SBarry Smith 78917ab2063SBarry Smith for (i=0; i<m; i++) { 79060e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 791aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 792a9bf72d8SJed 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); 79317ab2063SBarry Smith #else 79460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 79517ab2063SBarry Smith #endif 79617ab2063SBarry Smith } 79717ab2063SBarry Smith } 798d00d2cf4SBarry Smith if (nofinalvalue) { 799c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 800c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 801c337ccceSJed Brown #else 802d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 803c337ccceSJed Brown #endif 804d00d2cf4SBarry Smith } 805317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 806fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 807d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 8082950ac48SStefano Zampini } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 809cd155464SBarry Smith PetscFunctionReturn(0); 810fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 811d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 81244cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 81377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 81460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 815aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 81636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 81760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 81836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 81960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 82036db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 82160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 8226831982aSBarry Smith } 82344cd7ae7SLois Curfman McInnes #else 82460e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 82544cd7ae7SLois Curfman McInnes #endif 82644cd7ae7SLois Curfman McInnes } 827b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 82844cd7ae7SLois Curfman McInnes } 829d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 830fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 83197f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 832d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 833854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 834496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 835496be53dSLois Curfman McInnes sptr[i] = nzd+1; 83660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 837496be53dSLois Curfman McInnes if (a->j[j] >= i) { 838aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 83936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 840496be53dSLois Curfman McInnes #else 841496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 842496be53dSLois Curfman McInnes #endif 843496be53dSLois Curfman McInnes } 844496be53dSLois Curfman McInnes } 845496be53dSLois Curfman McInnes } 8462e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 84777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 8482e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 8492205254eSKarl Rupp if (i+4<m) { 8502205254eSKarl 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); 8512205254eSKarl Rupp } else if (i+3<m) { 8522205254eSKarl 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); 8532205254eSKarl Rupp } else if (i+2<m) { 8542205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 8552205254eSKarl Rupp } else if (i+1<m) { 8562205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 8572205254eSKarl Rupp } else if (i<m) { 8582205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 8592205254eSKarl Rupp } else { 8602205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 8612205254eSKarl Rupp } 862496be53dSLois Curfman McInnes } 863b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 864606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 865496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 86660e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 86777431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 868496be53dSLois Curfman McInnes } 869b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 870496be53dSLois Curfman McInnes } 871b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 872496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 87360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 874496be53dSLois Curfman McInnes if (a->j[j] >= i) { 875aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 87636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 87760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8786831982aSBarry Smith } 879496be53dSLois Curfman McInnes #else 88060e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 881496be53dSLois Curfman McInnes #endif 882496be53dSLois Curfman McInnes } 883496be53dSLois Curfman McInnes } 884b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 885496be53dSLois Curfman McInnes } 886d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 887fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 88897f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 88987828ca2SBarry Smith PetscScalar value; 89068f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 89168f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 89268f1ed48SBarry Smith 89368f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 89468f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 89568f1ed48SBarry Smith realonly = PETSC_FALSE; 89668f1ed48SBarry Smith break; 89768f1ed48SBarry Smith } 89868f1ed48SBarry Smith } 89968f1ed48SBarry Smith #endif 90002594712SBarry Smith 901d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 90202594712SBarry Smith for (i=0; i<m; i++) { 90302594712SBarry Smith jcnt = 0; 904d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 905e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 90602594712SBarry Smith value = a->a[cnt++]; 907e24b481bSBarry Smith jcnt++; 90802594712SBarry Smith } else { 90902594712SBarry Smith value = 0.0; 91002594712SBarry Smith } 911aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 91268f1ed48SBarry Smith if (realonly) { 91360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 91468f1ed48SBarry Smith } else { 91560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 91668f1ed48SBarry Smith } 91702594712SBarry Smith #else 91860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 91902594712SBarry Smith #endif 92002594712SBarry Smith } 921b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 92202594712SBarry Smith } 923d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9243c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 925150b93efSMatthew G. Knepley PetscInt fshift=1; 926d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 9273c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 92819303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 9293c215bfdSMatthew Knepley #else 93019303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 9313c215bfdSMatthew Knepley #endif 932d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 9333c215bfdSMatthew Knepley for (i=0; i<m; i++) { 93460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 9353c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 936a9a0e077SKarl 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); 9373c215bfdSMatthew Knepley #else 938150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 9393c215bfdSMatthew Knepley #endif 9403c215bfdSMatthew Knepley } 9413c215bfdSMatthew Knepley } 942d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 9433a40ed3dSBarry Smith } else { 944d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 945d5f3da31SBarry Smith if (A->factortype) { 94616cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 94716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 94816cd7e1dSShri Abhyankar /* L part */ 94960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 95016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 95116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 95260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 95316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9546712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 95516cd7e1dSShri Abhyankar } else { 95660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 95716cd7e1dSShri Abhyankar } 95816cd7e1dSShri Abhyankar #else 95960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 96016cd7e1dSShri Abhyankar #endif 96116cd7e1dSShri Abhyankar } 96216cd7e1dSShri Abhyankar /* diagonal */ 96316cd7e1dSShri Abhyankar j = a->diag[i]; 96416cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 96516cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 96660e0710aSBarry 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); 96716cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 9686712e2f1SBarry 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); 96916cd7e1dSShri Abhyankar } else { 97060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 97116cd7e1dSShri Abhyankar } 97216cd7e1dSShri Abhyankar #else 97360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 97416cd7e1dSShri Abhyankar #endif 97516cd7e1dSShri Abhyankar 97616cd7e1dSShri Abhyankar /* U part */ 97760e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 97816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 97916cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 98060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 98116cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 98222ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 98316cd7e1dSShri Abhyankar } else { 98460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 98516cd7e1dSShri Abhyankar } 98616cd7e1dSShri Abhyankar #else 98760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 98816cd7e1dSShri Abhyankar #endif 98916cd7e1dSShri Abhyankar } 99016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 99116cd7e1dSShri Abhyankar } 99216cd7e1dSShri Abhyankar } else { 99317ab2063SBarry Smith for (i=0; i<m; i++) { 99477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 99560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 996aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 99736db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 99860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 99936db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 100060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 10013a40ed3dSBarry Smith } else { 100260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 100317ab2063SBarry Smith } 100417ab2063SBarry Smith #else 100560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 100617ab2063SBarry Smith #endif 100717ab2063SBarry Smith } 1008b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 100917ab2063SBarry Smith } 101016cd7e1dSShri Abhyankar } 1011d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 101217ab2063SBarry Smith } 1013b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 10143a40ed3dSBarry Smith PetscFunctionReturn(0); 1015416022c9SBarry Smith } 1016416022c9SBarry Smith 10179804daf3SBarry Smith #include <petscdraw.h> 1018dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 1019416022c9SBarry Smith { 1020480ef9eaSBarry Smith Mat A = (Mat) Aa; 1021416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1022dfbe8321SBarry Smith PetscErrorCode ierr; 1023383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 1024383922c3SLisandro Dalcin int color; 1025b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1026b0a32e0cSBarry Smith PetscViewer viewer; 1027f3ef73ceSBarry Smith PetscViewerFormat format; 1028cddf8d76SBarry Smith 10293a40ed3dSBarry Smith PetscFunctionBegin; 1030480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1031b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1032b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1033383922c3SLisandro Dalcin 1034416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 10350513a670SBarry Smith 1036fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1037383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10380513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 1039b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1040416022c9SBarry Smith for (i=0; i<m; i++) { 1041cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1042bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1043bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 104436db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 1045b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1046cddf8d76SBarry Smith } 1047cddf8d76SBarry Smith } 1048b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 1049cddf8d76SBarry Smith for (i=0; i<m; i++) { 1050cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1051bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1052bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 1053cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 1054b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1055cddf8d76SBarry Smith } 1056cddf8d76SBarry Smith } 1057b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1058cddf8d76SBarry Smith for (i=0; i<m; i++) { 1059cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 1060bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1061bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 106236db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 1063b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1064416022c9SBarry Smith } 1065416022c9SBarry Smith } 1066383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10670513a670SBarry Smith } else { 10680513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 10690513a670SBarry Smith /* first determine max of all nonzero values */ 1070b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1071383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 1072b0a32e0cSBarry Smith PetscDraw popup; 10730513a670SBarry Smith 10740513a670SBarry Smith for (i=0; i<nz; i++) { 10750513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 10760513a670SBarry Smith } 1077383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1078b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 107945f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1080383922c3SLisandro Dalcin 1081383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 10820513a670SBarry Smith for (i=0; i<m; i++) { 1083383922c3SLisandro Dalcin y_l = m - i - 1.0; 1084383922c3SLisandro Dalcin y_r = y_l + 1.0; 1085bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1086383922c3SLisandro Dalcin x_l = a->j[j]; 1087383922c3SLisandro Dalcin x_r = x_l + 1.0; 1088b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 1089b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 10900513a670SBarry Smith count++; 10910513a670SBarry Smith } 10920513a670SBarry Smith } 1093383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 10940513a670SBarry Smith } 1095480ef9eaSBarry Smith PetscFunctionReturn(0); 1096480ef9eaSBarry Smith } 1097cddf8d76SBarry Smith 10989804daf3SBarry Smith #include <petscdraw.h> 1099dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 1100480ef9eaSBarry Smith { 1101dfbe8321SBarry Smith PetscErrorCode ierr; 1102b0a32e0cSBarry Smith PetscDraw draw; 110336db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1104ace3abfcSBarry Smith PetscBool isnull; 1105480ef9eaSBarry Smith 1106480ef9eaSBarry Smith PetscFunctionBegin; 1107b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1108b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1109480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 1110480ef9eaSBarry Smith 1111d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1112480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1113b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1114832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1115b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 11160298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1117832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 11183a40ed3dSBarry Smith PetscFunctionReturn(0); 1119416022c9SBarry Smith } 1120416022c9SBarry Smith 1121dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 1122416022c9SBarry Smith { 1123dfbe8321SBarry Smith PetscErrorCode ierr; 1124ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1125416022c9SBarry Smith 11263a40ed3dSBarry Smith PetscFunctionBegin; 1127251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1128251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1129251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 1130c45a1595SBarry Smith if (iascii) { 11313a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 11320f5bd95cSBarry Smith } else if (isbinary) { 11333a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 11340f5bd95cSBarry Smith } else if (isdraw) { 11353a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 113611aeaf0aSBarry Smith } 11374108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 11383a40ed3dSBarry Smith PetscFunctionReturn(0); 113917ab2063SBarry Smith } 114019bcc07fSBarry Smith 1141dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 114217ab2063SBarry Smith { 1143416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11446849ba73SBarry Smith PetscErrorCode ierr; 1145580bdb30SBarry Smith PetscInt fshift = 0,i,*ai = a->i,*aj = a->j,*imax = a->imax; 1146d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 114754f21887SBarry Smith MatScalar *aa = a->a,*ap; 11483447b6efSHong Zhang PetscReal ratio = 0.6; 114917ab2063SBarry Smith 11503a40ed3dSBarry Smith PetscFunctionBegin; 11513a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 1152071fcb05SBarry Smith ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 1153b215bc84SStefano Zampini if (A->was_assembled && A->ass_nonzerostate == A->nonzerostate) { 1154b215bc84SStefano Zampini /* we need to respect users asking to use or not the inodes routine in between matrix assemblies */ 1155b215bc84SStefano Zampini ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1156b215bc84SStefano Zampini PetscFunctionReturn(0); 1157b215bc84SStefano Zampini } 115817ab2063SBarry Smith 115943ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 116017ab2063SBarry Smith for (i=1; i<m; i++) { 1161416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 116217ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 116394a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 116417ab2063SBarry Smith if (fshift) { 1165bfeeae90SHong Zhang ip = aj + ai[i]; 1166bfeeae90SHong Zhang ap = aa + ai[i]; 116717ab2063SBarry Smith N = ailen[i]; 1168580bdb30SBarry Smith ierr = PetscArraymove(ip-fshift,ip,N);CHKERRQ(ierr); 1169580bdb30SBarry Smith if (!A->structure_only) { 1170580bdb30SBarry Smith ierr = PetscArraymove(ap-fshift,ap,N);CHKERRQ(ierr); 117117ab2063SBarry Smith } 117217ab2063SBarry Smith } 117317ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 117417ab2063SBarry Smith } 117517ab2063SBarry Smith if (m) { 117617ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 117717ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 117817ab2063SBarry Smith } 11797b083b7cSBarry Smith 118017ab2063SBarry Smith /* reset ilen and imax for each row */ 11817b083b7cSBarry Smith a->nonzerorowcnt = 0; 1182396832f4SHong Zhang if (A->structure_only) { 1183071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1184071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1185396832f4SHong Zhang } else { /* !A->structure_only */ 118617ab2063SBarry Smith for (i=0; i<m; i++) { 118717ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 11887b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 118917ab2063SBarry Smith } 1190396832f4SHong Zhang } 1191bfeeae90SHong Zhang a->nz = ai[m]; 119265e19b50SBarry 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); 119317ab2063SBarry Smith 119409f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1195d0f46423SBarry 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); 1196ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 1197ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 11982205254eSKarl Rupp 11998e58a170SBarry Smith A->info.mallocs += a->reallocs; 1200dd5f02e7SSatish Balay a->reallocs = 0; 12016712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 120236db0b34SBarry Smith a->rmax = rmax; 12034e220ebcSLois Curfman McInnes 1204396832f4SHong Zhang if (!A->structure_only) { 120511e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 1206396832f4SHong Zhang } 12074108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 12083a40ed3dSBarry Smith PetscFunctionReturn(0); 120917ab2063SBarry Smith } 121017ab2063SBarry Smith 121199cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 121299cafbc1SBarry Smith { 121399cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 121499cafbc1SBarry Smith PetscInt i,nz = a->nz; 121554f21887SBarry Smith MatScalar *aa = a->a; 1216acf2f550SJed Brown PetscErrorCode ierr; 121799cafbc1SBarry Smith 121899cafbc1SBarry Smith PetscFunctionBegin; 121999cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1220acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12218c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1222c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1223e2cf4d64SStefano Zampini #endif 122499cafbc1SBarry Smith PetscFunctionReturn(0); 122599cafbc1SBarry Smith } 122699cafbc1SBarry Smith 122799cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 122899cafbc1SBarry Smith { 122999cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 123099cafbc1SBarry Smith PetscInt i,nz = a->nz; 123154f21887SBarry Smith MatScalar *aa = a->a; 1232acf2f550SJed Brown PetscErrorCode ierr; 123399cafbc1SBarry Smith 123499cafbc1SBarry Smith PetscFunctionBegin; 123599cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1236acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12378c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1238c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1239e2cf4d64SStefano Zampini #endif 124099cafbc1SBarry Smith PetscFunctionReturn(0); 124199cafbc1SBarry Smith } 124299cafbc1SBarry Smith 1243dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 124417ab2063SBarry Smith { 1245416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1246dfbe8321SBarry Smith PetscErrorCode ierr; 12473a40ed3dSBarry Smith 12483a40ed3dSBarry Smith PetscFunctionBegin; 1249580bdb30SBarry Smith ierr = PetscArrayzero(a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 1250acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 12518c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 1252c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 1253e2cf4d64SStefano Zampini #endif 12543a40ed3dSBarry Smith PetscFunctionReturn(0); 125517ab2063SBarry Smith } 1256416022c9SBarry Smith 1257dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 125817ab2063SBarry Smith { 1259416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1260dfbe8321SBarry Smith PetscErrorCode ierr; 1261d5d45c9bSBarry Smith 12623a40ed3dSBarry Smith PetscFunctionBegin; 1263aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1264d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 126517ab2063SBarry Smith #endif 1266e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 12676bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 12686bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 126905b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1270d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 1271071fcb05SBarry Smith ierr = PetscFree(a->imax);CHKERRQ(ierr); 1272071fcb05SBarry Smith ierr = PetscFree(a->ilen);CHKERRQ(ierr); 1273846b4da1SFande Kong ierr = PetscFree(a->ipre);CHKERRQ(ierr); 127471f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 127505b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 12766bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 127705b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 1278cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 1279a30b2313SHong Zhang 12804108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1281bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1282901853e0SKris Buschelman 12836718818eSStefano Zampini /* MatMatMultNumeric_SeqAIJ_SeqAIJ_Sorted may allocate this. 12846718818eSStefano Zampini That function is so heavily used (sometimes in an hidden way through multnumeric function pointers) 12856718818eSStefano Zampini that is hard to properly add this data to the MatProduct data. We free it here to avoid 12866718818eSStefano Zampini users reusing the matrix object with different data to incur in obscure segmentation faults 12876718818eSStefano Zampini due to different matrix sizes */ 12886718818eSStefano Zampini ierr = PetscObjectCompose((PetscObject)A,"__PETSc__ab_dense",NULL);CHKERRQ(ierr); 12896718818eSStefano Zampini 1290f4259b30SLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject)A,NULL);CHKERRQ(ierr); 1291bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1292bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1293bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1294bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1295bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1296bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 12974222ddf1SHong Zhang #if defined(PETSC_HAVE_CUDA) 12984222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 1299e6e9a74fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",NULL);CHKERRQ(ierr); 1300fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",NULL);CHKERRQ(ierr); 13014222ddf1SHong Zhang #endif 13023d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 13033d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijkokkos_C",NULL);CHKERRQ(ierr); 13043d0639e7SStefano Zampini #endif 13054222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijcrl_C",NULL);CHKERRQ(ierr); 1306af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1307af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1308af8000cdSHong Zhang #endif 1309d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 1310d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_scalapack_C",NULL);CHKERRQ(ierr); 1311d24d4204SJose E. Roman #endif 131263c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 131363c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 13144222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 131563c07aadSStefano Zampini #endif 1316b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1317c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsell_C",NULL);CHKERRQ(ierr); 1318c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_is_C",NULL);CHKERRQ(ierr); 1319bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1320bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1321846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)A,"MatResetPreallocation_C",NULL);CHKERRQ(ierr); 1322bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1323bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 13244222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_is_seqaij_C",NULL);CHKERRQ(ierr); 13254222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13264222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatProductSetFromOptions_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 13273a40ed3dSBarry Smith PetscFunctionReturn(0); 132817ab2063SBarry Smith } 132917ab2063SBarry Smith 1330ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 133117ab2063SBarry Smith { 1332416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13334846f1f5SKris Buschelman PetscErrorCode ierr; 13343a40ed3dSBarry Smith 13353a40ed3dSBarry Smith PetscFunctionBegin; 1336a65d3064SKris Buschelman switch (op) { 1337a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 13384e0d8c25SBarry Smith a->roworiented = flg; 1339a65d3064SKris Buschelman break; 1340a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1341a9817697SBarry Smith a->keepnonzeropattern = flg; 1342a65d3064SKris Buschelman break; 1343512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1344512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1345a65d3064SKris Buschelman break; 1346a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 13474e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1348a65d3064SKris Buschelman break; 1349a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 13504e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1351a65d3064SKris Buschelman break; 135228b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 135328b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 135428b2fa4aSMatthew Knepley break; 1355a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 13564e0d8c25SBarry Smith a->ignorezeroentries = flg; 13570df259c2SBarry Smith break; 13583d472b54SHong Zhang case MAT_SPD: 1359b1646e73SJed Brown case MAT_SYMMETRIC: 1360b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1361b1646e73SJed Brown case MAT_HERMITIAN: 1362b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1363957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 13645021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 13655021d80fSJed Brown break; 13668c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 1367a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1368a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1369290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1370a65d3064SKris Buschelman break; 1371b87ac2d8SJed Brown case MAT_USE_INODES: 1372b215bc84SStefano Zampini ierr = MatSetOption_SeqAIJ_Inode(A,MAT_USE_INODES,flg);CHKERRQ(ierr); 1373b87ac2d8SJed Brown break; 1374c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1375c10200c1SHong Zhang A->submat_singleis = flg; 1376c10200c1SHong Zhang break; 1377071fcb05SBarry Smith case MAT_SORTED_FULL: 1378071fcb05SBarry Smith if (flg) A->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 1379071fcb05SBarry Smith else A->ops->setvalues = MatSetValues_SeqAIJ; 1380071fcb05SBarry Smith break; 1381a65d3064SKris Buschelman default: 1382e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1383a65d3064SKris Buschelman } 13843a40ed3dSBarry Smith PetscFunctionReturn(0); 138517ab2063SBarry Smith } 138617ab2063SBarry Smith 1387dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 138817ab2063SBarry Smith { 1389416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 13906849ba73SBarry Smith PetscErrorCode ierr; 1391fdc842d1SBarry Smith PetscInt i,j,n,*ai=a->i,*aj=a->j; 1392c898d852SStefano Zampini PetscScalar *x; 1393c898d852SStefano Zampini const PetscScalar *aa; 139417ab2063SBarry Smith 13953a40ed3dSBarry Smith PetscFunctionBegin; 1396d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1397e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 1398c898d852SStefano Zampini ierr = MatSeqAIJGetArrayRead(A,&aa);CHKERRQ(ierr); 1399d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1400d3e70bfaSHong Zhang PetscInt *diag=a->diag; 1401fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 14022c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 1403fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1404c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 140535e7444dSHong Zhang PetscFunctionReturn(0); 140635e7444dSHong Zhang } 140735e7444dSHong Zhang 1408fdc842d1SBarry Smith ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 140935e7444dSHong Zhang for (i=0; i<n; i++) { 1410fdc842d1SBarry Smith x[i] = 0.0; 141135e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 141235e7444dSHong Zhang if (aj[j] == i) { 141335e7444dSHong Zhang x[i] = aa[j]; 141417ab2063SBarry Smith break; 141517ab2063SBarry Smith } 141617ab2063SBarry Smith } 141717ab2063SBarry Smith } 1418fdc842d1SBarry Smith ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 1419c898d852SStefano Zampini ierr = MatSeqAIJRestoreArrayRead(A,&aa);CHKERRQ(ierr); 14203a40ed3dSBarry Smith PetscFunctionReturn(0); 142117ab2063SBarry Smith } 142217ab2063SBarry Smith 1423c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1424dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 142517ab2063SBarry Smith { 1426416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1427d9ca1df4SBarry Smith PetscScalar *y; 1428d9ca1df4SBarry Smith const PetscScalar *x; 1429dfbe8321SBarry Smith PetscErrorCode ierr; 1430d0f46423SBarry Smith PetscInt m = A->rmap->n; 14315c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1432d9ca1df4SBarry Smith const MatScalar *v; 1433a77337e4SBarry Smith PetscScalar alpha; 1434d9ca1df4SBarry Smith PetscInt n,i,j; 1435d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 14363447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1437ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 14385c897100SBarry Smith #endif 143917ab2063SBarry Smith 14403a40ed3dSBarry Smith PetscFunctionBegin; 14412e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1442d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14431ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14445c897100SBarry Smith 14455c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1446bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 14475c897100SBarry Smith #else 14483447b6efSHong Zhang if (usecprow) { 14493447b6efSHong Zhang m = cprow.nrows; 14503447b6efSHong Zhang ii = cprow.i; 14517b2bb3b9SHong Zhang ridx = cprow.rindex; 14523447b6efSHong Zhang } else { 14533447b6efSHong Zhang ii = a->i; 14543447b6efSHong Zhang } 145517ab2063SBarry Smith for (i=0; i<m; i++) { 14563447b6efSHong Zhang idx = a->j + ii[i]; 14573447b6efSHong Zhang v = a->a + ii[i]; 14583447b6efSHong Zhang n = ii[i+1] - ii[i]; 14593447b6efSHong Zhang if (usecprow) { 14607b2bb3b9SHong Zhang alpha = x[ridx[i]]; 14613447b6efSHong Zhang } else { 146217ab2063SBarry Smith alpha = x[i]; 14633447b6efSHong Zhang } 146404fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 146517ab2063SBarry Smith } 14665c897100SBarry Smith #endif 1467dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1468d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14691ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14703a40ed3dSBarry Smith PetscFunctionReturn(0); 147117ab2063SBarry Smith } 147217ab2063SBarry Smith 1473dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 14745c897100SBarry Smith { 1475dfbe8321SBarry Smith PetscErrorCode ierr; 14765c897100SBarry Smith 14775c897100SBarry Smith PetscFunctionBegin; 1478170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 14795c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 14805c897100SBarry Smith PetscFunctionReturn(0); 14815c897100SBarry Smith } 14825c897100SBarry Smith 1483c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 148478b84d54SShri Abhyankar 1485dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 148617ab2063SBarry Smith { 1487416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1488d9fead3dSBarry Smith PetscScalar *y; 148954f21887SBarry Smith const PetscScalar *x; 149054f21887SBarry Smith const MatScalar *aa; 1491dfbe8321SBarry Smith PetscErrorCode ierr; 1492003131ecSBarry Smith PetscInt m=A->rmap->n; 14930298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 14947b083b7cSBarry Smith PetscInt n,i; 1495362ced78SSatish Balay PetscScalar sum; 1496ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 149717ab2063SBarry Smith 1498b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 149997952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1500fee21e36SBarry Smith #endif 1501fee21e36SBarry Smith 15023a40ed3dSBarry Smith PetscFunctionBegin; 1503b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1504b215bc84SStefano Zampini ierr = MatMult_SeqAIJ_Inode(A,xx,yy);CHKERRQ(ierr); 1505b215bc84SStefano Zampini PetscFunctionReturn(0); 1506b215bc84SStefano Zampini } 15073649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 15081ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1509416022c9SBarry Smith ii = a->i; 15104eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 1511580bdb30SBarry Smith ierr = PetscArrayzero(y,m);CHKERRQ(ierr); 151297952fefSHong Zhang m = a->compressedrow.nrows; 151397952fefSHong Zhang ii = a->compressedrow.i; 151497952fefSHong Zhang ridx = a->compressedrow.rindex; 151597952fefSHong Zhang for (i=0; i<m; i++) { 151697952fefSHong Zhang n = ii[i+1] - ii[i]; 151797952fefSHong Zhang aj = a->j + ii[i]; 151897952fefSHong Zhang aa = a->a + ii[i]; 151997952fefSHong Zhang sum = 0.0; 1520003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1521003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 152297952fefSHong Zhang y[*ridx++] = sum; 152397952fefSHong Zhang } 152497952fefSHong Zhang } else { /* do not use compressed row format */ 1525b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 15263d3eaba7SBarry Smith aj = a->j; 15273d3eaba7SBarry Smith aa = a->a; 1528b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1529b05257ddSBarry Smith #else 153017ab2063SBarry Smith for (i=0; i<m; i++) { 1531003131ecSBarry Smith n = ii[i+1] - ii[i]; 1532003131ecSBarry Smith aj = a->j + ii[i]; 1533003131ecSBarry Smith aa = a->a + ii[i]; 153417ab2063SBarry Smith sum = 0.0; 1535003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 153617ab2063SBarry Smith y[i] = sum; 153717ab2063SBarry Smith } 15388d195f9aSBarry Smith #endif 1539b05257ddSBarry Smith } 15407b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 15413649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 15421ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 15433a40ed3dSBarry Smith PetscFunctionReturn(0); 154417ab2063SBarry Smith } 154517ab2063SBarry Smith 1546b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1547b434eb95SMatthew G. Knepley { 1548b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1549b434eb95SMatthew G. Knepley PetscScalar *y; 1550b434eb95SMatthew G. Knepley const PetscScalar *x; 1551b434eb95SMatthew G. Knepley const MatScalar *aa; 1552b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1553b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1554b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1555b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1556b434eb95SMatthew G. Knepley PetscScalar sum; 1557b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1558b434eb95SMatthew G. Knepley 1559b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1560b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1561b434eb95SMatthew G. Knepley #endif 1562b434eb95SMatthew G. Knepley 1563b434eb95SMatthew G. Knepley PetscFunctionBegin; 1564b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1565b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1566b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1567b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1568b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1569b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1570b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1571b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1572b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1573b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1574b434eb95SMatthew G. Knepley sum = 0.0; 1575b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1576b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1577b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1578b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1579b434eb95SMatthew G. Knepley } 1580b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 15813d3eaba7SBarry Smith ii = a->i; 1582b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1583b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1584b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1585b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1586b434eb95SMatthew G. Knepley sum = 0.0; 1587b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1588b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1589b434eb95SMatthew G. Knepley y[i] = sum; 1590b434eb95SMatthew G. Knepley } 1591b434eb95SMatthew G. Knepley } 1592b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1593b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1594b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1595b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1596b434eb95SMatthew G. Knepley } 1597b434eb95SMatthew G. Knepley 1598b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1599b434eb95SMatthew G. Knepley { 1600b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1601b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1602b434eb95SMatthew G. Knepley const PetscScalar *x; 1603b434eb95SMatthew G. Knepley const MatScalar *aa; 1604b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1605b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1606b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1607b434eb95SMatthew G. Knepley PetscScalar sum; 1608b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1609b434eb95SMatthew G. Knepley 1610b434eb95SMatthew G. Knepley PetscFunctionBegin; 1611b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1612d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1613b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1614b434eb95SMatthew G. Knepley if (zz != yy) { 1615580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 1616b434eb95SMatthew G. Knepley } 1617b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1618b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1619b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1620b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1621b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1622b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1623b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1624b434eb95SMatthew G. Knepley sum = y[*ridx]; 1625b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1626b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1627b434eb95SMatthew G. Knepley } 1628b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 16293d3eaba7SBarry Smith ii = a->i; 1630b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1631b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1632b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1633b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1634b434eb95SMatthew G. Knepley sum = y[i]; 1635b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1636b434eb95SMatthew G. Knepley z[i] = sum; 1637b434eb95SMatthew G. Knepley } 1638b434eb95SMatthew G. Knepley } 1639b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1640b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1641d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1642b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1643b434eb95SMatthew G. Knepley } 1644b434eb95SMatthew G. Knepley 1645c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1646dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 164717ab2063SBarry Smith { 1648416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1649f15663dcSBarry Smith PetscScalar *y,*z; 1650f15663dcSBarry Smith const PetscScalar *x; 165154f21887SBarry Smith const MatScalar *aa; 1652dfbe8321SBarry Smith PetscErrorCode ierr; 1653d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1654d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1655362ced78SSatish Balay PetscScalar sum; 1656ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 16579ea0dfa2SSatish Balay 16583a40ed3dSBarry Smith PetscFunctionBegin; 1659b215bc84SStefano Zampini if (a->inode.use && a->inode.checked) { 1660b215bc84SStefano Zampini ierr = MatMultAdd_SeqAIJ_Inode(A,xx,yy,zz);CHKERRQ(ierr); 1661b215bc84SStefano Zampini PetscFunctionReturn(0); 1662b215bc84SStefano Zampini } 1663f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1664d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 16654eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 16664eb6d288SHong Zhang if (zz != yy) { 1667580bdb30SBarry Smith ierr = PetscArraycpy(z,y,m);CHKERRQ(ierr); 16684eb6d288SHong Zhang } 166997952fefSHong Zhang m = a->compressedrow.nrows; 167097952fefSHong Zhang ii = a->compressedrow.i; 167197952fefSHong Zhang ridx = a->compressedrow.rindex; 167297952fefSHong Zhang for (i=0; i<m; i++) { 167397952fefSHong Zhang n = ii[i+1] - ii[i]; 167497952fefSHong Zhang aj = a->j + ii[i]; 167597952fefSHong Zhang aa = a->a + ii[i]; 167697952fefSHong Zhang sum = y[*ridx]; 1677f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 167897952fefSHong Zhang z[*ridx++] = sum; 167997952fefSHong Zhang } 168097952fefSHong Zhang } else { /* do not use compressed row format */ 16813d3eaba7SBarry Smith ii = a->i; 1682f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 16833d3eaba7SBarry Smith aj = a->j; 16843d3eaba7SBarry Smith aa = a->a; 1685f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1686f15663dcSBarry Smith #else 168717ab2063SBarry Smith for (i=0; i<m; i++) { 1688f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1689f15663dcSBarry Smith aj = a->j + ii[i]; 1690f15663dcSBarry Smith aa = a->a + ii[i]; 169117ab2063SBarry Smith sum = y[i]; 1692f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 169317ab2063SBarry Smith z[i] = sum; 169417ab2063SBarry Smith } 169502ab625aSSatish Balay #endif 1696f15663dcSBarry Smith } 1697dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1698f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1699d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 17003a40ed3dSBarry Smith PetscFunctionReturn(0); 170117ab2063SBarry Smith } 170217ab2063SBarry Smith 170317ab2063SBarry Smith /* 170417ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 170517ab2063SBarry Smith */ 1706dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 170717ab2063SBarry Smith { 1708416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17096849ba73SBarry Smith PetscErrorCode ierr; 1710d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 171117ab2063SBarry Smith 17123a40ed3dSBarry Smith PetscFunctionBegin; 171309f38230SBarry Smith if (!a->diag) { 1714785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 17153bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 171609f38230SBarry Smith } 1717d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 171809f38230SBarry Smith a->diag[i] = a->i[i+1]; 1719bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1720bfeeae90SHong Zhang if (a->j[j] == i) { 172109f38230SBarry Smith a->diag[i] = j; 172217ab2063SBarry Smith break; 172317ab2063SBarry Smith } 172417ab2063SBarry Smith } 172517ab2063SBarry Smith } 17263a40ed3dSBarry Smith PetscFunctionReturn(0); 172717ab2063SBarry Smith } 172817ab2063SBarry Smith 172961ecd0c6SBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat A,PetscScalar v) 173061ecd0c6SBarry Smith { 173161ecd0c6SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 173261ecd0c6SBarry Smith const PetscInt *diag = (const PetscInt*)a->diag; 173361ecd0c6SBarry Smith const PetscInt *ii = (const PetscInt*) a->i; 173461ecd0c6SBarry Smith PetscInt i,*mdiag = NULL; 173561ecd0c6SBarry Smith PetscErrorCode ierr; 173661ecd0c6SBarry Smith PetscInt cnt = 0; /* how many diagonals are missing */ 173761ecd0c6SBarry Smith 173861ecd0c6SBarry Smith PetscFunctionBegin; 173961ecd0c6SBarry Smith if (!A->preallocated || !a->nz) { 174061ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation(A,1,NULL);CHKERRQ(ierr); 174161ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 174261ecd0c6SBarry Smith PetscFunctionReturn(0); 174361ecd0c6SBarry Smith } 174461ecd0c6SBarry Smith 174561ecd0c6SBarry Smith if (a->diagonaldense) { 174661ecd0c6SBarry Smith cnt = 0; 174761ecd0c6SBarry Smith } else { 174861ecd0c6SBarry Smith ierr = PetscCalloc1(A->rmap->n,&mdiag);CHKERRQ(ierr); 174961ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 175061ecd0c6SBarry Smith if (diag[i] >= ii[i+1]) { 175161ecd0c6SBarry Smith cnt++; 175261ecd0c6SBarry Smith mdiag[i] = 1; 175361ecd0c6SBarry Smith } 175461ecd0c6SBarry Smith } 175561ecd0c6SBarry Smith } 175661ecd0c6SBarry Smith if (!cnt) { 175761ecd0c6SBarry Smith ierr = MatShift_Basic(A,v);CHKERRQ(ierr); 175861ecd0c6SBarry Smith } else { 1759b6f2aa54SBarry Smith PetscScalar *olda = a->a; /* preserve pointers to current matrix nonzeros structure and values */ 1760b6f2aa54SBarry Smith PetscInt *oldj = a->j, *oldi = a->i; 176161ecd0c6SBarry Smith PetscBool singlemalloc = a->singlemalloc,free_a = a->free_a,free_ij = a->free_ij; 176261ecd0c6SBarry Smith 176361ecd0c6SBarry Smith a->a = NULL; 176461ecd0c6SBarry Smith a->j = NULL; 176561ecd0c6SBarry Smith a->i = NULL; 176661ecd0c6SBarry Smith /* increase the values in imax for each row where a diagonal is being inserted then reallocate the matrix data structures */ 176761ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 176861ecd0c6SBarry Smith a->imax[i] += mdiag[i]; 1769447d62f5SStefano Zampini a->imax[i] = PetscMin(a->imax[i],A->cmap->n); 177061ecd0c6SBarry Smith } 177161ecd0c6SBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,0,a->imax);CHKERRQ(ierr); 177261ecd0c6SBarry Smith 177361ecd0c6SBarry Smith /* copy old values into new matrix data structure */ 177461ecd0c6SBarry Smith for (i=0; i<A->rmap->n; i++) { 177561ecd0c6SBarry Smith ierr = MatSetValues(A,1,&i,a->imax[i] - mdiag[i],&oldj[oldi[i]],&olda[oldi[i]],ADD_VALUES);CHKERRQ(ierr); 1776447d62f5SStefano Zampini if (i < A->cmap->n) { 177761ecd0c6SBarry Smith ierr = MatSetValue(A,i,i,v,ADD_VALUES);CHKERRQ(ierr); 177861ecd0c6SBarry Smith } 1779447d62f5SStefano Zampini } 178061ecd0c6SBarry Smith ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 178161ecd0c6SBarry Smith ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 178261ecd0c6SBarry Smith if (singlemalloc) { 178361ecd0c6SBarry Smith ierr = PetscFree3(olda,oldj,oldi);CHKERRQ(ierr); 178461ecd0c6SBarry Smith } else { 178561ecd0c6SBarry Smith if (free_a) {ierr = PetscFree(olda);CHKERRQ(ierr);} 178661ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldj);CHKERRQ(ierr);} 178761ecd0c6SBarry Smith if (free_ij) {ierr = PetscFree(oldi);CHKERRQ(ierr);} 178861ecd0c6SBarry Smith } 178961ecd0c6SBarry Smith } 179061ecd0c6SBarry Smith ierr = PetscFree(mdiag);CHKERRQ(ierr); 179161ecd0c6SBarry Smith a->diagonaldense = PETSC_TRUE; 179261ecd0c6SBarry Smith PetscFunctionReturn(0); 179361ecd0c6SBarry Smith } 179461ecd0c6SBarry Smith 1795be5855fcSBarry Smith /* 1796be5855fcSBarry Smith Checks for missing diagonals 1797be5855fcSBarry Smith */ 1798ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1799be5855fcSBarry Smith { 1800be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18017734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1802994fe344SLisandro Dalcin PetscErrorCode ierr; 1803be5855fcSBarry Smith 1804be5855fcSBarry Smith PetscFunctionBegin; 180509f38230SBarry Smith *missing = PETSC_FALSE; 18067734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 180709f38230SBarry Smith *missing = PETSC_TRUE; 180809f38230SBarry Smith if (d) *d = 0; 1809994fe344SLisandro Dalcin ierr = PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n");CHKERRQ(ierr); 181009f38230SBarry Smith } else { 181101445905SHong Zhang PetscInt n; 181201445905SHong Zhang n = PetscMin(A->rmap->n, A->cmap->n); 1813f1e2ffcdSBarry Smith diag = a->diag; 181401445905SHong Zhang for (i=0; i<n; i++) { 18157734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 181609f38230SBarry Smith *missing = PETSC_TRUE; 181709f38230SBarry Smith if (d) *d = i; 1818994fe344SLisandro Dalcin ierr = PetscInfo1(A,"Matrix is missing diagonal number %D\n",i);CHKERRQ(ierr); 1819358d2f5dSShri Abhyankar break; 182009f38230SBarry Smith } 1821be5855fcSBarry Smith } 1822be5855fcSBarry Smith } 1823be5855fcSBarry Smith PetscFunctionReturn(0); 1824be5855fcSBarry Smith } 1825be5855fcSBarry Smith 18260da83c2eSBarry Smith #include <petscblaslapack.h> 18270da83c2eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 18280da83c2eSBarry Smith 18290da83c2eSBarry Smith /* 18300da83c2eSBarry Smith Note that values is allocated externally by the PC and then passed into this routine 18310da83c2eSBarry Smith */ 18320da83c2eSBarry Smith PetscErrorCode MatInvertVariableBlockDiagonal_SeqAIJ(Mat A,PetscInt nblocks,const PetscInt *bsizes,PetscScalar *diag) 18330da83c2eSBarry Smith { 18340da83c2eSBarry Smith PetscErrorCode ierr; 18350da83c2eSBarry Smith PetscInt n = A->rmap->n, i, ncnt = 0, *indx,j,bsizemax = 0,*v_pivots; 18360da83c2eSBarry Smith PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 18370da83c2eSBarry Smith const PetscReal shift = 0.0; 18380da83c2eSBarry Smith PetscInt ipvt[5]; 18390da83c2eSBarry Smith PetscScalar work[25],*v_work; 18400da83c2eSBarry Smith 18410da83c2eSBarry Smith PetscFunctionBegin; 18420da83c2eSBarry Smith allowzeropivot = PetscNot(A->erroriffailure); 18430da83c2eSBarry Smith for (i=0; i<nblocks; i++) ncnt += bsizes[i]; 18440da83c2eSBarry Smith if (ncnt != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Total blocksizes %D doesn't match number matrix rows %D",ncnt,n); 18450da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18460da83c2eSBarry Smith bsizemax = PetscMax(bsizemax,bsizes[i]); 18470da83c2eSBarry Smith } 18480da83c2eSBarry Smith ierr = PetscMalloc1(bsizemax,&indx);CHKERRQ(ierr); 18490da83c2eSBarry Smith if (bsizemax > 7) { 18500da83c2eSBarry Smith ierr = PetscMalloc2(bsizemax,&v_work,bsizemax,&v_pivots);CHKERRQ(ierr); 18510da83c2eSBarry Smith } 18520da83c2eSBarry Smith ncnt = 0; 18530da83c2eSBarry Smith for (i=0; i<nblocks; i++) { 18540da83c2eSBarry Smith for (j=0; j<bsizes[i]; j++) indx[j] = ncnt+j; 18550da83c2eSBarry Smith ierr = MatGetValues(A,bsizes[i],indx,bsizes[i],indx,diag);CHKERRQ(ierr); 18560da83c2eSBarry Smith switch (bsizes[i]) { 18570da83c2eSBarry Smith case 1: 18580da83c2eSBarry Smith *diag = 1.0/(*diag); 18590da83c2eSBarry Smith break; 18600da83c2eSBarry Smith case 2: 18610da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18620da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18630da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 18640da83c2eSBarry Smith break; 18650da83c2eSBarry Smith case 3: 18660da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18670da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18680da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 18690da83c2eSBarry Smith break; 18700da83c2eSBarry Smith case 4: 18710da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18720da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18730da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 18740da83c2eSBarry Smith break; 18750da83c2eSBarry Smith case 5: 18760da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18770da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18780da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 18790da83c2eSBarry Smith break; 18800da83c2eSBarry Smith case 6: 18810da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18820da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18830da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 18840da83c2eSBarry Smith break; 18850da83c2eSBarry Smith case 7: 18860da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18870da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18880da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 18890da83c2eSBarry Smith break; 18900da83c2eSBarry Smith default: 18910da83c2eSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bsizes[i],diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 18920da83c2eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 18930da83c2eSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bsizes[i]);CHKERRQ(ierr); 18940da83c2eSBarry Smith } 18950da83c2eSBarry Smith ncnt += bsizes[i]; 18960da83c2eSBarry Smith diag += bsizes[i]*bsizes[i]; 18970da83c2eSBarry Smith } 18980da83c2eSBarry Smith if (bsizemax > 7) { 18990da83c2eSBarry Smith ierr = PetscFree2(v_work,v_pivots);CHKERRQ(ierr); 19000da83c2eSBarry Smith } 19010da83c2eSBarry Smith ierr = PetscFree(indx);CHKERRQ(ierr); 19020da83c2eSBarry Smith PetscFunctionReturn(0); 19030da83c2eSBarry Smith } 19040da83c2eSBarry Smith 1905422a814eSBarry Smith /* 1906422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1907422a814eSBarry Smith */ 19087087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 190971f1c65dSBarry Smith { 191071f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 191171f1c65dSBarry Smith PetscErrorCode ierr; 1912d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 191354f21887SBarry Smith MatScalar *v = a->a; 191454f21887SBarry Smith PetscScalar *idiag,*mdiag; 191571f1c65dSBarry Smith 191671f1c65dSBarry Smith PetscFunctionBegin; 191771f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 191871f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 191971f1c65dSBarry Smith diag = a->diag; 192071f1c65dSBarry Smith if (!a->idiag) { 1921dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 19223bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 192371f1c65dSBarry Smith v = a->a; 192471f1c65dSBarry Smith } 192571f1c65dSBarry Smith mdiag = a->mdiag; 192671f1c65dSBarry Smith idiag = a->idiag; 192771f1c65dSBarry Smith 1928422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 192971f1c65dSBarry Smith for (i=0; i<m; i++) { 193071f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1931899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1932899639b0SHong Zhang if (PetscRealPart(fshift)) { 1933899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 19347b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 19357b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 19367b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 1937a6fa060aSHong Zhang } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1938899639b0SHong Zhang } 193971f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 194071f1c65dSBarry Smith } 194171f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 194271f1c65dSBarry Smith } else { 194371f1c65dSBarry Smith for (i=0; i<m; i++) { 194471f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 194571f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 194671f1c65dSBarry Smith } 1947dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 194871f1c65dSBarry Smith } 194971f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 195071f1c65dSBarry Smith PetscFunctionReturn(0); 195171f1c65dSBarry Smith } 195271f1c65dSBarry Smith 1953c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 195441f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 195517ab2063SBarry Smith { 1956416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1957e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1958f4259b30SLisandro Dalcin const MatScalar *v,*idiag=NULL,*mdiag; 195954f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1960dfbe8321SBarry Smith PetscErrorCode ierr; 19613d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 196297f1f81fSBarry Smith const PetscInt *idx,*diag; 196317ab2063SBarry Smith 19643a40ed3dSBarry Smith PetscFunctionBegin; 1965b215bc84SStefano Zampini if (a->inode.use && a->inode.checked && omega == 1.0 && fshift == 0.0) { 1966b215bc84SStefano Zampini ierr = MatSOR_SeqAIJ_Inode(A,bb,omega,flag,fshift,its,lits,xx);CHKERRQ(ierr); 1967b215bc84SStefano Zampini PetscFunctionReturn(0); 1968b215bc84SStefano Zampini } 1969b965ef7fSBarry Smith its = its*lits; 197091723122SBarry Smith 197171f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 197271f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 197371f1c65dSBarry Smith a->fshift = fshift; 197471f1c65dSBarry Smith a->omega = omega; 1975ed480e8bSBarry Smith 197671f1c65dSBarry Smith diag = a->diag; 197771f1c65dSBarry Smith t = a->ssor_work; 1978ed480e8bSBarry Smith idiag = a->idiag; 197971f1c65dSBarry Smith mdiag = a->mdiag; 1980ed480e8bSBarry Smith 19811ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 19823649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1983ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 198417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 198517ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1986ed480e8bSBarry Smith bs = b; 198717ab2063SBarry Smith for (i=0; i<m; i++) { 198871f1c65dSBarry Smith d = fshift + mdiag[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]*d/omega; 1993003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 199417ab2063SBarry Smith x[i] = sum; 199517ab2063SBarry Smith } 19961ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 19973649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1998efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 19993a40ed3dSBarry Smith PetscFunctionReturn(0); 200017ab2063SBarry Smith } 2001c783ea89SBarry Smith 20022205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 20032205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 20044c500f23SPierre Jolivet /* Let A = L + U + D; where L is lower triangular, 2005887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 200617ab2063SBarry Smith 200717ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 200817ab2063SBarry Smith 2009887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 201017ab2063SBarry Smith */ 201117ab2063SBarry Smith scale = (2.0/omega) - 1.0; 201217ab2063SBarry Smith 201317ab2063SBarry Smith /* x = (E + U)^{-1} b */ 201417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2015416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2016ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 2017ed480e8bSBarry Smith v = a->a + diag[i] + 1; 201817ab2063SBarry Smith sum = b[i]; 2019e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2020ed480e8bSBarry Smith x[i] = sum*idiag[i]; 202117ab2063SBarry Smith } 202217ab2063SBarry Smith 202317ab2063SBarry Smith /* t = b - (2*E - D)x */ 2024416022c9SBarry Smith v = a->a; 20252205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 202617ab2063SBarry Smith 202717ab2063SBarry Smith /* t = (E + L)^{-1}t */ 2028ed480e8bSBarry Smith ts = t; 2029416022c9SBarry Smith diag = a->diag; 203017ab2063SBarry Smith for (i=0; i<m; i++) { 2031416022c9SBarry Smith n = diag[i] - a->i[i]; 2032ed480e8bSBarry Smith idx = a->j + a->i[i]; 2033ed480e8bSBarry Smith v = a->a + a->i[i]; 203417ab2063SBarry Smith sum = t[i]; 2035003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 2036ed480e8bSBarry Smith t[i] = sum*idiag[i]; 2037733d66baSBarry Smith /* x = x + t */ 2038733d66baSBarry Smith x[i] += t[i]; 203917ab2063SBarry Smith } 204017ab2063SBarry Smith 2041dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 20421ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 20433649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 20443a40ed3dSBarry Smith PetscFunctionReturn(0); 204517ab2063SBarry Smith } 204617ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 204717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 204817ab2063SBarry Smith for (i=0; i<m; i++) { 2049416022c9SBarry Smith n = diag[i] - a->i[i]; 2050ed480e8bSBarry Smith idx = a->j + a->i[i]; 2051ed480e8bSBarry Smith v = a->a + a->i[i]; 205217ab2063SBarry Smith sum = b[i]; 2053e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20545c99c7daSBarry Smith t[i] = sum; 2055ed480e8bSBarry Smith x[i] = sum*idiag[i]; 205617ab2063SBarry Smith } 20575c99c7daSBarry Smith xb = t; 2058efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 20593a40ed3dSBarry Smith } else xb = b; 206017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 206117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2062416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 2063ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 2064ed480e8bSBarry Smith v = a->a + diag[i] + 1; 206517ab2063SBarry Smith sum = xb[i]; 2066e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 20675c99c7daSBarry Smith if (xb == b) { 2068ed480e8bSBarry Smith x[i] = sum*idiag[i]; 20695c99c7daSBarry Smith } else { 2070b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 207117ab2063SBarry Smith } 20725c99c7daSBarry Smith } 2073b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 207417ab2063SBarry Smith } 207517ab2063SBarry Smith its--; 207617ab2063SBarry Smith } 207717ab2063SBarry Smith while (its--) { 207817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 207917ab2063SBarry Smith for (i=0; i<m; i++) { 2080b19a5dc2SMark Adams /* lower */ 2081b19a5dc2SMark Adams n = diag[i] - a->i[i]; 2082ed480e8bSBarry Smith idx = a->j + a->i[i]; 2083ed480e8bSBarry Smith v = a->a + a->i[i]; 208417ab2063SBarry Smith sum = b[i]; 2085e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2086b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 2087b19a5dc2SMark Adams /* upper */ 2088b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2089b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 2090b19a5dc2SMark Adams v = a->a + diag[i] + 1; 2091b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2092b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 209317ab2063SBarry Smith } 2094b19a5dc2SMark Adams xb = t; 20959f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2096b19a5dc2SMark Adams } else xb = b; 209717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 209817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 2099b19a5dc2SMark Adams sum = xb[i]; 2100b19a5dc2SMark Adams if (xb == b) { 2101b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 2102416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 2103ed480e8bSBarry Smith idx = a->j + a->i[i]; 2104ed480e8bSBarry Smith v = a->a + a->i[i]; 2105e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 2106ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 2107b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 2108b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 2109b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 2110b19a5dc2SMark Adams v = a->a + diag[i] + 1; 2111b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 2112b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 211317ab2063SBarry Smith } 2114b19a5dc2SMark Adams } 2115b19a5dc2SMark Adams if (xb == b) { 21169f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 2117b19a5dc2SMark Adams } else { 2118b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 2119b19a5dc2SMark Adams } 212017ab2063SBarry Smith } 212117ab2063SBarry Smith } 21221ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 21233649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 2124365a8a9eSBarry Smith PetscFunctionReturn(0); 212517ab2063SBarry Smith } 212617ab2063SBarry Smith 21272af78befSBarry Smith 2128dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 212917ab2063SBarry Smith { 2130416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 21314e220ebcSLois Curfman McInnes 21323a40ed3dSBarry Smith PetscFunctionBegin; 21334e220ebcSLois Curfman McInnes info->block_size = 1.0; 21343966268fSBarry Smith info->nz_allocated = a->maxnz; 21353966268fSBarry Smith info->nz_used = a->nz; 21363966268fSBarry Smith info->nz_unneeded = (a->maxnz - a->nz); 21373966268fSBarry Smith info->assemblies = A->num_ass; 21383966268fSBarry Smith info->mallocs = A->info.mallocs; 21397adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2140d5f3da31SBarry Smith if (A->factortype) { 21414e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 21424e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 21434e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 21444e220ebcSLois Curfman McInnes } else { 21454e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 21464e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 21474e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 21484e220ebcSLois Curfman McInnes } 21493a40ed3dSBarry Smith PetscFunctionReturn(0); 215017ab2063SBarry Smith } 215117ab2063SBarry Smith 21522b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 215317ab2063SBarry Smith { 2154416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2155c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 21566849ba73SBarry Smith PetscErrorCode ierr; 215797b48c8fSBarry Smith const PetscScalar *xx; 215897b48c8fSBarry Smith PetscScalar *bb; 2159c7da8527SEric Chamberland PetscInt d = 0; 216017ab2063SBarry Smith 21613a40ed3dSBarry Smith PetscFunctionBegin; 216297b48c8fSBarry Smith if (x && b) { 216397b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 216497b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 216597b48c8fSBarry Smith for (i=0; i<N; i++) { 216697b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2167447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 216897b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 216997b48c8fSBarry Smith } 217097b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 217197b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 217297b48c8fSBarry Smith } 217397b48c8fSBarry Smith 2174a9817697SBarry Smith if (a->keepnonzeropattern) { 2175f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2176e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2177580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 2178f1e2ffcdSBarry Smith } 2179f4df32b1SMatthew Knepley if (diag != 0.0) { 2180c7da8527SEric Chamberland for (i=0; i<N; i++) { 2181c7da8527SEric Chamberland d = rows[i]; 2182447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2183c7da8527SEric 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); 2184c7da8527SEric Chamberland } 2185f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 2186447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) continue; 2187f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 2188f1e2ffcdSBarry Smith } 2189f1e2ffcdSBarry Smith } 2190f1e2ffcdSBarry Smith } else { 2191f4df32b1SMatthew Knepley if (diag != 0.0) { 219217ab2063SBarry Smith for (i=0; i<N; i++) { 2193e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 21947ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 2195447d62f5SStefano Zampini if (rows[i] >= A->cmap->n) { 2196447d62f5SStefano Zampini a->ilen[rows[i]] = 0; 2197447d62f5SStefano Zampini } else { 2198416022c9SBarry Smith a->ilen[rows[i]] = 1; 2199f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 2200bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 2201447d62f5SStefano Zampini } 2202447d62f5SStefano Zampini } else if (rows[i] < A->cmap->n) { /* in case row was completely empty */ 2203f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 220417ab2063SBarry Smith } 220517ab2063SBarry Smith } 22063a40ed3dSBarry Smith } else { 220717ab2063SBarry Smith for (i=0; i<N; i++) { 2208e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2209416022c9SBarry Smith a->ilen[rows[i]] = 0; 221017ab2063SBarry Smith } 221117ab2063SBarry Smith } 2212e56f5c9eSBarry Smith A->nonzerostate++; 2213f1e2ffcdSBarry Smith } 22148c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2215c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2216e2cf4d64SStefano Zampini #endif 22174099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22183a40ed3dSBarry Smith PetscFunctionReturn(0); 221917ab2063SBarry Smith } 222017ab2063SBarry Smith 22216e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 22226e169961SBarry Smith { 22236e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22246e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 22256e169961SBarry Smith PetscErrorCode ierr; 22262b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 22276e169961SBarry Smith const PetscScalar *xx; 22286e169961SBarry Smith PetscScalar *bb; 22296e169961SBarry Smith 22306e169961SBarry Smith PetscFunctionBegin; 22316e169961SBarry Smith if (x && b) { 22326e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 22336e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 22342b40b63fSBarry Smith vecs = PETSC_TRUE; 22356e169961SBarry Smith } 22361795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 22376e169961SBarry Smith for (i=0; i<N; i++) { 22386e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 2239580bdb30SBarry Smith ierr = PetscArrayzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]);CHKERRQ(ierr); 22402205254eSKarl Rupp 22416e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 22426e169961SBarry Smith } 22436e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 22446e169961SBarry Smith if (!zeroed[i]) { 22456e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 22464cf107fdSStefano Zampini if (a->j[j] < A->rmap->n && zeroed[a->j[j]]) { 22472b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 22486e169961SBarry Smith a->a[j] = 0.0; 22496e169961SBarry Smith } 22506e169961SBarry Smith } 22514cf107fdSStefano Zampini } else if (vecs && i < A->cmap->N) bb[i] = diag*xx[i]; 22526e169961SBarry Smith } 22536e169961SBarry Smith if (x && b) { 22546e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 22556e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 22566e169961SBarry Smith } 22576e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 22586e169961SBarry Smith if (diag != 0.0) { 22596e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 22601d5a398dSstefano_zampini if (missing) { 22611d5a398dSstefano_zampini for (i=0; i<N; i++) { 22624cf107fdSStefano Zampini if (rows[i] >= A->cmap->N) continue; 22634cf107fdSStefano 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]); 22641d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 22651d5a398dSstefano_zampini } 22661d5a398dSstefano_zampini } else { 22676e169961SBarry Smith for (i=0; i<N; i++) { 22686e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 22696e169961SBarry Smith } 22706e169961SBarry Smith } 22711d5a398dSstefano_zampini } 22728c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2273c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2274e2cf4d64SStefano Zampini #endif 22754099cc6bSBarry Smith ierr = (*A->ops->assemblyend)(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22766e169961SBarry Smith PetscFunctionReturn(0); 22776e169961SBarry Smith } 22786e169961SBarry Smith 2279a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 228017ab2063SBarry Smith { 2281416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 228297f1f81fSBarry Smith PetscInt *itmp; 228317ab2063SBarry Smith 22843a40ed3dSBarry Smith PetscFunctionBegin; 2285e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 228617ab2063SBarry Smith 2287416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 2288bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 228917ab2063SBarry Smith if (idx) { 2290bfeeae90SHong Zhang itmp = a->j + a->i[row]; 229126fbe8dcSKarl Rupp if (*nz) *idx = itmp; 2292f4259b30SLisandro Dalcin else *idx = NULL; 229317ab2063SBarry Smith } 22943a40ed3dSBarry Smith PetscFunctionReturn(0); 229517ab2063SBarry Smith } 229617ab2063SBarry Smith 2297bfeeae90SHong Zhang /* remove this function? */ 2298a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 229917ab2063SBarry Smith { 23003a40ed3dSBarry Smith PetscFunctionBegin; 23013a40ed3dSBarry Smith PetscFunctionReturn(0); 230217ab2063SBarry Smith } 230317ab2063SBarry Smith 2304dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 230517ab2063SBarry Smith { 2306416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 230754f21887SBarry Smith MatScalar *v = a->a; 230836db0b34SBarry Smith PetscReal sum = 0.0; 23096849ba73SBarry Smith PetscErrorCode ierr; 231097f1f81fSBarry Smith PetscInt i,j; 231117ab2063SBarry Smith 23123a40ed3dSBarry Smith PetscFunctionBegin; 231317ab2063SBarry Smith if (type == NORM_FROBENIUS) { 2314570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 2315570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 231673cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&nz,v,&one)); 2317570b7f6dSBarry Smith #else 2318416022c9SBarry Smith for (i=0; i<a->nz; i++) { 231936db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 232017ab2063SBarry Smith } 23218f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 2322570b7f6dSBarry Smith #endif 2323ca0c957dSBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 23243a40ed3dSBarry Smith } else if (type == NORM_1) { 232536db0b34SBarry Smith PetscReal *tmp; 232697f1f81fSBarry Smith PetscInt *jj = a->j; 23271795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 2328064f8208SBarry Smith *nrm = 0.0; 2329416022c9SBarry Smith for (j=0; j<a->nz; j++) { 2330bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 233117ab2063SBarry Smith } 2332d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 2333064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 233417ab2063SBarry Smith } 2335606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 233651f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 23373a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2338064f8208SBarry Smith *nrm = 0.0; 2339d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 2340bfeeae90SHong Zhang v = a->a + a->i[j]; 234117ab2063SBarry Smith sum = 0.0; 2342416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 2343cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 234417ab2063SBarry Smith } 2345064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 234617ab2063SBarry Smith } 234751f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 2348f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 23493a40ed3dSBarry Smith PetscFunctionReturn(0); 235017ab2063SBarry Smith } 235117ab2063SBarry Smith 23524e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 23534e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 23544e938277SHong Zhang { 23554e938277SHong Zhang PetscErrorCode ierr; 23564e938277SHong Zhang PetscInt i,j,anzj; 23574e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 23584e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 23594e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 23604e938277SHong Zhang 23614e938277SHong Zhang PetscFunctionBegin; 23624e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 2363854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 2364785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 2365785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 23664e938277SHong Zhang 23674e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 23684e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 236926fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 23704e938277SHong Zhang /* Form ati for csr format of A^T. */ 237126fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 23724e938277SHong Zhang 23734e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 2374580bdb30SBarry Smith ierr = PetscArraycpy(atfill,ati,an);CHKERRQ(ierr); 23754e938277SHong Zhang 23764e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 23774e938277SHong Zhang for (i=0;i<am;i++) { 23784e938277SHong Zhang anzj = ai[i+1] - ai[i]; 23794e938277SHong Zhang for (j=0;j<anzj;j++) { 23804e938277SHong Zhang atj[atfill[*aj]] = i; 23814e938277SHong Zhang atfill[*aj++] += 1; 23824e938277SHong Zhang } 23834e938277SHong Zhang } 23844e938277SHong Zhang 23854e938277SHong Zhang /* Clean up temporary space and complete requests. */ 23864e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 2387ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 238833d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 2389b5bb3eecSMark Adams ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2390a2f3521dSMark F. Adams 23914e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 23924e938277SHong Zhang b->free_a = PETSC_FALSE; 23934e938277SHong Zhang b->free_ij = PETSC_TRUE; 23944e938277SHong Zhang b->nonew = 0; 23954e938277SHong Zhang PetscFunctionReturn(0); 23964e938277SHong Zhang } 23974e938277SHong Zhang 23987087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2399cd0d46ebSvictorle { 24003d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 240154f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 240254f21887SBarry Smith MatScalar *va,*vb; 24036849ba73SBarry Smith PetscErrorCode ierr; 240497f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2405cd0d46ebSvictorle 2406cd0d46ebSvictorle PetscFunctionBegin; 2407cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2408cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24095485867bSBarry Smith if (ma!=nb || na!=mb) { 24105485867bSBarry Smith *f = PETSC_FALSE; 24115485867bSBarry Smith PetscFunctionReturn(0); 24125485867bSBarry Smith } 2413cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2414cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2415cd0d46ebSvictorle va = aij->a; vb = bij->a; 2416785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2417785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2418cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2419cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2420cd0d46ebSvictorle 2421cd0d46ebSvictorle *f = PETSC_TRUE; 2422cd0d46ebSvictorle for (i=0; i<ma; i++) { 2423cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 242497f1f81fSBarry Smith PetscInt idc,idr; 24255485867bSBarry Smith PetscScalar vc,vr; 2426cd0d46ebSvictorle /* column/row index/value */ 24275485867bSBarry Smith idc = adx[aptr[i]]; 24285485867bSBarry Smith idr = bdx[bptr[idc]]; 24295485867bSBarry Smith vc = va[aptr[i]]; 24305485867bSBarry Smith vr = vb[bptr[idc]]; 24315485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 24325485867bSBarry Smith *f = PETSC_FALSE; 24335485867bSBarry Smith goto done; 2434cd0d46ebSvictorle } else { 24355485867bSBarry Smith aptr[i]++; 24365485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2437cd0d46ebSvictorle } 2438cd0d46ebSvictorle } 2439cd0d46ebSvictorle } 2440cd0d46ebSvictorle done: 2441cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 24423aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2443cd0d46ebSvictorle PetscFunctionReturn(0); 2444cd0d46ebSvictorle } 2445cd0d46ebSvictorle 24467087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 24471cbb95d3SBarry Smith { 24483d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 244954f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 245054f21887SBarry Smith MatScalar *va,*vb; 24511cbb95d3SBarry Smith PetscErrorCode ierr; 24521cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 24531cbb95d3SBarry Smith 24541cbb95d3SBarry Smith PetscFunctionBegin; 24551cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 24561cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 24571cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 24581cbb95d3SBarry Smith *f = PETSC_FALSE; 24591cbb95d3SBarry Smith PetscFunctionReturn(0); 24601cbb95d3SBarry Smith } 24611cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 24621cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 24631cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2464785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2465785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 24661cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 24671cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 24681cbb95d3SBarry Smith 24691cbb95d3SBarry Smith *f = PETSC_TRUE; 24701cbb95d3SBarry Smith for (i=0; i<ma; i++) { 24711cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 24721cbb95d3SBarry Smith PetscInt idc,idr; 24731cbb95d3SBarry Smith PetscScalar vc,vr; 24741cbb95d3SBarry Smith /* column/row index/value */ 24751cbb95d3SBarry Smith idc = adx[aptr[i]]; 24761cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 24771cbb95d3SBarry Smith vc = va[aptr[i]]; 24781cbb95d3SBarry Smith vr = vb[bptr[idc]]; 24791cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 24801cbb95d3SBarry Smith *f = PETSC_FALSE; 24811cbb95d3SBarry Smith goto done; 24821cbb95d3SBarry Smith } else { 24831cbb95d3SBarry Smith aptr[i]++; 24841cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 24851cbb95d3SBarry Smith } 24861cbb95d3SBarry Smith } 24871cbb95d3SBarry Smith } 24881cbb95d3SBarry Smith done: 24891cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 24901cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 24911cbb95d3SBarry Smith PetscFunctionReturn(0); 24921cbb95d3SBarry Smith } 24931cbb95d3SBarry Smith 2494ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 24959e29f15eSvictorle { 2496dfbe8321SBarry Smith PetscErrorCode ierr; 24976e111a19SKarl Rupp 24989e29f15eSvictorle PetscFunctionBegin; 24995485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25009e29f15eSvictorle PetscFunctionReturn(0); 25019e29f15eSvictorle } 25029e29f15eSvictorle 2503ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 25041cbb95d3SBarry Smith { 25051cbb95d3SBarry Smith PetscErrorCode ierr; 25066e111a19SKarl Rupp 25071cbb95d3SBarry Smith PetscFunctionBegin; 25081cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 25091cbb95d3SBarry Smith PetscFunctionReturn(0); 25101cbb95d3SBarry Smith } 25111cbb95d3SBarry Smith 2512dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 251317ab2063SBarry Smith { 2514416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2515fff8e43fSBarry Smith const PetscScalar *l,*r; 2516fff8e43fSBarry Smith PetscScalar x; 251754f21887SBarry Smith MatScalar *v; 2518dfbe8321SBarry Smith PetscErrorCode ierr; 2519fff8e43fSBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz; 2520fff8e43fSBarry Smith const PetscInt *jj; 252117ab2063SBarry Smith 25223a40ed3dSBarry Smith PetscFunctionBegin; 252317ab2063SBarry Smith if (ll) { 25243ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 25253ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2526e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2527e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 2528fff8e43fSBarry Smith ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 2529416022c9SBarry Smith v = a->a; 253017ab2063SBarry Smith for (i=0; i<m; i++) { 253117ab2063SBarry Smith x = l[i]; 2532416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 25332205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 253417ab2063SBarry Smith } 2535fff8e43fSBarry Smith ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 2536efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 253717ab2063SBarry Smith } 253817ab2063SBarry Smith if (rr) { 2539e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2540e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 2541fff8e43fSBarry Smith ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 2542416022c9SBarry Smith v = a->a; jj = a->j; 25432205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 2544fff8e43fSBarry Smith ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 2545efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 254617ab2063SBarry Smith } 2547acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 25488c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2549c70f7ee4SJunchao Zhang if (A->offloadmask != PETSC_OFFLOAD_UNALLOCATED) A->offloadmask = PETSC_OFFLOAD_CPU; 2550e2cf4d64SStefano Zampini #endif 25513a40ed3dSBarry Smith PetscFunctionReturn(0); 255217ab2063SBarry Smith } 255317ab2063SBarry Smith 25547dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 255517ab2063SBarry Smith { 2556db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 25576849ba73SBarry Smith PetscErrorCode ierr; 2558d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 255997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 25605d0c19d7SBarry Smith const PetscInt *irow,*icol; 25615d0c19d7SBarry Smith PetscInt nrows,ncols; 256297f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 256354f21887SBarry Smith MatScalar *a_new,*mat_a; 2564416022c9SBarry Smith Mat C; 2565cdc6f3adSToby Isaac PetscBool stride; 256617ab2063SBarry Smith 25673a40ed3dSBarry Smith PetscFunctionBegin; 256899141d43SSatish Balay 256917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2570b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2571b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 257217ab2063SBarry Smith 2573251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2574ff718158SBarry Smith if (stride) { 2575ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2576ff718158SBarry Smith } else { 2577ff718158SBarry Smith first = 0; 2578ff718158SBarry Smith step = 0; 2579ff718158SBarry Smith } 2580fee21e36SBarry Smith if (stride && step == 1) { 258102834360SBarry Smith /* special case of contiguous rows */ 2582dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 258302834360SBarry Smith /* loop over new rows determining lens and starting points */ 258402834360SBarry Smith for (i=0; i<nrows; i++) { 2585bfeeae90SHong Zhang kstart = ai[irow[i]]; 2586a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2587a91a9bebSLisandro Dalcin starts[i] = kstart; 258802834360SBarry Smith for (k=kstart; k<kend; k++) { 2589bfeeae90SHong Zhang if (aj[k] >= first) { 259002834360SBarry Smith starts[i] = k; 259102834360SBarry Smith break; 259202834360SBarry Smith } 259302834360SBarry Smith } 2594a2744918SBarry Smith sum = 0; 259502834360SBarry Smith while (k < kend) { 2596bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2597a2744918SBarry Smith sum++; 259802834360SBarry Smith } 2599a2744918SBarry Smith lens[i] = sum; 260002834360SBarry Smith } 260102834360SBarry Smith /* create submatrix */ 2602cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 260397f1f81fSBarry Smith PetscInt n_cols,n_rows; 260408480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2605e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2606d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 260708480c60SBarry Smith C = *B; 26083a40ed3dSBarry Smith } else { 26093bef6203SJed Brown PetscInt rbs,cbs; 2610ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2611f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26123bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26133bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26143bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26157adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2616ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 261708480c60SBarry Smith } 2618db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2619db02288aSLois Curfman McInnes 262002834360SBarry Smith /* loop over rows inserting into submatrix */ 2621db02288aSLois Curfman McInnes a_new = c->a; 2622db02288aSLois Curfman McInnes j_new = c->j; 2623db02288aSLois Curfman McInnes i_new = c->i; 2624bfeeae90SHong Zhang 262502834360SBarry Smith for (i=0; i<nrows; i++) { 2626a2744918SBarry Smith ii = starts[i]; 2627a2744918SBarry Smith lensi = lens[i]; 2628a2744918SBarry Smith for (k=0; k<lensi; k++) { 2629a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 263002834360SBarry Smith } 2631580bdb30SBarry Smith ierr = PetscArraycpy(a_new,a->a + starts[i],lensi);CHKERRQ(ierr); 2632a2744918SBarry Smith a_new += lensi; 2633a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2634a2744918SBarry Smith c->ilen[i] = lensi; 263502834360SBarry Smith } 26360e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 26373a40ed3dSBarry Smith } else { 263802834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 26391795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2640854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 26414dcab191SBarry Smith for (i=0; i<ncols; i++) { 2642d9ef940eSSatish 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); 26434dcab191SBarry Smith smap[icol[i]] = i+1; 26444dcab191SBarry Smith } 26454dcab191SBarry Smith 264602834360SBarry Smith /* determine lens of each row */ 264702834360SBarry Smith for (i=0; i<nrows; i++) { 2648bfeeae90SHong Zhang kstart = ai[irow[i]]; 264902834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 265002834360SBarry Smith lens[i] = 0; 265102834360SBarry Smith for (k=kstart; k<kend; k++) { 2652bfeeae90SHong Zhang if (smap[aj[k]]) { 265302834360SBarry Smith lens[i]++; 265402834360SBarry Smith } 265502834360SBarry Smith } 265602834360SBarry Smith } 265717ab2063SBarry Smith /* Create and fill new matrix */ 2658a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2659ace3abfcSBarry Smith PetscBool equal; 26600f5bd95cSBarry Smith 266199141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2662e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2663580bdb30SBarry Smith ierr = PetscArraycmp(c->ilen,lens,(*B)->rmap->n,&equal);CHKERRQ(ierr); 2664f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2665580bdb30SBarry Smith ierr = PetscArrayzero(c->ilen,(*B)->rmap->n);CHKERRQ(ierr); 266608480c60SBarry Smith C = *B; 26673a40ed3dSBarry Smith } else { 26683bef6203SJed Brown PetscInt rbs,cbs; 2669ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2670f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 26713bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 26723bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 26733bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 26747adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2675ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 267608480c60SBarry Smith } 267799141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 267817ab2063SBarry Smith for (i=0; i<nrows; i++) { 267999141d43SSatish Balay row = irow[i]; 2680bfeeae90SHong Zhang kstart = ai[row]; 268199141d43SSatish Balay kend = kstart + a->ilen[row]; 2682bfeeae90SHong Zhang mat_i = c->i[i]; 268399141d43SSatish Balay mat_j = c->j + mat_i; 268499141d43SSatish Balay mat_a = c->a + mat_i; 268599141d43SSatish Balay mat_ilen = c->ilen + i; 268617ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2687bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2688ed480e8bSBarry Smith *mat_j++ = tcol - 1; 268999141d43SSatish Balay *mat_a++ = a->a[k]; 269099141d43SSatish Balay (*mat_ilen)++; 269199141d43SSatish Balay 269217ab2063SBarry Smith } 269317ab2063SBarry Smith } 269417ab2063SBarry Smith } 269502834360SBarry Smith /* Free work space */ 269602834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2697606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2698606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2699cdc6f3adSToby Isaac /* sort */ 2700cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2701cdc6f3adSToby Isaac PetscInt ilen; 2702cdc6f3adSToby Isaac 2703cdc6f3adSToby Isaac mat_i = c->i[i]; 2704cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2705cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2706cdc6f3adSToby Isaac ilen = c->ilen[i]; 2707390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2708cdc6f3adSToby Isaac } 270902834360SBarry Smith } 27108c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2711b470e4b4SRichard Tran Mills ierr = MatBindToCPU(C,A->boundtocpu);CHKERRQ(ierr); 2712305c6ccfSStefano Zampini #endif 27136d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27146d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 271517ab2063SBarry Smith 271617ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2717416022c9SBarry Smith *B = C; 27183a40ed3dSBarry Smith PetscFunctionReturn(0); 271917ab2063SBarry Smith } 272017ab2063SBarry Smith 2721fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 272282d44351SHong Zhang { 272382d44351SHong Zhang PetscErrorCode ierr; 272482d44351SHong Zhang Mat B; 272582d44351SHong Zhang 272682d44351SHong Zhang PetscFunctionBegin; 2727c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 272882d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 272982d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 273033d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 273182d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 273282d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 273382d44351SHong Zhang *subMat = B; 2734c2d650bdSHong Zhang } else { 2735c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2736c2d650bdSHong Zhang } 273782d44351SHong Zhang PetscFunctionReturn(0); 273882d44351SHong Zhang } 273982d44351SHong Zhang 27409a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2741a871dcd8SBarry Smith { 274263b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2743dfbe8321SBarry Smith PetscErrorCode ierr; 274463b91edcSBarry Smith Mat outA; 2745ace3abfcSBarry Smith PetscBool row_identity,col_identity; 274663b91edcSBarry Smith 27473a40ed3dSBarry Smith PetscFunctionBegin; 2748e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 27491df811f5SHong Zhang 2750b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2751b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2752a871dcd8SBarry Smith 275363b91edcSBarry Smith outA = inA; 2754d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2755f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2756f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 27572205254eSKarl Rupp 2758c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 27596bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 27602205254eSKarl Rupp 2761c3122656SLisandro Dalcin a->row = row; 27622205254eSKarl Rupp 2763c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 27646bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 27652205254eSKarl Rupp 2766c3122656SLisandro Dalcin a->col = col; 276763b91edcSBarry Smith 276836db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 27696bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 27704c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 27713bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2772f0ec6fceSSatish Balay 277394a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2774854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 27753bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 277694a9d846SBarry Smith } 277763b91edcSBarry Smith 2778f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2779137fb511SHong Zhang if (row_identity && col_identity) { 2780ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2781137fb511SHong Zhang } else { 2782719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2783137fb511SHong Zhang } 27843a40ed3dSBarry Smith PetscFunctionReturn(0); 2785a871dcd8SBarry Smith } 2786a871dcd8SBarry Smith 2787f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2788f0b747eeSBarry Smith { 2789f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2790f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2791efee365bSSatish Balay PetscErrorCode ierr; 2792c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 27933a40ed3dSBarry Smith 27943a40ed3dSBarry Smith PetscFunctionBegin; 2795c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 27968b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2797efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2798acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 27998c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 2800c70f7ee4SJunchao Zhang if (inA->offloadmask != PETSC_OFFLOAD_UNALLOCATED) inA->offloadmask = PETSC_OFFLOAD_CPU; 2801e2cf4d64SStefano Zampini #endif 28023a40ed3dSBarry Smith PetscFunctionReturn(0); 2803f0b747eeSBarry Smith } 2804f0b747eeSBarry Smith 2805f68bb481SHong Zhang PetscErrorCode MatDestroySubMatrix_Private(Mat_SubSppt *submatj) 280616b64355SHong Zhang { 280716b64355SHong Zhang PetscErrorCode ierr; 280816b64355SHong Zhang PetscInt i; 280916b64355SHong Zhang 281016b64355SHong Zhang PetscFunctionBegin; 281116b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 281216b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 281316b64355SHong Zhang 281416b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 281516b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 281616b64355SHong Zhang } 281716b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 281816b64355SHong Zhang 281916b64355SHong Zhang if (submatj->rbuf1) { 282016b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 282116b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 282216b64355SHong Zhang } 282316b64355SHong Zhang 282416b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 282516b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 282616b64355SHong Zhang } 282716b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 282816b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 282916b64355SHong Zhang } 283016b64355SHong Zhang 283116b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 283216b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 283316b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 283416b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 283516b64355SHong Zhang #else 283616b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 283716b64355SHong Zhang #endif 283816b64355SHong Zhang 283916b64355SHong Zhang if (!submatj->allcolumns) { 284016b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 284116b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 284216b64355SHong Zhang #else 284316b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 284416b64355SHong Zhang #endif 284516b64355SHong Zhang } 284616b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 284716b64355SHong Zhang 284816b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 284916b64355SHong Zhang PetscFunctionReturn(0); 285016b64355SHong Zhang } 285116b64355SHong Zhang 28520fb991dcSHong Zhang PetscErrorCode MatDestroySubMatrix_SeqAIJ(Mat C) 285316b64355SHong Zhang { 285416b64355SHong Zhang PetscErrorCode ierr; 285516b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 28565c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 285716b64355SHong Zhang 285816b64355SHong Zhang PetscFunctionBegin; 285934136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2860f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 286116b64355SHong Zhang PetscFunctionReturn(0); 286216b64355SHong Zhang } 286316b64355SHong Zhang 28642d033e1fSHong Zhang PetscErrorCode MatDestroySubMatrices_SeqAIJ(PetscInt n,Mat *mat[]) 28652d033e1fSHong Zhang { 28662d033e1fSHong Zhang PetscErrorCode ierr; 28672d033e1fSHong Zhang PetscInt i; 28680fb991dcSHong Zhang Mat C; 28690fb991dcSHong Zhang Mat_SeqAIJ *c; 28700fb991dcSHong Zhang Mat_SubSppt *submatj; 28712d033e1fSHong Zhang 28722d033e1fSHong Zhang PetscFunctionBegin; 28732d033e1fSHong Zhang for (i=0; i<n; i++) { 28740fb991dcSHong Zhang C = (*mat)[i]; 28750fb991dcSHong Zhang c = (Mat_SeqAIJ*)C->data; 28760fb991dcSHong Zhang submatj = c->submatis1; 28772d033e1fSHong Zhang if (submatj) { 2878682e4c99SStefano Zampini if (--((PetscObject)C)->refct <= 0) { 287934136279SStefano Zampini ierr = (*submatj->destroy)(C);CHKERRQ(ierr); 2880f68bb481SHong Zhang ierr = MatDestroySubMatrix_Private(submatj);CHKERRQ(ierr); 288134136279SStefano Zampini ierr = PetscFree(C->defaultvectype);CHKERRQ(ierr); 28822d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->rmap);CHKERRQ(ierr); 28832d033e1fSHong Zhang ierr = PetscLayoutDestroy(&C->cmap);CHKERRQ(ierr); 28842d033e1fSHong Zhang ierr = PetscHeaderDestroy(&C);CHKERRQ(ierr); 2885682e4c99SStefano Zampini } 28862d033e1fSHong Zhang } else { 28872d033e1fSHong Zhang ierr = MatDestroy(&C);CHKERRQ(ierr); 28882d033e1fSHong Zhang } 28892d033e1fSHong Zhang } 289086e85357SHong Zhang 289163a75b2aSHong Zhang /* Destroy Dummy submatrices created for reuse */ 289263a75b2aSHong Zhang ierr = MatDestroySubMatrices_Dummy(n,mat);CHKERRQ(ierr); 289363a75b2aSHong Zhang 28942d033e1fSHong Zhang ierr = PetscFree(*mat);CHKERRQ(ierr); 28952d033e1fSHong Zhang PetscFunctionReturn(0); 28962d033e1fSHong Zhang } 28972d033e1fSHong Zhang 28987dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2899cddf8d76SBarry Smith { 2900dfbe8321SBarry Smith PetscErrorCode ierr; 290197f1f81fSBarry Smith PetscInt i; 2902cddf8d76SBarry Smith 29033a40ed3dSBarry Smith PetscFunctionBegin; 2904cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2905df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2906cddf8d76SBarry Smith } 2907cddf8d76SBarry Smith 2908cddf8d76SBarry Smith for (i=0; i<n; i++) { 29097dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2910cddf8d76SBarry Smith } 29113a40ed3dSBarry Smith PetscFunctionReturn(0); 2912cddf8d76SBarry Smith } 2913cddf8d76SBarry Smith 291497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 29154dcbc457SBarry Smith { 2916e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29176849ba73SBarry Smith PetscErrorCode ierr; 29185d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 29195d0c19d7SBarry Smith const PetscInt *idx; 292097f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2921f1af5d2fSBarry Smith PetscBT table; 2922bbd702dbSSatish Balay 29233a40ed3dSBarry Smith PetscFunctionBegin; 2924d0f46423SBarry Smith m = A->rmap->n; 2925e4d965acSSatish Balay ai = a->i; 2926bfeeae90SHong Zhang aj = a->j; 29278a047759SSatish Balay 2928e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 292906763907SSatish Balay 2930854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 293153b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 293206763907SSatish Balay 2933e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2934b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2935e4d965acSSatish Balay isz = 0; 29366831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2937e4d965acSSatish Balay 2938e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 29394dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2940b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2941e4d965acSSatish Balay 2942dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2943e4d965acSSatish Balay for (j=0; j<n; ++j) { 29442205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 29454dcbc457SBarry Smith } 294606763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 29476bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2948e4d965acSSatish Balay 294904a348a9SBarry Smith k = 0; 295004a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 295104a348a9SBarry Smith n = isz; 295206763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2953e4d965acSSatish Balay row = nidx[k]; 2954e4d965acSSatish Balay start = ai[row]; 2955e4d965acSSatish Balay end = ai[row+1]; 295604a348a9SBarry Smith for (l = start; l<end; l++) { 2957efb16452SHong Zhang val = aj[l]; 29582205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2959e4d965acSSatish Balay } 2960e4d965acSSatish Balay } 2961e4d965acSSatish Balay } 296270b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2963e4d965acSSatish Balay } 296494bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2965606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 29663a40ed3dSBarry Smith PetscFunctionReturn(0); 29674dcbc457SBarry Smith } 296817ab2063SBarry Smith 29690513a670SBarry Smith /* -------------------------------------------------------------- */ 2970dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 29710513a670SBarry Smith { 29720513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 29736849ba73SBarry Smith PetscErrorCode ierr; 29743b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 29755d0c19d7SBarry Smith const PetscInt *row,*col; 29765d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 297756cd22aeSBarry Smith IS icolp,irowp; 29780298fd71SBarry Smith PetscInt *cwork = NULL; 29790298fd71SBarry Smith PetscScalar *vwork = NULL; 29800513a670SBarry Smith 29813a40ed3dSBarry Smith PetscFunctionBegin; 29824c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 298356cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 29844c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 298556cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 29860513a670SBarry Smith 29870513a670SBarry Smith /* determine lengths of permuted rows */ 2988854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 29892205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2990ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2991f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 299233d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 29937adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2994ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2995606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 29960513a670SBarry Smith 2997785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 29980513a670SBarry Smith for (i=0; i<m; i++) { 299932ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30002205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 3001cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 300232ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 30030513a670SBarry Smith } 3004606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 30052205254eSKarl Rupp 30063c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 30072205254eSKarl Rupp 30088c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3009b470e4b4SRichard Tran Mills ierr = MatBindToCPU(*B,A->boundtocpu);CHKERRQ(ierr); 30109fe5e383SStefano Zampini #endif 30110513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 30120513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 301356cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 301456cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 30156bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 30166bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 30176768869dSprj- if (rowp == colp) { 30186768869dSprj- if (A->symmetric) { 30196768869dSprj- ierr = MatSetOption(*B,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 30206768869dSprj- } 30216768869dSprj- if (A->hermitian) { 30226768869dSprj- ierr = MatSetOption(*B,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); 30236768869dSprj- } 30246768869dSprj- } 30253a40ed3dSBarry Smith PetscFunctionReturn(0); 30260513a670SBarry Smith } 30270513a670SBarry Smith 3028dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 3029cb5b572fSBarry Smith { 3030dfbe8321SBarry Smith PetscErrorCode ierr; 3031cb5b572fSBarry Smith 3032cb5b572fSBarry Smith PetscFunctionBegin; 303333f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 303433f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 3035be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3036be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 3037be6bf707SBarry Smith 30384d805d7cSStefano 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]); 3039580bdb30SBarry Smith ierr = PetscArraycpy(b->a,a->a,a->i[A->rmap->n]);CHKERRQ(ierr); 3040cdc753b6SBarry Smith ierr = PetscObjectStateIncrease((PetscObject)B);CHKERRQ(ierr); 3041cb5b572fSBarry Smith } else { 3042cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 3043cb5b572fSBarry Smith } 3044cb5b572fSBarry Smith PetscFunctionReturn(0); 3045cb5b572fSBarry Smith } 3046cb5b572fSBarry Smith 30474994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 3048273d9f13SBarry Smith { 3049dfbe8321SBarry Smith PetscErrorCode ierr; 3050273d9f13SBarry Smith 3051273d9f13SBarry Smith PetscFunctionBegin; 3052f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,NULL);CHKERRQ(ierr); 3053273d9f13SBarry Smith PetscFunctionReturn(0); 3054273d9f13SBarry Smith } 3055273d9f13SBarry Smith 3056f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 30576c0721eeSBarry Smith { 30586c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 30596e111a19SKarl Rupp 30606c0721eeSBarry Smith PetscFunctionBegin; 30616c0721eeSBarry Smith *array = a->a; 30626c0721eeSBarry Smith PetscFunctionReturn(0); 30636c0721eeSBarry Smith } 30646c0721eeSBarry Smith 3065f38c1e66SStefano Zampini PETSC_INTERN PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 30666c0721eeSBarry Smith { 30676c0721eeSBarry Smith PetscFunctionBegin; 3068f38c1e66SStefano Zampini *array = NULL; 30696c0721eeSBarry Smith PetscFunctionReturn(0); 30706c0721eeSBarry Smith } 3071273d9f13SBarry Smith 30728229c054SShri Abhyankar /* 30738229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 30748229c054SShri Abhyankar have different nonzero structure. 30758229c054SShri Abhyankar */ 3076b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 3077ec7775f6SShri Abhyankar { 3078b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 3079ec7775f6SShri Abhyankar 3080ec7775f6SShri Abhyankar PetscFunctionBegin; 3081ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 3082ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 3083b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 3084b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 3085b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 30868af7cee1SJed Brown nnz[i] = 0; 30878af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 3088b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 3089b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 30908af7cee1SJed Brown nnz[i]++; 30918af7cee1SJed Brown } 30928af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 3093ec7775f6SShri Abhyankar } 3094ec7775f6SShri Abhyankar PetscFunctionReturn(0); 3095ec7775f6SShri Abhyankar } 3096ec7775f6SShri Abhyankar 3097b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 3098b264fe52SHong Zhang { 3099b264fe52SHong Zhang PetscInt m = Y->rmap->N; 3100b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 3101b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 3102b264fe52SHong Zhang PetscErrorCode ierr; 3103b264fe52SHong Zhang 3104b264fe52SHong Zhang PetscFunctionBegin; 3105b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 3106b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 3107b264fe52SHong Zhang PetscFunctionReturn(0); 3108b264fe52SHong Zhang } 3109b264fe52SHong Zhang 3110f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 3111ac90fabeSBarry Smith { 3112dfbe8321SBarry Smith PetscErrorCode ierr; 3113ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 3114ac90fabeSBarry Smith 3115ac90fabeSBarry Smith PetscFunctionBegin; 3116d60b7d5cSBarry Smith if (str == UNKNOWN_NONZERO_PATTERN) { 311781fa06acSBarry Smith if (x->nz == y->nz) { 311881fa06acSBarry Smith PetscBool e; 311981fa06acSBarry Smith ierr = PetscArraycmp(x->i,y->i,Y->rmap->n+1,&e);CHKERRQ(ierr); 312081fa06acSBarry Smith if (e) { 312181fa06acSBarry Smith ierr = PetscArraycmp(x->j,y->j,y->nz,&e);CHKERRQ(ierr); 312281fa06acSBarry Smith if (e) { 312381fa06acSBarry Smith str = SAME_NONZERO_PATTERN; 312481fa06acSBarry Smith } 312581fa06acSBarry Smith } 312681fa06acSBarry Smith } 312781fa06acSBarry Smith } 3128ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 3129f4df32b1SMatthew Knepley PetscScalar alpha = a; 313081fa06acSBarry Smith PetscBLASInt one = 1,bnz; 313181fa06acSBarry Smith 313281fa06acSBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 31338b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 3134acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 3135a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 313681fa06acSBarry Smith /* the MatAXPY_Basic* subroutines calls MatAssembly, so the matrix on the GPU will be updated */ 31378c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3138c70f7ee4SJunchao Zhang if (Y->offloadmask != PETSC_OFFLOAD_UNALLOCATED) { 3139c70f7ee4SJunchao Zhang Y->offloadmask = PETSC_OFFLOAD_CPU; 3140e2cf4d64SStefano Zampini } 3141e2cf4d64SStefano Zampini #endif 3142ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 3143ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 3144ac90fabeSBarry Smith } else { 31458229c054SShri Abhyankar Mat B; 31468229c054SShri Abhyankar PetscInt *nnz; 3147785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 3148ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 3149bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 315081fa06acSBarry Smith ierr = MatSetLayouts(B,Y->rmap,Y->cmap);CHKERRQ(ierr); 3151176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 31528229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 3153ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 3154ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 315528be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 31568229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 3157ac90fabeSBarry Smith } 3158ac90fabeSBarry Smith PetscFunctionReturn(0); 3159ac90fabeSBarry Smith } 3160ac90fabeSBarry Smith 31617087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 3162354c94deSBarry Smith { 3163354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 3164354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3165354c94deSBarry Smith PetscInt i,nz; 3166354c94deSBarry Smith PetscScalar *a; 3167354c94deSBarry Smith 3168354c94deSBarry Smith PetscFunctionBegin; 3169354c94deSBarry Smith nz = aij->nz; 3170354c94deSBarry Smith a = aij->a; 31712205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 31728c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 3173c70f7ee4SJunchao Zhang if (mat->offloadmask != PETSC_OFFLOAD_UNALLOCATED) mat->offloadmask = PETSC_OFFLOAD_CPU; 3174e2cf4d64SStefano Zampini #endif 3175354c94deSBarry Smith #else 3176354c94deSBarry Smith PetscFunctionBegin; 3177354c94deSBarry Smith #endif 3178354c94deSBarry Smith PetscFunctionReturn(0); 3179354c94deSBarry Smith } 3180354c94deSBarry Smith 3181985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3182e34fafa9SBarry Smith { 3183e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3184e34fafa9SBarry Smith PetscErrorCode ierr; 3185d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3186e34fafa9SBarry Smith PetscReal atmp; 3187985db425SBarry Smith PetscScalar *x; 3188e34fafa9SBarry Smith MatScalar *aa; 3189e34fafa9SBarry Smith 3190e34fafa9SBarry Smith PetscFunctionBegin; 3191e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3192e34fafa9SBarry Smith aa = a->a; 3193e34fafa9SBarry Smith ai = a->i; 3194e34fafa9SBarry Smith aj = a->j; 3195e34fafa9SBarry Smith 3196985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3197475b8b61SHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3198e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3199e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3200e34fafa9SBarry Smith for (i=0; i<m; i++) { 3201e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 3202e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 3203985db425SBarry Smith atmp = PetscAbsScalar(*aa); 3204985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 3205985db425SBarry Smith aa++; aj++; 3206985db425SBarry Smith } 3207985db425SBarry Smith } 3208475b8b61SHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3209985db425SBarry Smith PetscFunctionReturn(0); 3210985db425SBarry Smith } 3211985db425SBarry Smith 3212985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3213985db425SBarry Smith { 3214985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3215985db425SBarry Smith PetscErrorCode ierr; 3216d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 3217985db425SBarry Smith PetscScalar *x; 3218985db425SBarry Smith MatScalar *aa; 3219985db425SBarry Smith 3220985db425SBarry Smith PetscFunctionBegin; 3221e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3222985db425SBarry Smith aa = a->a; 3223985db425SBarry Smith ai = a->i; 3224985db425SBarry Smith aj = a->j; 3225985db425SBarry Smith 3226985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3227fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3228985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3229e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3230985db425SBarry Smith for (i=0; i<m; i++) { 3231985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3232d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3233985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3234985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 3235985db425SBarry Smith x[i] = 0.0; 3236985db425SBarry Smith if (idx) { 3237985db425SBarry Smith for (j=0; j<ncols; j++) { /* find first implicit 0.0 in the row */ 3238985db425SBarry Smith if (aj[j] > j) { 3239985db425SBarry Smith idx[i] = j; 3240985db425SBarry Smith break; 3241985db425SBarry Smith } 3242985db425SBarry Smith } 32431a254869SHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 32441a254869SHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3245985db425SBarry Smith } 3246985db425SBarry Smith } 3247985db425SBarry Smith for (j=0; j<ncols; j++) { 3248985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3249985db425SBarry Smith aa++; aj++; 3250985db425SBarry Smith } 3251985db425SBarry Smith } 3252fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3253985db425SBarry Smith PetscFunctionReturn(0); 3254985db425SBarry Smith } 3255985db425SBarry Smith 3256c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3257c87e5d42SMatthew Knepley { 3258c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3259c87e5d42SMatthew Knepley PetscErrorCode ierr; 3260c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 32614e879edeSHong Zhang PetscScalar *x,*aa; 3262c87e5d42SMatthew Knepley 3263c87e5d42SMatthew Knepley PetscFunctionBegin; 3264c87e5d42SMatthew Knepley aa = a->a; 3265c87e5d42SMatthew Knepley ai = a->i; 3266c87e5d42SMatthew Knepley aj = a->j; 3267c87e5d42SMatthew Knepley 3268c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 3269f07e67edSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3270c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3271f07e67edSHong Zhang if (n != m) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %D vs. %D rows", m, n); 3272c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 3273c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 3274f07e67edSHong Zhang if (ncols == A->cmap->n) { /* row is dense */ 3275f07e67edSHong Zhang x[i] = *aa; if (idx) idx[i] = 0; 3276f07e67edSHong Zhang } else { /* row is sparse so already KNOW minimum is 0.0 or higher */ 3277f07e67edSHong Zhang x[i] = 0.0; 3278f07e67edSHong Zhang if (idx) { /* find first implicit 0.0 in the row */ 3279289a08f5SMatthew Knepley for (j=0; j<ncols; j++) { 3280f07e67edSHong Zhang if (aj[j] > j) { 3281f07e67edSHong Zhang idx[i] = j; 32822205254eSKarl Rupp break; 32832205254eSKarl Rupp } 3284289a08f5SMatthew Knepley } 3285f07e67edSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3286f07e67edSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3287f07e67edSHong Zhang } 3288289a08f5SMatthew Knepley } 3289c87e5d42SMatthew Knepley for (j=0; j<ncols; j++) { 3290f07e67edSHong Zhang if (PetscAbsScalar(x[i]) > PetscAbsScalar(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3291c87e5d42SMatthew Knepley aa++; aj++; 3292c87e5d42SMatthew Knepley } 3293c87e5d42SMatthew Knepley } 3294f07e67edSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3295c87e5d42SMatthew Knepley PetscFunctionReturn(0); 3296c87e5d42SMatthew Knepley } 3297c87e5d42SMatthew Knepley 3298985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 3299985db425SBarry Smith { 3300985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3301985db425SBarry Smith PetscErrorCode ierr; 3302d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 3303d9ca1df4SBarry Smith const PetscInt *ai,*aj; 3304985db425SBarry Smith PetscScalar *x; 3305d9ca1df4SBarry Smith const MatScalar *aa; 3306985db425SBarry Smith 3307985db425SBarry Smith PetscFunctionBegin; 3308e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 3309985db425SBarry Smith aa = a->a; 3310985db425SBarry Smith ai = a->i; 3311985db425SBarry Smith aj = a->j; 3312985db425SBarry Smith 3313985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 3314fa213d2fSHong Zhang ierr = VecGetArrayWrite(v,&x);CHKERRQ(ierr); 3315985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 3316f07e67edSHong Zhang if (n != m) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 3317985db425SBarry Smith for (i=0; i<m; i++) { 3318985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 3319d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 3320985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 3321985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 3322985db425SBarry Smith x[i] = 0.0; 3323985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 3324985db425SBarry Smith for (j=0; j<ncols; j++) { 3325985db425SBarry Smith if (aj[j] > j) { 3326985db425SBarry Smith idx[i] = j; 3327985db425SBarry Smith break; 3328985db425SBarry Smith } 3329985db425SBarry Smith } 3330fa213d2fSHong Zhang /* in case first implicit 0.0 in the row occurs at ncols-th column */ 3331fa213d2fSHong Zhang if (j==ncols && j < A->cmap->n) idx[i] = j; 3332985db425SBarry Smith } 3333985db425SBarry Smith } 3334985db425SBarry Smith for (j=0; j<ncols; j++) { 3335985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 3336985db425SBarry Smith aa++; aj++; 3337e34fafa9SBarry Smith } 3338e34fafa9SBarry Smith } 3339fa213d2fSHong Zhang ierr = VecRestoreArrayWrite(v,&x);CHKERRQ(ierr); 3340e34fafa9SBarry Smith PetscFunctionReturn(0); 3341e34fafa9SBarry Smith } 3342bbead8a2SBarry Smith 3343713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 3344bbead8a2SBarry Smith { 3345bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 3346bbead8a2SBarry Smith PetscErrorCode ierr; 334733d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 3348bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 33490da83c2eSBarry Smith const PetscReal shift = 0.0; 33501a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 3351bbead8a2SBarry Smith 3352bbead8a2SBarry Smith PetscFunctionBegin; 3353a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 33544a0d0026SBarry Smith if (a->ibdiagvalid) { 33554a0d0026SBarry Smith if (values) *values = a->ibdiag; 33564a0d0026SBarry Smith PetscFunctionReturn(0); 33574a0d0026SBarry Smith } 3358bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 3359bbead8a2SBarry Smith if (!a->ibdiag) { 3360785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 33613bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 3362bbead8a2SBarry Smith } 3363bbead8a2SBarry Smith diag = a->ibdiag; 3364bbead8a2SBarry Smith if (values) *values = a->ibdiag; 3365bbead8a2SBarry Smith /* factor and invert each block */ 3366bbead8a2SBarry Smith switch (bs) { 3367bbead8a2SBarry Smith case 1: 3368bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3369bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 3370ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 3371ec1892c8SHong Zhang if (allowzeropivot) { 33727b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 33737b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 33747b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 33757b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 33767b6c816cSBarry 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); 3377ec1892c8SHong Zhang } 3378bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 3379bbead8a2SBarry Smith } 3380bbead8a2SBarry Smith break; 3381bbead8a2SBarry Smith case 2: 3382bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3383bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 3384bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 3385a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33867b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 338796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 3388bbead8a2SBarry Smith diag += 4; 3389bbead8a2SBarry Smith } 3390bbead8a2SBarry Smith break; 3391bbead8a2SBarry Smith case 3: 3392bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3393bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 3394bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 3395a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 33967b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 339796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 3398bbead8a2SBarry Smith diag += 9; 3399bbead8a2SBarry Smith } 3400bbead8a2SBarry Smith break; 3401bbead8a2SBarry Smith case 4: 3402bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3403bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 3404bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 3405a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34067b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 340796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 3408bbead8a2SBarry Smith diag += 16; 3409bbead8a2SBarry Smith } 3410bbead8a2SBarry Smith break; 3411bbead8a2SBarry Smith case 5: 3412bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3413bbead8a2SBarry 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; 3414bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 3415a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34167b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 341796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 3418bbead8a2SBarry Smith diag += 25; 3419bbead8a2SBarry Smith } 3420bbead8a2SBarry Smith break; 3421bbead8a2SBarry Smith case 6: 3422bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3423bbead8a2SBarry 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; 3424bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 3425a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34267b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 342796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 3428bbead8a2SBarry Smith diag += 36; 3429bbead8a2SBarry Smith } 3430bbead8a2SBarry Smith break; 3431bbead8a2SBarry Smith case 7: 3432bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3433bbead8a2SBarry 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; 3434bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 3435a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34367b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 343796b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3438bbead8a2SBarry Smith diag += 49; 3439bbead8a2SBarry Smith } 3440bbead8a2SBarry Smith break; 3441bbead8a2SBarry Smith default: 3442dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3443bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3444bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3445bbead8a2SBarry Smith IJ[j] = bs*i + j; 3446bbead8a2SBarry Smith } 3447bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 34485f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 34497b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 345096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3451bbead8a2SBarry Smith diag += bs2; 3452bbead8a2SBarry Smith } 3453bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3454bbead8a2SBarry Smith } 3455bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3456bbead8a2SBarry Smith PetscFunctionReturn(0); 3457bbead8a2SBarry Smith } 3458bbead8a2SBarry Smith 345973a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 346073a71a0fSBarry Smith { 346173a71a0fSBarry Smith PetscErrorCode ierr; 346273a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 346373a71a0fSBarry Smith PetscScalar a; 346473a71a0fSBarry Smith PetscInt m,n,i,j,col; 346573a71a0fSBarry Smith 346673a71a0fSBarry Smith PetscFunctionBegin; 346773a71a0fSBarry Smith if (!x->assembled) { 346873a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 346973a71a0fSBarry Smith for (i=0; i<m; i++) { 347073a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 347173a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 347273a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 347373a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 347473a71a0fSBarry Smith } 347573a71a0fSBarry Smith } 3476e2ce353bSJunchao Zhang } else { 3477e2ce353bSJunchao Zhang for (i=0; i<aij->nz; i++) {ierr = PetscRandomGetValue(rctx,aij->a+i);CHKERRQ(ierr);} 3478e2ce353bSJunchao Zhang } 347973a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 348073a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 348173a71a0fSBarry Smith PetscFunctionReturn(0); 348273a71a0fSBarry Smith } 348373a71a0fSBarry Smith 3484679944adSJunchao Zhang /* Like MatSetRandom_SeqAIJ, but do not set values on columns in range of [low, high) */ 3485679944adSJunchao Zhang PetscErrorCode MatSetRandomSkipColumnRange_SeqAIJ_Private(Mat x,PetscInt low,PetscInt high,PetscRandom rctx) 3486679944adSJunchao Zhang { 3487679944adSJunchao Zhang PetscErrorCode ierr; 3488679944adSJunchao Zhang Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 3489679944adSJunchao Zhang PetscScalar a; 3490679944adSJunchao Zhang PetscInt m,n,i,j,col,nskip; 3491679944adSJunchao Zhang 3492679944adSJunchao Zhang PetscFunctionBegin; 3493679944adSJunchao Zhang nskip = high - low; 3494679944adSJunchao Zhang ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 3495679944adSJunchao Zhang n -= nskip; /* shrink number of columns where nonzeros can be set */ 3496679944adSJunchao Zhang for (i=0; i<m; i++) { 3497679944adSJunchao Zhang for (j=0; j<aij->imax[i]; j++) { 3498679944adSJunchao Zhang ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 3499679944adSJunchao Zhang col = (PetscInt)(n*PetscRealPart(a)); 3500679944adSJunchao Zhang if (col >= low) col += nskip; /* shift col rightward to skip the hole */ 3501679944adSJunchao Zhang ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 3502679944adSJunchao Zhang } 3503e2ce353bSJunchao Zhang } 3504679944adSJunchao Zhang ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3505679944adSJunchao Zhang ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3506679944adSJunchao Zhang PetscFunctionReturn(0); 3507679944adSJunchao Zhang } 3508679944adSJunchao Zhang 3509679944adSJunchao Zhang 3510682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 35110a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3512cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3513cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3514cb5b572fSBarry Smith MatMult_SeqAIJ, 351597304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 35167c922b88SBarry Smith MatMultTranspose_SeqAIJ, 35177c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3518f4259b30SLisandro Dalcin NULL, 3519f4259b30SLisandro Dalcin NULL, 3520f4259b30SLisandro Dalcin NULL, 3521f4259b30SLisandro Dalcin /* 10*/ NULL, 3522cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3523f4259b30SLisandro Dalcin NULL, 352441f059aeSBarry Smith MatSOR_SeqAIJ, 352591e9d3e2SHong Zhang MatTranspose_SeqAIJ, 352697304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3527cb5b572fSBarry Smith MatEqual_SeqAIJ, 3528cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3529cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3530cb5b572fSBarry Smith MatNorm_SeqAIJ, 3531f4259b30SLisandro Dalcin /* 20*/ NULL, 3532cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3533cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3534cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3535d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3536f4259b30SLisandro Dalcin NULL, 3537f4259b30SLisandro Dalcin NULL, 3538f4259b30SLisandro Dalcin NULL, 3539f4259b30SLisandro Dalcin NULL, 35404994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3541f4259b30SLisandro Dalcin NULL, 3542f4259b30SLisandro Dalcin NULL, 3543f4259b30SLisandro Dalcin NULL, 3544f4259b30SLisandro Dalcin NULL, 3545d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3546f4259b30SLisandro Dalcin NULL, 3547f4259b30SLisandro Dalcin NULL, 3548cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3549f4259b30SLisandro Dalcin NULL, 3550d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 35517dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3552cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3553cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3554cb5b572fSBarry Smith MatCopy_SeqAIJ, 3555d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3556cb5b572fSBarry Smith MatScale_SeqAIJ, 35577d68702bSBarry Smith MatShift_SeqAIJ, 355879299369SBarry Smith MatDiagonalSet_SeqAIJ, 35596e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 356073a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 35613b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 35623b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 35633b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3564a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 356593dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3566f4259b30SLisandro Dalcin NULL, 3567f4259b30SLisandro Dalcin NULL, 3568cda55fadSBarry Smith MatPermute_SeqAIJ, 3569f4259b30SLisandro Dalcin NULL, 3570f4259b30SLisandro Dalcin /* 59*/ NULL, 3571b9b97703SBarry Smith MatDestroy_SeqAIJ, 3572b9b97703SBarry Smith MatView_SeqAIJ, 3573f4259b30SLisandro Dalcin NULL, 3574f4259b30SLisandro Dalcin NULL, 3575f4259b30SLisandro Dalcin /* 64*/ NULL, 3576321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3577f4259b30SLisandro Dalcin NULL, 3578f4259b30SLisandro Dalcin NULL, 3579f4259b30SLisandro Dalcin NULL, 3580d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3581c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3582f4259b30SLisandro Dalcin NULL, 3583f4259b30SLisandro Dalcin NULL, 3584f4259b30SLisandro Dalcin NULL, 3585f4259b30SLisandro Dalcin /* 74*/ NULL, 35863acb8795SBarry Smith MatFDColoringApply_AIJ, 3587f4259b30SLisandro Dalcin NULL, 3588f4259b30SLisandro Dalcin NULL, 3589f4259b30SLisandro Dalcin NULL, 35906ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 3591f4259b30SLisandro Dalcin NULL, 3592f4259b30SLisandro Dalcin NULL, 3593f4259b30SLisandro Dalcin NULL, 3594bc011b1eSHong Zhang MatLoad_SeqAIJ, 3595d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 35961cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 3597f4259b30SLisandro Dalcin NULL, 3598f4259b30SLisandro Dalcin NULL, 3599f4259b30SLisandro Dalcin NULL, 3600f4259b30SLisandro Dalcin /* 89*/ NULL, 3601f4259b30SLisandro Dalcin NULL, 360226be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3603f4259b30SLisandro Dalcin NULL, 3604f4259b30SLisandro Dalcin NULL, 36058fa4b5a6SHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ_SparseAxpy, 3606f4259b30SLisandro Dalcin NULL, 3607f4259b30SLisandro Dalcin NULL, 36086fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 3609f4259b30SLisandro Dalcin NULL, 36104222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqAIJ, 3611f4259b30SLisandro Dalcin NULL, 3612f4259b30SLisandro Dalcin NULL, 361387d4246cSBarry Smith MatConjugate_SeqAIJ, 3614f4259b30SLisandro Dalcin NULL, 3615d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 361699cafbc1SBarry Smith MatRealPart_SeqAIJ, 3617f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3618f4259b30SLisandro Dalcin NULL, 3619f4259b30SLisandro Dalcin NULL, 3620cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3621f4259b30SLisandro Dalcin NULL, 36222af78befSBarry Smith MatGetRowMin_SeqAIJ, 3623f4259b30SLisandro Dalcin NULL, 3624599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3625f4259b30SLisandro Dalcin /*114*/ NULL, 3626f4259b30SLisandro Dalcin NULL, 3627f4259b30SLisandro Dalcin NULL, 3628f4259b30SLisandro Dalcin NULL, 3629f4259b30SLisandro Dalcin NULL, 3630f4259b30SLisandro Dalcin /*119*/ NULL, 3631f4259b30SLisandro Dalcin NULL, 3632f4259b30SLisandro Dalcin NULL, 3633f4259b30SLisandro Dalcin NULL, 3634b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 36350716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3636bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 363737868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 36380da83c2eSBarry Smith MatInvertVariableBlockDiagonal_SeqAIJ, 3639f4259b30SLisandro Dalcin NULL, 3640f4259b30SLisandro Dalcin /*129*/ NULL, 3641f4259b30SLisandro Dalcin NULL, 3642f4259b30SLisandro Dalcin NULL, 364375648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3644b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3645b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 36462b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 3647f4259b30SLisandro Dalcin NULL, 3648f4259b30SLisandro Dalcin NULL, 36493964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 3650f4259b30SLisandro Dalcin /*139*/NULL, 3651f4259b30SLisandro Dalcin NULL, 3652f4259b30SLisandro Dalcin NULL, 36533a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 36549c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 36554222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqAIJ, 36564222ddf1SHong Zhang /*145*/MatDestroySubMatrices_SeqAIJ, 3657f4259b30SLisandro Dalcin NULL, 3658f4259b30SLisandro Dalcin NULL 36599e29f15eSvictorle }; 366017ab2063SBarry Smith 36617087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3662bef8e0ddSBarry Smith { 3663bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 366497f1f81fSBarry Smith PetscInt i,nz,n; 3665bef8e0ddSBarry Smith 3666bef8e0ddSBarry Smith PetscFunctionBegin; 3667bef8e0ddSBarry Smith nz = aij->maxnz; 3668d0f46423SBarry Smith n = mat->rmap->n; 3669bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3670bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3671bef8e0ddSBarry Smith } 3672bef8e0ddSBarry Smith aij->nz = nz; 3673bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3674bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3675bef8e0ddSBarry Smith } 3676bef8e0ddSBarry Smith PetscFunctionReturn(0); 3677bef8e0ddSBarry Smith } 3678bef8e0ddSBarry Smith 3679a3bb6f32SFande Kong /* 3680e8b528d9SFande Kong * When a sparse matrix has many zero columns, we should compact them out to save the space 3681a3bb6f32SFande Kong * This happens in MatPtAPSymbolic_MPIAIJ_MPIAIJ_scalable() 3682a3bb6f32SFande Kong * */ 3683a3bb6f32SFande Kong PetscErrorCode MatSeqAIJCompactOutExtraColumns_SeqAIJ(Mat mat, ISLocalToGlobalMapping *mapping) 3684a3bb6f32SFande Kong { 3685a3bb6f32SFande Kong Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 3686a3bb6f32SFande Kong PetscTable gid1_lid1; 3687a3bb6f32SFande Kong PetscTablePosition tpos; 3688*25b670f0SStefano Zampini PetscInt gid,lid,i,ec,nz = aij->nz; 3689*25b670f0SStefano Zampini PetscInt *garray,*jj = aij->j; 3690a3bb6f32SFande Kong PetscErrorCode ierr; 3691a3bb6f32SFande Kong 3692a3bb6f32SFande Kong PetscFunctionBegin; 3693a3bb6f32SFande Kong PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3694a3bb6f32SFande Kong PetscValidPointer(mapping,2); 3695a3bb6f32SFande Kong /* use a table */ 3696a3bb6f32SFande Kong ierr = PetscTableCreate(mat->rmap->n,mat->cmap->N+1,&gid1_lid1);CHKERRQ(ierr); 3697a3bb6f32SFande Kong ec = 0; 3698*25b670f0SStefano Zampini for (i=0; i<nz; i++) { 3699*25b670f0SStefano Zampini PetscInt data,gid1 = jj[i] + 1; 3700a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&data);CHKERRQ(ierr); 3701a3bb6f32SFande Kong if (!data) { 3702a3bb6f32SFande Kong /* one based table */ 3703a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,gid1,++ec,INSERT_VALUES);CHKERRQ(ierr); 3704a3bb6f32SFande Kong } 3705a3bb6f32SFande Kong } 3706a3bb6f32SFande Kong /* form array of columns we need */ 3707a3bb6f32SFande Kong ierr = PetscMalloc1(ec+1,&garray);CHKERRQ(ierr); 3708a3bb6f32SFande Kong ierr = PetscTableGetHeadPosition(gid1_lid1,&tpos);CHKERRQ(ierr); 3709a3bb6f32SFande Kong while (tpos) { 3710a3bb6f32SFande Kong ierr = PetscTableGetNext(gid1_lid1,&tpos,&gid,&lid);CHKERRQ(ierr); 3711a3bb6f32SFande Kong gid--; 3712a3bb6f32SFande Kong lid--; 3713a3bb6f32SFande Kong garray[lid] = gid; 3714a3bb6f32SFande Kong } 3715a3bb6f32SFande Kong ierr = PetscSortInt(ec,garray);CHKERRQ(ierr); /* sort, and rebuild */ 3716a3bb6f32SFande Kong ierr = PetscTableRemoveAll(gid1_lid1);CHKERRQ(ierr); 3717a3bb6f32SFande Kong for (i=0; i<ec; i++) { 3718a3bb6f32SFande Kong ierr = PetscTableAdd(gid1_lid1,garray[i]+1,i+1,INSERT_VALUES);CHKERRQ(ierr); 3719a3bb6f32SFande Kong } 3720a3bb6f32SFande Kong /* compact out the extra columns in B */ 3721*25b670f0SStefano Zampini for (i=0; i<nz; i++) { 3722*25b670f0SStefano Zampini PetscInt gid1 = jj[i] + 1; 3723a3bb6f32SFande Kong ierr = PetscTableFind(gid1_lid1,gid1,&lid);CHKERRQ(ierr); 3724a3bb6f32SFande Kong lid--; 3725*25b670f0SStefano Zampini jj[i] = lid; 3726a3bb6f32SFande Kong } 3727ca5434daSLawrence Mitchell ierr = PetscLayoutDestroy(&mat->cmap);CHKERRQ(ierr); 3728a3bb6f32SFande Kong ierr = PetscTableDestroy(&gid1_lid1);CHKERRQ(ierr); 3729*25b670f0SStefano Zampini ierr = PetscLayoutCreateFromSizes(PetscObjectComm((PetscObject)mat),ec,ec,1,&mat->cmap);CHKERRQ(ierr); 3730a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,mat->cmap->bs,mat->cmap->n,garray,PETSC_OWN_POINTER,mapping);CHKERRQ(ierr); 3731a3bb6f32SFande Kong ierr = ISLocalToGlobalMappingSetType(*mapping,ISLOCALTOGLOBALMAPPINGHASH);CHKERRQ(ierr); 3732a3bb6f32SFande Kong PetscFunctionReturn(0); 3733a3bb6f32SFande Kong } 3734a3bb6f32SFande Kong 3735bef8e0ddSBarry Smith /*@ 3736bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3737bef8e0ddSBarry Smith in the matrix. 3738bef8e0ddSBarry Smith 3739bef8e0ddSBarry Smith Input Parameters: 3740bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3741bef8e0ddSBarry Smith - indices - the column indices 3742bef8e0ddSBarry Smith 374315091d37SBarry Smith Level: advanced 374415091d37SBarry Smith 3745bef8e0ddSBarry Smith Notes: 3746bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3747bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3748bef8e0ddSBarry Smith of the MatSetValues() operation. 3749bef8e0ddSBarry Smith 3750bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3751d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3752bef8e0ddSBarry Smith 3753bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3754bef8e0ddSBarry Smith 3755b9617806SBarry Smith The indices should start with zero, not one. 3756b9617806SBarry Smith 3757bef8e0ddSBarry Smith @*/ 37587087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3759bef8e0ddSBarry Smith { 37604ac538c5SBarry Smith PetscErrorCode ierr; 3761bef8e0ddSBarry Smith 3762bef8e0ddSBarry Smith PetscFunctionBegin; 37630700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 37644482741eSBarry Smith PetscValidPointer(indices,2); 37654ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3766bef8e0ddSBarry Smith PetscFunctionReturn(0); 3767bef8e0ddSBarry Smith } 3768bef8e0ddSBarry Smith 3769be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3770be6bf707SBarry Smith 37717087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3772be6bf707SBarry Smith { 3773be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 37746849ba73SBarry Smith PetscErrorCode ierr; 3775d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3776be6bf707SBarry Smith 3777be6bf707SBarry Smith PetscFunctionBegin; 3778169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3779be6bf707SBarry Smith 3780be6bf707SBarry Smith /* allocate space for values if not already there */ 3781be6bf707SBarry Smith if (!aij->saved_values) { 3782854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 37833bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3784be6bf707SBarry Smith } 3785be6bf707SBarry Smith 3786be6bf707SBarry Smith /* copy values over */ 3787580bdb30SBarry Smith ierr = PetscArraycpy(aij->saved_values,aij->a,nz);CHKERRQ(ierr); 3788be6bf707SBarry Smith PetscFunctionReturn(0); 3789be6bf707SBarry Smith } 3790be6bf707SBarry Smith 3791be6bf707SBarry Smith /*@ 3792be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3793be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3794be6bf707SBarry Smith nonlinear portion. 3795be6bf707SBarry Smith 3796be6bf707SBarry Smith Collect on Mat 3797be6bf707SBarry Smith 3798be6bf707SBarry Smith Input Parameters: 37990e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3800be6bf707SBarry Smith 380115091d37SBarry Smith Level: advanced 380215091d37SBarry Smith 3803be6bf707SBarry Smith Common Usage, with SNESSolve(): 3804be6bf707SBarry Smith $ Create Jacobian matrix 3805be6bf707SBarry Smith $ Set linear terms into matrix 3806be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3807be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3808be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3809512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3810be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3811be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3812be6bf707SBarry Smith $ In your Jacobian routine 3813be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3814be6bf707SBarry Smith $ Set nonlinear terms in matrix 3815be6bf707SBarry Smith 3816be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3817be6bf707SBarry Smith $ // build linear portion of Jacobian 3818512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3819be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3820be6bf707SBarry Smith $ loop over nonlinear iterations 3821be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3822be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3823be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3824be6bf707SBarry Smith $ Solve linear system with Jacobian 3825be6bf707SBarry Smith $ endloop 3826be6bf707SBarry Smith 3827be6bf707SBarry Smith Notes: 3828be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3829512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3830be6bf707SBarry Smith calling this routine. 3831be6bf707SBarry Smith 38320c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 38330c468ba9SBarry Smith and does not allocated additional space. 38340c468ba9SBarry Smith 3835be6bf707SBarry Smith .seealso: MatRetrieveValues() 3836be6bf707SBarry Smith 3837be6bf707SBarry Smith @*/ 38387087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3839be6bf707SBarry Smith { 38404ac538c5SBarry Smith PetscErrorCode ierr; 3841be6bf707SBarry Smith 3842be6bf707SBarry Smith PetscFunctionBegin; 38430700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3844e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3845e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38464ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3847be6bf707SBarry Smith PetscFunctionReturn(0); 3848be6bf707SBarry Smith } 3849be6bf707SBarry Smith 38507087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3851be6bf707SBarry Smith { 3852be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 38536849ba73SBarry Smith PetscErrorCode ierr; 3854d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3855be6bf707SBarry Smith 3856be6bf707SBarry Smith PetscFunctionBegin; 3857169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3858f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3859be6bf707SBarry Smith /* copy values over */ 3860580bdb30SBarry Smith ierr = PetscArraycpy(aij->a,aij->saved_values,nz);CHKERRQ(ierr); 3861be6bf707SBarry Smith PetscFunctionReturn(0); 3862be6bf707SBarry Smith } 3863be6bf707SBarry Smith 3864be6bf707SBarry Smith /*@ 3865be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3866be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3867be6bf707SBarry Smith nonlinear portion. 3868be6bf707SBarry Smith 3869be6bf707SBarry Smith Collect on Mat 3870be6bf707SBarry Smith 3871be6bf707SBarry Smith Input Parameters: 3872386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3873be6bf707SBarry Smith 387415091d37SBarry Smith Level: advanced 387515091d37SBarry Smith 3876be6bf707SBarry Smith .seealso: MatStoreValues() 3877be6bf707SBarry Smith 3878be6bf707SBarry Smith @*/ 38797087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3880be6bf707SBarry Smith { 38814ac538c5SBarry Smith PetscErrorCode ierr; 3882be6bf707SBarry Smith 3883be6bf707SBarry Smith PetscFunctionBegin; 38840700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3885e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3886e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 38874ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3888be6bf707SBarry Smith PetscFunctionReturn(0); 3889be6bf707SBarry Smith } 3890be6bf707SBarry Smith 3891f83d6046SBarry Smith 3892be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 389317ab2063SBarry Smith /*@C 3894682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 38950d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 38966e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 389751c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 38982bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 389917ab2063SBarry Smith 3900d083f849SBarry Smith Collective 3901db81eaa0SLois Curfman McInnes 390217ab2063SBarry Smith Input Parameters: 3903db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 390417ab2063SBarry Smith . m - number of rows 390517ab2063SBarry Smith . n - number of columns 390617ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 390751c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39080298fd71SBarry Smith (possibly different for each row) or NULL 390917ab2063SBarry Smith 391017ab2063SBarry Smith Output Parameter: 3911416022c9SBarry Smith . A - the matrix 391217ab2063SBarry Smith 3913175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3914f6f02116SRichard Tran Mills MatXXXXSetPreallocation() paradigm instead of this routine directly. 3915175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3916175b88e8SBarry Smith 3917b259b22eSLois Curfman McInnes Notes: 391849a6f317SBarry Smith If nnz is given then nz is ignored 391949a6f317SBarry Smith 392017ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 392117ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 39220002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 392344cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 392417ab2063SBarry Smith 392517ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39260298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 39273d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 39286da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 392917ab2063SBarry Smith 3930682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 39314fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3932682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 39336c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 39346c7ebb05SLois Curfman McInnes 39356c7ebb05SLois Curfman McInnes Options Database Keys: 3936698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 39379db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 393817ab2063SBarry Smith 3939027ccd11SLois Curfman McInnes Level: intermediate 3940027ccd11SLois Curfman McInnes 394169b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 394236db0b34SBarry Smith 394317ab2063SBarry Smith @*/ 39447087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 394517ab2063SBarry Smith { 3946dfbe8321SBarry Smith PetscErrorCode ierr; 39476945ee14SBarry Smith 39483a40ed3dSBarry Smith PetscFunctionBegin; 3949f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3950117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3951c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3952d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3953273d9f13SBarry Smith PetscFunctionReturn(0); 3954273d9f13SBarry Smith } 3955273d9f13SBarry Smith 3956273d9f13SBarry Smith /*@C 3957273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3958273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3959273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3960273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3961273d9f13SBarry Smith 3962d083f849SBarry Smith Collective 3963273d9f13SBarry Smith 3964273d9f13SBarry Smith Input Parameters: 39651c4f3114SJed Brown + B - The matrix 3966273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3967273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 39680298fd71SBarry Smith (possibly different for each row) or NULL 3969273d9f13SBarry Smith 3970273d9f13SBarry Smith Notes: 397149a6f317SBarry Smith If nnz is given then nz is ignored 397249a6f317SBarry Smith 3973273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3974273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3975273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3976273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3977273d9f13SBarry Smith 3978273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 39790298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3980273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3981273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3982273d9f13SBarry Smith 3983aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3984aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3985aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3986aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3987aa95bbe8SBarry Smith 3988a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3989a96a251dSBarry Smith entries or columns indices 3990a96a251dSBarry Smith 3991273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3992273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3993273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3994273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3995273d9f13SBarry Smith 3996273d9f13SBarry Smith Options Database Keys: 3997698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 399847b2e64bSBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3999273d9f13SBarry Smith 4000273d9f13SBarry Smith Level: intermediate 4001273d9f13SBarry Smith 400219b08ed1SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo(), 400319b08ed1SBarry Smith MatSeqAIJSetTotalPreallocation() 4004273d9f13SBarry Smith 4005273d9f13SBarry Smith @*/ 40067087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 4007273d9f13SBarry Smith { 40084ac538c5SBarry Smith PetscErrorCode ierr; 4009a23d5eceSKris Buschelman 4010a23d5eceSKris Buschelman PetscFunctionBegin; 40116ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 40126ba663aaSJed Brown PetscValidType(B,1); 40134ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 4014a23d5eceSKris Buschelman PetscFunctionReturn(0); 4015a23d5eceSKris Buschelman } 4016a23d5eceSKris Buschelman 40177087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 4018a23d5eceSKris Buschelman { 4019273d9f13SBarry Smith Mat_SeqAIJ *b; 40202576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 40216849ba73SBarry Smith PetscErrorCode ierr; 402297f1f81fSBarry Smith PetscInt i; 4023273d9f13SBarry Smith 4024273d9f13SBarry Smith PetscFunctionBegin; 40252576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 4026a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 4027c461c341SBarry Smith skipallocation = PETSC_TRUE; 4028c461c341SBarry Smith nz = 0; 4029c461c341SBarry Smith } 403026283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 403126283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4032899cda47SBarry Smith 4033435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 403460e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 4035cf9c20a2SJed Brown if (PetscUnlikelyDebug(nnz)) { 4036d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 403760e0710aSBarry 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]); 403860e0710aSBarry 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); 4039b73539f3SBarry Smith } 4040b73539f3SBarry Smith } 4041b73539f3SBarry Smith 4042273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 40432205254eSKarl Rupp 4044273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 4045273d9f13SBarry Smith 4046ab93d7beSBarry Smith if (!skipallocation) { 40472ee49352SLisandro Dalcin if (!b->imax) { 4048071fcb05SBarry Smith ierr = PetscMalloc1(B->rmap->n,&b->imax);CHKERRQ(ierr); 4049071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4050071fcb05SBarry Smith } 4051071fcb05SBarry Smith if (!b->ilen) { 4052071fcb05SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 4053071fcb05SBarry Smith ierr = PetscCalloc1(B->rmap->n,&b->ilen);CHKERRQ(ierr); 4054071fcb05SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4055071fcb05SBarry Smith } else { 4056071fcb05SBarry Smith ierr = PetscMemzero(b->ilen,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 40572ee49352SLisandro Dalcin } 4058846b4da1SFande Kong if (!b->ipre) { 4059846b4da1SFande Kong ierr = PetscMalloc1(B->rmap->n,&b->ipre);CHKERRQ(ierr); 4060846b4da1SFande Kong ierr = PetscLogObjectMemory((PetscObject)B,B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 4061846b4da1SFande Kong } 4062273d9f13SBarry Smith if (!nnz) { 4063435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 4064c62bd62aSJed Brown else if (nz < 0) nz = 1; 40655d2a9ed1SStefano Zampini nz = PetscMin(nz,B->cmap->n); 4066d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 4067d0f46423SBarry Smith nz = nz*B->rmap->n; 4068273d9f13SBarry Smith } else { 4069c73702f5SBarry Smith PetscInt64 nz64 = 0; 4070c73702f5SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz64 += nnz[i];} 4071c73702f5SBarry Smith ierr = PetscIntCast(nz64,&nz);CHKERRQ(ierr); 4072273d9f13SBarry Smith } 4073ab93d7beSBarry Smith 4074273d9f13SBarry Smith /* allocate the matrix space */ 407553dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 40762ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 4077396832f4SHong Zhang if (B->structure_only) { 40785848002fSHong Zhang ierr = PetscMalloc1(nz,&b->j);CHKERRQ(ierr); 40795848002fSHong Zhang ierr = PetscMalloc1(B->rmap->n+1,&b->i);CHKERRQ(ierr); 4080396832f4SHong Zhang ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*sizeof(PetscInt));CHKERRQ(ierr); 4081396832f4SHong Zhang } else { 4082dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 40833bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 4084396832f4SHong Zhang } 4085bfeeae90SHong Zhang b->i[0] = 0; 4086d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 40875da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 40885da197adSKris Buschelman } 4089396832f4SHong Zhang if (B->structure_only) { 4090396832f4SHong Zhang b->singlemalloc = PETSC_FALSE; 4091396832f4SHong Zhang b->free_a = PETSC_FALSE; 4092396832f4SHong Zhang } else { 4093273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 4094e6b907acSBarry Smith b->free_a = PETSC_TRUE; 4095396832f4SHong Zhang } 4096e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 4097c461c341SBarry Smith } else { 4098e6b907acSBarry Smith b->free_a = PETSC_FALSE; 4099e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 4100c461c341SBarry Smith } 4101273d9f13SBarry Smith 4102846b4da1SFande Kong if (b->ipre && nnz != b->ipre && b->imax) { 4103846b4da1SFande Kong /* reserve user-requested sparsity */ 4104580bdb30SBarry Smith ierr = PetscArraycpy(b->ipre,b->imax,B->rmap->n);CHKERRQ(ierr); 4105846b4da1SFande Kong } 4106846b4da1SFande Kong 4107846b4da1SFande Kong 4108273d9f13SBarry Smith b->nz = 0; 4109273d9f13SBarry Smith b->maxnz = nz; 4110273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 41112205254eSKarl Rupp if (realalloc) { 41122205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 41132205254eSKarl Rupp } 4114cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 4115cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 4116273d9f13SBarry Smith PetscFunctionReturn(0); 4117273d9f13SBarry Smith } 4118273d9f13SBarry Smith 4119846b4da1SFande Kong 4120846b4da1SFande Kong PetscErrorCode MatResetPreallocation_SeqAIJ(Mat A) 4121846b4da1SFande Kong { 4122846b4da1SFande Kong Mat_SeqAIJ *a; 4123a5bbaf83SFande Kong PetscInt i; 4124846b4da1SFande Kong PetscErrorCode ierr; 4125846b4da1SFande Kong 4126846b4da1SFande Kong PetscFunctionBegin; 4127846b4da1SFande Kong PetscValidHeaderSpecific(A,MAT_CLASSID,1); 412814d0e64fSAlex Lindsay 412914d0e64fSAlex Lindsay /* Check local size. If zero, then return */ 413014d0e64fSAlex Lindsay if (!A->rmap->n) PetscFunctionReturn(0); 413114d0e64fSAlex Lindsay 4132846b4da1SFande Kong a = (Mat_SeqAIJ*)A->data; 41332c814fdeSFande Kong /* if no saved info, we error out */ 4134fb4dc15dSAlex Lindsay if (!a->ipre) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"No saved preallocation info \n"); 41352c814fdeSFande Kong 4136fb4dc15dSAlex 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"); 41372c814fdeSFande Kong 4138580bdb30SBarry Smith ierr = PetscArraycpy(a->imax,a->ipre,A->rmap->n);CHKERRQ(ierr); 4139580bdb30SBarry Smith ierr = PetscArrayzero(a->ilen,A->rmap->n);CHKERRQ(ierr); 4140846b4da1SFande Kong a->i[0] = 0; 4141846b4da1SFande Kong for (i=1; i<A->rmap->n+1; i++) { 4142846b4da1SFande Kong a->i[i] = a->i[i-1] + a->imax[i-1]; 4143846b4da1SFande Kong } 4144846b4da1SFande Kong A->preallocated = PETSC_TRUE; 4145846b4da1SFande Kong a->nz = 0; 4146846b4da1SFande Kong a->maxnz = a->i[A->rmap->n]; 4147846b4da1SFande Kong A->info.nz_unneeded = (double)a->maxnz; 4148846b4da1SFande Kong A->was_assembled = PETSC_FALSE; 4149846b4da1SFande Kong A->assembled = PETSC_FALSE; 4150846b4da1SFande Kong PetscFunctionReturn(0); 4151846b4da1SFande Kong } 4152846b4da1SFande Kong 415358d36128SBarry Smith /*@ 4154a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 4155a1661176SMatthew Knepley 4156a1661176SMatthew Knepley Input Parameters: 4157a1661176SMatthew Knepley + B - the matrix 4158a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 4159a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 4160a1661176SMatthew Knepley - v - optional values in the matrix 4161a1661176SMatthew Knepley 4162a1661176SMatthew Knepley Level: developer 4163a1661176SMatthew Knepley 41646a9b8d82SBarry Smith Notes: 416558d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 416658d36128SBarry Smith 41676a9b8d82SBarry Smith This routine may be called multiple times with different nonzero patterns (or the same nonzero pattern). The nonzero 41686a9b8d82SBarry Smith structure will be the union of all the previous nonzero structures. 41696a9b8d82SBarry Smith 41706a9b8d82SBarry Smith Developer Notes: 41716a9b8d82SBarry 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 41726a9b8d82SBarry Smith then just copies the v values directly with PetscMemcpy(). 41736a9b8d82SBarry Smith 41746a9b8d82SBarry Smith This routine could also take a PetscCopyMode argument to allow sharing the values instead of always copying them. 41756a9b8d82SBarry Smith 41766a9b8d82SBarry Smith .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), MATSEQAIJ, MatResetPreallocation() 4177a1661176SMatthew Knepley @*/ 4178a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 4179a1661176SMatthew Knepley { 4180a1661176SMatthew Knepley PetscErrorCode ierr; 4181a1661176SMatthew Knepley 4182a1661176SMatthew Knepley PetscFunctionBegin; 41830700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 41846ba663aaSJed Brown PetscValidType(B,1); 41854ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 4186a1661176SMatthew Knepley PetscFunctionReturn(0); 4187a1661176SMatthew Knepley } 4188a1661176SMatthew Knepley 41897087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 4190a1661176SMatthew Knepley { 4191a1661176SMatthew Knepley PetscInt i; 4192a1661176SMatthew Knepley PetscInt m,n; 4193a1661176SMatthew Knepley PetscInt nz; 41946a9b8d82SBarry Smith PetscInt *nnz; 4195a1661176SMatthew Knepley PetscErrorCode ierr; 4196a1661176SMatthew Knepley 4197a1661176SMatthew Knepley PetscFunctionBegin; 419865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 4199779a8d59SSatish Balay 4200779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 4201779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 4202779a8d59SSatish Balay 4203779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 4204854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 4205a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4206b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 420765e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 4208a1661176SMatthew Knepley nnz[i] = nz; 4209a1661176SMatthew Knepley } 4210a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 4211a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 4212a1661176SMatthew Knepley 4213a1661176SMatthew Knepley for (i = 0; i < m; i++) { 4214071fcb05SBarry Smith ierr = MatSetValues_SeqAIJ(B, 1, &i, Ii[i+1] - Ii[i], J+Ii[i], v ? v + Ii[i] : NULL, INSERT_VALUES);CHKERRQ(ierr); 4215a1661176SMatthew Knepley } 4216a1661176SMatthew Knepley 4217a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4218a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4219a1661176SMatthew Knepley 42207827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 4221a1661176SMatthew Knepley PetscFunctionReturn(0); 4222a1661176SMatthew Knepley } 4223a1661176SMatthew Knepley 4224c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 4225af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 4226170fe5c8SBarry Smith 4227170fe5c8SBarry Smith /* 4228170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 4229170fe5c8SBarry Smith 4230170fe5c8SBarry Smith n p p 42312da392ccSBarry Smith [ ] [ ] [ ] 42322da392ccSBarry Smith m [ A ] * n [ B ] = m [ C ] 42332da392ccSBarry Smith [ ] [ ] [ ] 4234170fe5c8SBarry Smith 4235170fe5c8SBarry Smith */ 4236170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 4237170fe5c8SBarry Smith { 4238170fe5c8SBarry Smith PetscErrorCode ierr; 4239170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 4240170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 4241170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 424286214ceeSStefano Zampini PetscInt i,j,n,m,q,p; 4243170fe5c8SBarry Smith const PetscInt *ii,*idx; 4244170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 4245170fe5c8SBarry Smith PetscScalar *c,*c_q; 424686214ceeSStefano Zampini PetscInt clda = sub_c->lda; 424786214ceeSStefano Zampini PetscInt alda = sub_a->lda; 4248170fe5c8SBarry Smith 4249170fe5c8SBarry Smith PetscFunctionBegin; 4250d0f46423SBarry Smith m = A->rmap->n; 4251d0f46423SBarry Smith n = A->cmap->n; 4252d0f46423SBarry Smith p = B->cmap->n; 4253170fe5c8SBarry Smith a = sub_a->v; 4254170fe5c8SBarry Smith b = sub_b->a; 4255170fe5c8SBarry Smith c = sub_c->v; 425686214ceeSStefano Zampini if (clda == m) { 4257580bdb30SBarry Smith ierr = PetscArrayzero(c,m*p);CHKERRQ(ierr); 425886214ceeSStefano Zampini } else { 425986214ceeSStefano Zampini for (j=0;j<p;j++) 426086214ceeSStefano Zampini for (i=0;i<m;i++) 426186214ceeSStefano Zampini c[j*clda + i] = 0.0; 426286214ceeSStefano Zampini } 4263170fe5c8SBarry Smith ii = sub_b->i; 4264170fe5c8SBarry Smith idx = sub_b->j; 4265170fe5c8SBarry Smith for (i=0; i<n; i++) { 4266170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 4267170fe5c8SBarry Smith while (q-->0) { 426886214ceeSStefano Zampini c_q = c + clda*(*idx); 426986214ceeSStefano Zampini a_q = a + alda*i; 4270854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 4271170fe5c8SBarry Smith idx++; 4272170fe5c8SBarry Smith b++; 4273170fe5c8SBarry Smith } 4274170fe5c8SBarry Smith } 4275170fe5c8SBarry Smith PetscFunctionReturn(0); 4276170fe5c8SBarry Smith } 4277170fe5c8SBarry Smith 42784222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat C) 4279170fe5c8SBarry Smith { 4280170fe5c8SBarry Smith PetscErrorCode ierr; 4281d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 428286214ceeSStefano Zampini PetscBool cisdense; 4283170fe5c8SBarry Smith 4284170fe5c8SBarry Smith PetscFunctionBegin; 428560e0710aSBarry 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); 42864222ddf1SHong Zhang ierr = MatSetSizes(C,m,n,m,n);CHKERRQ(ierr); 42874222ddf1SHong Zhang ierr = MatSetBlockSizesFromMats(C,A,B);CHKERRQ(ierr); 428886214ceeSStefano Zampini ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr); 428986214ceeSStefano Zampini if (!cisdense) { 429086214ceeSStefano Zampini ierr = MatSetType(C,MATDENSE);CHKERRQ(ierr); 429186214ceeSStefano Zampini } 429286214ceeSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 4293d73949e8SHong Zhang 42944222ddf1SHong Zhang C->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 4295170fe5c8SBarry Smith PetscFunctionReturn(0); 4296170fe5c8SBarry Smith } 4297170fe5c8SBarry Smith 4298170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 42990bad9183SKris Buschelman /*MC 4300fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 43010bad9183SKris Buschelman based on compressed sparse row format. 43020bad9183SKris Buschelman 43030bad9183SKris Buschelman Options Database Keys: 43040bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 43050bad9183SKris Buschelman 43060bad9183SKris Buschelman Level: beginner 43070bad9183SKris Buschelman 43080cd7f59aSBarry Smith Notes: 43090cd7f59aSBarry Smith MatSetValues() may be called for this matrix type with a NULL argument for the numerical values, 43100cd7f59aSBarry Smith in this case the values associated with the rows and columns one passes in are set to zero 43110cd7f59aSBarry Smith in the matrix 43120cd7f59aSBarry Smith 43130cd7f59aSBarry Smith MatSetOptions(,MAT_STRUCTURE_ONLY,PETSC_TRUE) may be called for this matrix type. In this no 43140cd7f59aSBarry Smith space is allocated for the nonzero entries and any entries passed with MatSetValues() are ignored 43150cd7f59aSBarry Smith 43160cd7f59aSBarry Smith Developer Notes: 43170cd7f59aSBarry Smith It would be nice if all matrix formats supported passing NULL in for the numerical values 43180cd7f59aSBarry Smith 4319f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 43200bad9183SKris Buschelman M*/ 43210bad9183SKris Buschelman 4322ccd284c7SBarry Smith /*MC 4323ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 4324ccd284c7SBarry Smith 4325ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 4326ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 43270cd7f59aSBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation() is supported 4328ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4329ccd284c7SBarry Smith the above preallocation routines for simplicity. 4330ccd284c7SBarry Smith 4331ccd284c7SBarry Smith Options Database Keys: 4332ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 4333ccd284c7SBarry Smith 433495452b02SPatrick Sanan Developer Notes: 4335ca9cdca7SRichard Tran Mills Subclasses include MATAIJCUSPARSE, MATAIJPERM, MATAIJSELL, MATAIJMKL, MATAIJCRL, and also automatically switches over to use inodes when 4336ccd284c7SBarry Smith enough exist. 4337ccd284c7SBarry Smith 4338ccd284c7SBarry Smith Level: beginner 4339ccd284c7SBarry Smith 4340ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 4341ccd284c7SBarry Smith M*/ 4342ccd284c7SBarry Smith 4343ccd284c7SBarry Smith /*MC 4344ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 4345ccd284c7SBarry Smith 4346ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 4347ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 4348ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 4349ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 4350ccd284c7SBarry Smith the above preallocation routines for simplicity. 4351ccd284c7SBarry Smith 4352ccd284c7SBarry Smith Options Database Keys: 4353ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 4354ccd284c7SBarry Smith 4355ccd284c7SBarry Smith Level: beginner 4356ccd284c7SBarry Smith 4357ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 4358ccd284c7SBarry Smith M*/ 4359ccd284c7SBarry Smith 43607906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 43617906f579SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 43627906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 43637906f579SHong Zhang #endif 4364d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4365d24d4204SJose E. Roman PETSC_INTERN PetscErrorCode MatConvert_AIJ_ScaLAPACK(Mat,MatType,MatReuse,Mat*); 4366d24d4204SJose E. Roman #endif 43677906f579SHong Zhang #if defined(PETSC_HAVE_HYPRE) 43687906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 43697906f579SHong Zhang #endif 43707906f579SHong Zhang PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 43717906f579SHong Zhang 4372d4002b98SHong Zhang PETSC_EXTERN PetscErrorCode MatConvert_SeqAIJ_SeqSELL(Mat,MatType,MatReuse,Mat*); 4373c9225affSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_XAIJ_IS(Mat,MatType,MatReuse,Mat*); 43744222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_IS_XAIJ(Mat); 43757906f579SHong Zhang 43768c778c55SBarry Smith /*@C 43778f1ea47aSStefano Zampini MatSeqAIJGetArray - gives read/write access to the array where the data for a MATSEQAIJ matrix is stored 43788c778c55SBarry Smith 43798c778c55SBarry Smith Not Collective 43808c778c55SBarry Smith 43818c778c55SBarry Smith Input Parameter: 4382579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 43838c778c55SBarry Smith 43848c778c55SBarry Smith Output Parameter: 43858c778c55SBarry Smith . array - pointer to the data 43868c778c55SBarry Smith 43878c778c55SBarry Smith Level: intermediate 43888c778c55SBarry Smith 4389774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 43908c778c55SBarry Smith @*/ 43918c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 43928c778c55SBarry Smith { 43938c778c55SBarry Smith PetscErrorCode ierr; 43948c778c55SBarry Smith 43958c778c55SBarry Smith PetscFunctionBegin; 43968c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 43978c778c55SBarry Smith PetscFunctionReturn(0); 43988c778c55SBarry Smith } 43998c778c55SBarry Smith 440021e72a00SBarry Smith /*@C 44018f1ea47aSStefano Zampini MatSeqAIJGetArrayRead - gives read-only access to the array where the data for a MATSEQAIJ matrix is stored 44028f1ea47aSStefano Zampini 44038f1ea47aSStefano Zampini Not Collective 44048f1ea47aSStefano Zampini 44058f1ea47aSStefano Zampini Input Parameter: 44068f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44078f1ea47aSStefano Zampini 44088f1ea47aSStefano Zampini Output Parameter: 44098f1ea47aSStefano Zampini . array - pointer to the data 44108f1ea47aSStefano Zampini 44118f1ea47aSStefano Zampini Level: intermediate 44128f1ea47aSStefano Zampini 44138f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayRead() 44148f1ea47aSStefano Zampini @*/ 44158f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJGetArrayRead(Mat A,const PetscScalar **array) 44168f1ea47aSStefano Zampini { 44178c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4418c70f7ee4SJunchao Zhang PetscOffloadMask oval; 44198f1ea47aSStefano Zampini #endif 44208f1ea47aSStefano Zampini PetscErrorCode ierr; 44218f1ea47aSStefano Zampini 44228f1ea47aSStefano Zampini PetscFunctionBegin; 44238c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4424c70f7ee4SJunchao Zhang oval = A->offloadmask; 44258f1ea47aSStefano Zampini #endif 44268f1ea47aSStefano Zampini ierr = MatSeqAIJGetArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44278c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4428c70f7ee4SJunchao Zhang if (oval == PETSC_OFFLOAD_GPU || oval == PETSC_OFFLOAD_BOTH) A->offloadmask = PETSC_OFFLOAD_BOTH; 44298f1ea47aSStefano Zampini #endif 44308f1ea47aSStefano Zampini PetscFunctionReturn(0); 44318f1ea47aSStefano Zampini } 44328f1ea47aSStefano Zampini 44338f1ea47aSStefano Zampini /*@C 44348f1ea47aSStefano Zampini MatSeqAIJRestoreArrayRead - restore the read-only access array obtained from MatSeqAIJGetArrayRead 44358f1ea47aSStefano Zampini 44368f1ea47aSStefano Zampini Not Collective 44378f1ea47aSStefano Zampini 44388f1ea47aSStefano Zampini Input Parameter: 44398f1ea47aSStefano Zampini . mat - a MATSEQAIJ matrix 44408f1ea47aSStefano Zampini 44418f1ea47aSStefano Zampini Output Parameter: 44428f1ea47aSStefano Zampini . array - pointer to the data 44438f1ea47aSStefano Zampini 44448f1ea47aSStefano Zampini Level: intermediate 44458f1ea47aSStefano Zampini 44468f1ea47aSStefano Zampini .seealso: MatSeqAIJGetArray(), MatSeqAIJGetArrayRead() 44478f1ea47aSStefano Zampini @*/ 44488f1ea47aSStefano Zampini PetscErrorCode MatSeqAIJRestoreArrayRead(Mat A,const PetscScalar **array) 44498f1ea47aSStefano Zampini { 44508c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4451c70f7ee4SJunchao Zhang PetscOffloadMask oval; 44528f1ea47aSStefano Zampini #endif 44538f1ea47aSStefano Zampini PetscErrorCode ierr; 44548f1ea47aSStefano Zampini 44558f1ea47aSStefano Zampini PetscFunctionBegin; 44568c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4457c70f7ee4SJunchao Zhang oval = A->offloadmask; 44588f1ea47aSStefano Zampini #endif 44598f1ea47aSStefano Zampini ierr = MatSeqAIJRestoreArray(A,(PetscScalar**)array);CHKERRQ(ierr); 44608c3ff71bSJunchao Zhang #if defined(PETSC_HAVE_DEVICE) 4461c70f7ee4SJunchao Zhang A->offloadmask = oval; 44628f1ea47aSStefano Zampini #endif 44638f1ea47aSStefano Zampini PetscFunctionReturn(0); 44648f1ea47aSStefano Zampini } 44658f1ea47aSStefano Zampini 44668f1ea47aSStefano Zampini /*@C 446721e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 446821e72a00SBarry Smith 446921e72a00SBarry Smith Not Collective 447021e72a00SBarry Smith 447121e72a00SBarry Smith Input Parameter: 4472579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 447321e72a00SBarry Smith 447421e72a00SBarry Smith Output Parameter: 447521e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 447621e72a00SBarry Smith 447721e72a00SBarry Smith Level: intermediate 447821e72a00SBarry Smith 447921e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 448021e72a00SBarry Smith @*/ 448121e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 448221e72a00SBarry Smith { 448321e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 448421e72a00SBarry Smith 448521e72a00SBarry Smith PetscFunctionBegin; 448621e72a00SBarry Smith *nz = aij->rmax; 448721e72a00SBarry Smith PetscFunctionReturn(0); 448821e72a00SBarry Smith } 448921e72a00SBarry Smith 44908c778c55SBarry Smith /*@C 4491579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 44928c778c55SBarry Smith 44938c778c55SBarry Smith Not Collective 44948c778c55SBarry Smith 44958c778c55SBarry Smith Input Parameters: 4496a2b725a8SWilliam Gropp + mat - a MATSEQAIJ matrix 4497a2b725a8SWilliam Gropp - array - pointer to the data 44988c778c55SBarry Smith 44998c778c55SBarry Smith Level: intermediate 45008c778c55SBarry Smith 4501774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 45028c778c55SBarry Smith @*/ 45038c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 45048c778c55SBarry Smith { 45058c778c55SBarry Smith PetscErrorCode ierr; 45068c778c55SBarry Smith 45078c778c55SBarry Smith PetscFunctionBegin; 45088c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 45098c778c55SBarry Smith PetscFunctionReturn(0); 45108c778c55SBarry Smith } 45118c778c55SBarry Smith 451234b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 45130ce8acdeSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCUSPARSE(Mat); 451402fe1965SBarry Smith #endif 45153d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 45163d0639e7SStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJKokkos(Mat); 45173d0639e7SStefano Zampini #endif 451802fe1965SBarry Smith 45198cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 4520273d9f13SBarry Smith { 4521273d9f13SBarry Smith Mat_SeqAIJ *b; 4522dfbe8321SBarry Smith PetscErrorCode ierr; 452338baddfdSBarry Smith PetscMPIInt size; 4524273d9f13SBarry Smith 4525273d9f13SBarry Smith PetscFunctionBegin; 4526ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRMPI(ierr); 4527e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 4528273d9f13SBarry Smith 4529b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 45302205254eSKarl Rupp 4531b0a32e0cSBarry Smith B->data = (void*)b; 45322205254eSKarl Rupp 4533549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 4534071fcb05SBarry Smith if (B->sortedfull) B->ops->setvalues = MatSetValues_SeqAIJ_SortedFull; 45352205254eSKarl Rupp 4536f4259b30SLisandro Dalcin b->row = NULL; 4537f4259b30SLisandro Dalcin b->col = NULL; 4538f4259b30SLisandro Dalcin b->icol = NULL; 4539b810aeb4SBarry Smith b->reallocs = 0; 454036db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 4541f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 4542416022c9SBarry Smith b->nonew = 0; 4543f4259b30SLisandro Dalcin b->diag = NULL; 4544f4259b30SLisandro Dalcin b->solve_work = NULL; 4545f4259b30SLisandro Dalcin B->spptr = NULL; 4546f4259b30SLisandro Dalcin b->saved_values = NULL; 4547f4259b30SLisandro Dalcin b->idiag = NULL; 4548f4259b30SLisandro Dalcin b->mdiag = NULL; 4549f4259b30SLisandro Dalcin b->ssor_work = NULL; 455071f1c65dSBarry Smith b->omega = 1.0; 455171f1c65dSBarry Smith b->fshift = 0.0; 455271f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 4553bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 4554a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 455517ab2063SBarry Smith 455635d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 4557bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 4558bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 45598c778c55SBarry Smith 4560b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4561bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 4562bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 4563b3866ffcSBarry Smith #endif 456417f1a0eaSHong Zhang 4565bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 4566bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 4567bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 4568bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 4569bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 4570bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 45714dfdc2d9SRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijsell_C",MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 45729779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 45734a2a386eSRichard Tran Mills ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijmkl_C",MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 4574191b95cbSRichard Tran Mills #endif 457534b5b067SBarry Smith #if defined(PETSC_HAVE_CUDA) 457602fe1965SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcusparse_C",MatConvert_SeqAIJ_SeqAIJCUSPARSE);CHKERRQ(ierr); 45774222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaijcusparse_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 4578fcdce8c4SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaijcusparse_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 457902fe1965SBarry Smith #endif 45803d0639e7SStefano Zampini #if defined(PETSC_HAVE_KOKKOS_KERNELS) 45813d0639e7SStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijkokkos_C",MatConvert_SeqAIJ_SeqAIJKokkos);CHKERRQ(ierr); 45823d0639e7SStefano Zampini #endif 4583bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 4584af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 4585af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 4586af8000cdSHong Zhang #endif 4587d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 4588d24d4204SJose E. Roman ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_scalapack_C",MatConvert_AIJ_ScaLAPACK);CHKERRQ(ierr); 4589d24d4204SJose E. Roman #endif 459063c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 459163c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 45924222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_transpose_seqaij_seqaij_C",MatProductSetFromOptions_Transpose_AIJ_AIJ);CHKERRQ(ierr); 459363c07aadSStefano Zampini #endif 4594b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 4595d4002b98SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsell_C",MatConvert_SeqAIJ_SeqSELL);CHKERRQ(ierr); 4596c9225affSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_is_C",MatConvert_XAIJ_IS);CHKERRQ(ierr); 4597bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4598bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 4599bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 4600846b4da1SFande Kong ierr = PetscObjectComposeFunction((PetscObject)B,"MatResetPreallocation_C",MatResetPreallocation_SeqAIJ);CHKERRQ(ierr); 4601bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 4602bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 46034222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_is_seqaij_C",MatProductSetFromOptions_IS_XAIJ);CHKERRQ(ierr); 46044222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqaij_C",MatProductSetFromOptions_SeqDense_SeqAIJ);CHKERRQ(ierr); 46054222ddf1SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqaij_C",MatProductSetFromOptions_SeqAIJ);CHKERRQ(ierr); 46064108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 460717667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 46084099cc6bSBarry Smith ierr = MatSeqAIJSetTypeFromOptions(B);CHKERRQ(ierr); /* this allows changing the matrix subtype to say MATSEQAIJPERM */ 46093a40ed3dSBarry Smith PetscFunctionReturn(0); 461017ab2063SBarry Smith } 461117ab2063SBarry Smith 4612b24902e0SBarry Smith /* 4613b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 4614b24902e0SBarry Smith */ 4615ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 461617ab2063SBarry Smith { 46172a350339SBarry Smith Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data,*a = (Mat_SeqAIJ*)A->data; 46186849ba73SBarry Smith PetscErrorCode ierr; 4619071fcb05SBarry Smith PetscInt m = A->rmap->n,i; 462017ab2063SBarry Smith 46213a40ed3dSBarry Smith PetscFunctionBegin; 4622ca133879SJose E. Roman if (!A->assembled && cpvalues!=MAT_DO_NOT_COPY_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot duplicate unassembled matrix"); 4623273d9f13SBarry Smith 4624d5f3da31SBarry Smith C->factortype = A->factortype; 4625f4259b30SLisandro Dalcin c->row = NULL; 4626f4259b30SLisandro Dalcin c->col = NULL; 4627f4259b30SLisandro Dalcin c->icol = NULL; 46286ad4291fSHong Zhang c->reallocs = 0; 462917ab2063SBarry Smith 46306ad4291fSHong Zhang C->assembled = PETSC_TRUE; 463117ab2063SBarry Smith 4632aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 4633aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 4634eec197d1SBarry Smith 4635071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->imax);CHKERRQ(ierr); 4636071fcb05SBarry Smith ierr = PetscMemcpy(c->imax,a->imax,m*sizeof(PetscInt));CHKERRQ(ierr); 4637071fcb05SBarry Smith ierr = PetscMalloc1(m,&c->ilen);CHKERRQ(ierr); 4638071fcb05SBarry Smith ierr = PetscMemcpy(c->ilen,a->ilen,m*sizeof(PetscInt));CHKERRQ(ierr); 46393bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 464017ab2063SBarry Smith 464117ab2063SBarry Smith /* allocate the matrix space */ 4642f77e22a1SHong Zhang if (mallocmatspace) { 4643dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 46443bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 46452205254eSKarl Rupp 4646f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 46472205254eSKarl Rupp 4648580bdb30SBarry Smith ierr = PetscArraycpy(c->i,a->i,m+1);CHKERRQ(ierr); 464917ab2063SBarry Smith if (m > 0) { 4650580bdb30SBarry Smith ierr = PetscArraycpy(c->j,a->j,a->i[m]);CHKERRQ(ierr); 4651be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 4652580bdb30SBarry Smith ierr = PetscArraycpy(c->a,a->a,a->i[m]);CHKERRQ(ierr); 4653be6bf707SBarry Smith } else { 4654580bdb30SBarry Smith ierr = PetscArrayzero(c->a,a->i[m]);CHKERRQ(ierr); 465517ab2063SBarry Smith } 465608480c60SBarry Smith } 4657f77e22a1SHong Zhang } 465817ab2063SBarry Smith 46596ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4660416022c9SBarry Smith c->roworiented = a->roworiented; 4661416022c9SBarry Smith c->nonew = a->nonew; 4662416022c9SBarry Smith if (a->diag) { 4663854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 4664071fcb05SBarry Smith ierr = PetscMemcpy(c->diag,a->diag,m*sizeof(PetscInt));CHKERRQ(ierr); 46653bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 4666071fcb05SBarry Smith } else c->diag = NULL; 46672205254eSKarl Rupp 4668f4259b30SLisandro Dalcin c->solve_work = NULL; 4669f4259b30SLisandro Dalcin c->saved_values = NULL; 4670f4259b30SLisandro Dalcin c->idiag = NULL; 4671f4259b30SLisandro Dalcin c->ssor_work = NULL; 4672a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4673e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4674e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 46756ad4291fSHong Zhang 4676893ad86cSHong Zhang c->rmax = a->rmax; 4677416022c9SBarry Smith c->nz = a->nz; 46788ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4679273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4680754ec7b1SSatish Balay 46816ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 46826ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4683cd6b891eSBarry Smith if (a->compressedrow.use) { 46846ad4291fSHong Zhang i = a->compressedrow.nrows; 4685dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 4686580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.i,a->compressedrow.i,i+1);CHKERRQ(ierr); 4687580bdb30SBarry Smith ierr = PetscArraycpy(c->compressedrow.rindex,a->compressedrow.rindex,i);CHKERRQ(ierr); 468827ea64f8SHong Zhang } else { 468927ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 46900298fd71SBarry Smith c->compressedrow.i = NULL; 46910298fd71SBarry Smith c->compressedrow.rindex = NULL; 46926ad4291fSHong Zhang } 4693ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4694e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 46954846f1f5SKris Buschelman 46962205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4697140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 46983a40ed3dSBarry Smith PetscFunctionReturn(0); 469917ab2063SBarry Smith } 470017ab2063SBarry Smith 4701b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4702b24902e0SBarry Smith { 4703b24902e0SBarry Smith PetscErrorCode ierr; 4704b24902e0SBarry Smith 4705b24902e0SBarry Smith PetscFunctionBegin; 4706ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 47074b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4708cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 470933d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4710cfd3f464SBarry Smith } 4711a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4712f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4713b24902e0SBarry Smith PetscFunctionReturn(0); 4714b24902e0SBarry Smith } 4715b24902e0SBarry Smith 4716112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4717fbdbba38SShri Abhyankar { 471852f91c60SVaclav Hapla PetscBool isbinary, ishdf5; 471952f91c60SVaclav Hapla PetscErrorCode ierr; 472052f91c60SVaclav Hapla 472152f91c60SVaclav Hapla PetscFunctionBegin; 472252f91c60SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 472352f91c60SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 4724c27b3999SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 4725c27b3999SVaclav Hapla ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 472652f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 472752f91c60SVaclav Hapla ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5);CHKERRQ(ierr); 472852f91c60SVaclav Hapla if (isbinary) { 472952f91c60SVaclav Hapla ierr = MatLoad_SeqAIJ_Binary(newMat,viewer);CHKERRQ(ierr); 473052f91c60SVaclav Hapla } else if (ishdf5) { 473152f91c60SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 473252f91c60SVaclav Hapla ierr = MatLoad_AIJ_HDF5(newMat,viewer);CHKERRQ(ierr); 473352f91c60SVaclav Hapla #else 473452f91c60SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 473552f91c60SVaclav Hapla #endif 473652f91c60SVaclav Hapla } else { 473752f91c60SVaclav 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); 473852f91c60SVaclav Hapla } 473952f91c60SVaclav Hapla PetscFunctionReturn(0); 474052f91c60SVaclav Hapla } 474152f91c60SVaclav Hapla 47423ea6fe3dSLisandro Dalcin PetscErrorCode MatLoad_SeqAIJ_Binary(Mat mat, PetscViewer viewer) 474352f91c60SVaclav Hapla { 47443ea6fe3dSLisandro Dalcin Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 4745fbdbba38SShri Abhyankar PetscErrorCode ierr; 47463ea6fe3dSLisandro Dalcin PetscInt header[4],*rowlens,M,N,nz,sum,rows,cols,i; 4747fbdbba38SShri Abhyankar 4748fbdbba38SShri Abhyankar PetscFunctionBegin; 47493ea6fe3dSLisandro Dalcin ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4750bbead8a2SBarry Smith 47513ea6fe3dSLisandro Dalcin /* read in matrix header */ 47523ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT);CHKERRQ(ierr); 47533ea6fe3dSLisandro Dalcin if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 4754fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 47553ea6fe3dSLisandro Dalcin if (M < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%D) in file is negative",M); 47563ea6fe3dSLisandro Dalcin if (N < 0) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%D) in file is negative",N); 4757bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 4758fbdbba38SShri Abhyankar 47593ea6fe3dSLisandro Dalcin /* set block sizes from the viewer's .info file */ 47603ea6fe3dSLisandro Dalcin ierr = MatLoad_Binary_BlockSizes(mat,viewer);CHKERRQ(ierr); 47613ea6fe3dSLisandro Dalcin /* set local and global sizes if not set already */ 47623ea6fe3dSLisandro Dalcin if (mat->rmap->n < 0) mat->rmap->n = M; 47633ea6fe3dSLisandro Dalcin if (mat->cmap->n < 0) mat->cmap->n = N; 47643ea6fe3dSLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 47653ea6fe3dSLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 47663ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->rmap);CHKERRQ(ierr); 47673ea6fe3dSLisandro Dalcin ierr = PetscLayoutSetUp(mat->cmap);CHKERRQ(ierr); 47683ea6fe3dSLisandro Dalcin 47693ea6fe3dSLisandro Dalcin /* check if the matrix sizes are correct */ 47703ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 47713ea6fe3dSLisandro 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); 47723ea6fe3dSLisandro Dalcin 4773fbdbba38SShri Abhyankar /* read in row lengths */ 47743ea6fe3dSLisandro Dalcin ierr = PetscMalloc1(M,&rowlens);CHKERRQ(ierr); 47753ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,rowlens,M,NULL,PETSC_INT);CHKERRQ(ierr); 47763ea6fe3dSLisandro Dalcin /* check if sum(rowlens) is same as nz */ 47773ea6fe3dSLisandro Dalcin sum = 0; for (i=0; i<M; i++) sum += rowlens[i]; 47783ea6fe3dSLisandro 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); 47793ea6fe3dSLisandro Dalcin /* preallocate and check sizes */ 47803ea6fe3dSLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(mat,0,rowlens);CHKERRQ(ierr); 47813ea6fe3dSLisandro Dalcin ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 478260e0710aSBarry 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); 47833ea6fe3dSLisandro Dalcin /* store row lengths */ 47843ea6fe3dSLisandro Dalcin ierr = PetscArraycpy(a->ilen,rowlens,M);CHKERRQ(ierr); 47853ea6fe3dSLisandro Dalcin ierr = PetscFree(rowlens);CHKERRQ(ierr); 4786fbdbba38SShri Abhyankar 47873ea6fe3dSLisandro Dalcin /* fill in "i" row pointers */ 47883ea6fe3dSLisandro Dalcin a->i[0] = 0; for (i=0; i<M; i++) a->i[i+1] = a->i[i] + a->ilen[i]; 47893ea6fe3dSLisandro Dalcin /* read in "j" column indices */ 47903ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->j,nz,NULL,PETSC_INT);CHKERRQ(ierr); 47913ea6fe3dSLisandro Dalcin /* read in "a" nonzero values */ 47923ea6fe3dSLisandro Dalcin ierr = PetscViewerBinaryRead(viewer,a->a,nz,NULL,PETSC_SCALAR);CHKERRQ(ierr); 4793fbdbba38SShri Abhyankar 47943ea6fe3dSLisandro Dalcin ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 47953ea6fe3dSLisandro Dalcin ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4796fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4797fbdbba38SShri Abhyankar } 4798fbdbba38SShri Abhyankar 4799ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 48007264ac53SSatish Balay { 48017264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4802dfbe8321SBarry Smith PetscErrorCode ierr; 4803eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4804eeffb40dSHong Zhang PetscInt k; 4805eeffb40dSHong Zhang #endif 48067264ac53SSatish Balay 48073a40ed3dSBarry Smith PetscFunctionBegin; 4808bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4809d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4810ca44d042SBarry Smith *flg = PETSC_FALSE; 4811ca44d042SBarry Smith PetscFunctionReturn(0); 4812bcd2baecSBarry Smith } 48137264ac53SSatish Balay 48147264ac53SSatish Balay /* if the a->i are the same */ 4815580bdb30SBarry Smith ierr = PetscArraycmp(a->i,b->i,A->rmap->n+1,flg);CHKERRQ(ierr); 4816abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 48177264ac53SSatish Balay 48187264ac53SSatish Balay /* if a->j are the same */ 4819580bdb30SBarry Smith ierr = PetscArraycmp(a->j,b->j,a->nz,flg);CHKERRQ(ierr); 4820abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4821bcd2baecSBarry Smith 4822bcd2baecSBarry Smith /* if a->a are the same */ 4823eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4824eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4825eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4826eeffb40dSHong Zhang *flg = PETSC_FALSE; 48273a40ed3dSBarry Smith PetscFunctionReturn(0); 4828eeffb40dSHong Zhang } 4829eeffb40dSHong Zhang } 4830eeffb40dSHong Zhang #else 4831580bdb30SBarry Smith ierr = PetscArraycmp(a->a,b->a,a->nz,flg);CHKERRQ(ierr); 4832eeffb40dSHong Zhang #endif 4833eeffb40dSHong Zhang PetscFunctionReturn(0); 48347264ac53SSatish Balay } 483536db0b34SBarry Smith 483605869f15SSatish Balay /*@ 483736db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 483836db0b34SBarry Smith provided by the user. 483936db0b34SBarry Smith 4840d083f849SBarry Smith Collective 484136db0b34SBarry Smith 484236db0b34SBarry Smith Input Parameters: 484336db0b34SBarry Smith + comm - must be an MPI communicator of size 1 484436db0b34SBarry Smith . m - number of rows 484536db0b34SBarry Smith . n - number of columns 4846483a2f95SBarry Smith . i - row indices; that is i[0] = 0, i[row] = i[row-1] + number of elements in that row of the matrix 484736db0b34SBarry Smith . j - column indices 484836db0b34SBarry Smith - a - matrix values 484936db0b34SBarry Smith 485036db0b34SBarry Smith Output Parameter: 485136db0b34SBarry Smith . mat - the matrix 485236db0b34SBarry Smith 485336db0b34SBarry Smith Level: intermediate 485436db0b34SBarry Smith 485536db0b34SBarry Smith Notes: 48560551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4857292fb18eSBarry Smith once the matrix is destroyed and not before 485836db0b34SBarry Smith 485936db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 486036db0b34SBarry Smith 4861bfeeae90SHong Zhang The i and j indices are 0 based 486236db0b34SBarry Smith 4863a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4864a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 48658eef79e4SBarry Smith as shown 4866a4552177SSatish Balay 48678eef79e4SBarry Smith $ 1 0 0 48688eef79e4SBarry Smith $ 2 0 3 48698eef79e4SBarry Smith $ 4 5 6 48708eef79e4SBarry Smith $ 48718eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 48728eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 48738eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4874a4552177SSatish Balay 48759985e31cSBarry Smith 487669b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 487736db0b34SBarry Smith 487836db0b34SBarry Smith @*/ 4879c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 488036db0b34SBarry Smith { 4881dfbe8321SBarry Smith PetscErrorCode ierr; 4882cbcfb4deSHong Zhang PetscInt ii; 488336db0b34SBarry Smith Mat_SeqAIJ *aij; 4884cbcfb4deSHong Zhang PetscInt jj; 488536db0b34SBarry Smith 488636db0b34SBarry Smith PetscFunctionBegin; 488741096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4888f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4889f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4890a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4891ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4892f4259b30SLisandro Dalcin ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,NULL);CHKERRQ(ierr); 4893ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4894071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->imax);CHKERRQ(ierr); 4895071fcb05SBarry Smith ierr = PetscMalloc1(m,&aij->ilen);CHKERRQ(ierr); 4896ab93d7beSBarry Smith 489736db0b34SBarry Smith aij->i = i; 489836db0b34SBarry Smith aij->j = j; 489936db0b34SBarry Smith aij->a = a; 490036db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 490136db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4902e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4903e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 490436db0b34SBarry Smith 490536db0b34SBarry Smith for (ii=0; ii<m; ii++) { 490636db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 490776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 490860e0710aSBarry 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]); 49099985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4910a061629eSStefano 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); 4911a061629eSStefano 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); 49129985e31cSBarry Smith } 491336db0b34SBarry Smith } 491476bd3646SJed Brown } 491576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 491636db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 491760e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 491860e0710aSBarry 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]); 491936db0b34SBarry Smith } 492076bd3646SJed Brown } 492136db0b34SBarry Smith 4922b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4923b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 492436db0b34SBarry Smith PetscFunctionReturn(0); 492536db0b34SBarry Smith } 492680ef6e79SMatthew G Knepley /*@C 4927d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 49288a0b0e6bSVictor Minden provided by the user. 49298a0b0e6bSVictor Minden 4930d083f849SBarry Smith Collective 49318a0b0e6bSVictor Minden 49328a0b0e6bSVictor Minden Input Parameters: 49338a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 49348a0b0e6bSVictor Minden . m - number of rows 49358a0b0e6bSVictor Minden . n - number of columns 49368a0b0e6bSVictor Minden . i - row indices 49378a0b0e6bSVictor Minden . j - column indices 49381230e6d1SVictor Minden . a - matrix values 49391230e6d1SVictor Minden . nz - number of nonzeros 49401230e6d1SVictor Minden - idx - 0 or 1 based 49418a0b0e6bSVictor Minden 49428a0b0e6bSVictor Minden Output Parameter: 49438a0b0e6bSVictor Minden . mat - the matrix 49448a0b0e6bSVictor Minden 49458a0b0e6bSVictor Minden Level: intermediate 49468a0b0e6bSVictor Minden 49478a0b0e6bSVictor Minden Notes: 49488a0b0e6bSVictor Minden The i and j indices are 0 based 49498a0b0e6bSVictor Minden 49508a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 49518a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 49528a0b0e6bSVictor Minden as shown: 49538a0b0e6bSVictor Minden 49548a0b0e6bSVictor Minden 1 0 0 49558a0b0e6bSVictor Minden 2 0 3 49568a0b0e6bSVictor Minden 4 5 6 49578a0b0e6bSVictor Minden 49588a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 49598a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 49608a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 49618a0b0e6bSVictor Minden 49628a0b0e6bSVictor Minden 496369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 49648a0b0e6bSVictor Minden 49658a0b0e6bSVictor Minden @*/ 4966c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 49678a0b0e6bSVictor Minden { 49688a0b0e6bSVictor Minden PetscErrorCode ierr; 4969d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 49708a0b0e6bSVictor Minden 49718a0b0e6bSVictor Minden 49728a0b0e6bSVictor Minden PetscFunctionBegin; 49731795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 49741230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4975c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 49761230e6d1SVictor Minden } 49778a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 49788a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 49798a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 49801230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 49811230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 49821230e6d1SVictor Minden if (idx) { 49831230e6d1SVictor Minden row = i[ii] - 1; 49841230e6d1SVictor Minden col = j[ii] - 1; 49851230e6d1SVictor Minden } else { 49861230e6d1SVictor Minden row = i[ii]; 49871230e6d1SVictor Minden col = j[ii]; 49888a0b0e6bSVictor Minden } 49891230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 49908a0b0e6bSVictor Minden } 49918a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 49928a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4993d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 49948a0b0e6bSVictor Minden PetscFunctionReturn(0); 49958a0b0e6bSVictor Minden } 499636db0b34SBarry Smith 4997acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4998acf2f550SJed Brown { 4999acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 5000acf2f550SJed Brown PetscErrorCode ierr; 5001acf2f550SJed Brown 5002acf2f550SJed Brown PetscFunctionBegin; 5003acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 5004acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 50052205254eSKarl Rupp 5006acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 5007acf2f550SJed Brown PetscFunctionReturn(0); 5008acf2f550SJed Brown } 5009acf2f550SJed Brown 50109c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 50119c8f2541SHong Zhang { 50129c8f2541SHong Zhang PetscErrorCode ierr; 50138761c3d6SHong Zhang PetscMPIInt size; 50149c8f2541SHong Zhang 50159c8f2541SHong Zhang PetscFunctionBegin; 5016ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 50177bbdc51dSHong Zhang if (size == 1) { 50187bbdc51dSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 50197bbdc51dSHong Zhang ierr = MatDuplicate(inmat,MAT_COPY_VALUES,outmat);CHKERRQ(ierr); 50207bbdc51dSHong Zhang } else { 50218761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 50227bbdc51dSHong Zhang } 50238761c3d6SHong Zhang } else { 50249c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 50258761c3d6SHong Zhang } 50269c8f2541SHong Zhang PetscFunctionReturn(0); 50279c8f2541SHong Zhang } 50289c8f2541SHong Zhang 502981824310SBarry Smith /* 503053dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 503153dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 503253dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 503353dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 503453dd7562SDmitry Karpeev */ 503553dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 503653dd7562SDmitry Karpeev { 503753dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 503853dd7562SDmitry Karpeev PetscErrorCode ierr; 503953dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 504053dd7562SDmitry Karpeev PetscBool seqaij; 504153dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 504253dd7562SDmitry Karpeev PetscScalar v; 504353dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 504453dd7562SDmitry Karpeev 504553dd7562SDmitry Karpeev PetscFunctionBegin; 504653dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 504753dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 50484099cc6bSBarry Smith ierr = PetscObjectBaseTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 504953dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 505053dd7562SDmitry Karpeev if (rowemb) { 505153dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 505253dd7562SDmitry 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); 505353dd7562SDmitry Karpeev } else { 50546c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 505553dd7562SDmitry Karpeev } 505653dd7562SDmitry Karpeev if (colemb) { 505753dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 505853dd7562SDmitry 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); 505953dd7562SDmitry Karpeev } else { 506053dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 506153dd7562SDmitry Karpeev } 506253dd7562SDmitry Karpeev 506353dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 506453dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 506553dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 506653dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 506753dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 506853dd7562SDmitry Karpeev } 506953dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 507053dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 507153dd7562SDmitry Karpeev } 507253dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 507353dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 507453dd7562SDmitry Karpeev } 507553dd7562SDmitry Karpeev count = 0; 507653dd7562SDmitry Karpeev rowindices = NULL; 507753dd7562SDmitry Karpeev colindices = NULL; 507853dd7562SDmitry Karpeev if (rowemb) { 507953dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 508053dd7562SDmitry Karpeev } 508153dd7562SDmitry Karpeev if (colemb) { 508253dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 508353dd7562SDmitry Karpeev } 508453dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 508553dd7562SDmitry Karpeev PetscInt row; 508653dd7562SDmitry Karpeev row = i; 508753dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 508853dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 508953dd7562SDmitry Karpeev PetscInt col; 509053dd7562SDmitry Karpeev col = Baij->j[count]; 509153dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 509253dd7562SDmitry Karpeev v = Baij->a[count]; 509353dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 509453dd7562SDmitry Karpeev ++count; 509553dd7562SDmitry Karpeev } 509653dd7562SDmitry Karpeev } 509753dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 509853dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 509953dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 510053dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 510153dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 510253dd7562SDmitry Karpeev PetscFunctionReturn(0); 510353dd7562SDmitry Karpeev } 510453dd7562SDmitry Karpeev 51054099cc6bSBarry Smith PetscFunctionList MatSeqAIJList = NULL; 51064099cc6bSBarry Smith 51074099cc6bSBarry Smith /*@C 51084099cc6bSBarry Smith MatSeqAIJSetType - Converts a MATSEQAIJ matrix to a subtype 51094099cc6bSBarry Smith 51104099cc6bSBarry Smith Collective on Mat 51114099cc6bSBarry Smith 51124099cc6bSBarry Smith Input Parameters: 51134099cc6bSBarry Smith + mat - the matrix object 51144099cc6bSBarry Smith - matype - matrix type 51154099cc6bSBarry Smith 51164099cc6bSBarry Smith Options Database Key: 51174099cc6bSBarry Smith . -mat_seqai_type <method> - for example seqaijcrl 51184099cc6bSBarry Smith 51194099cc6bSBarry Smith 51204099cc6bSBarry Smith Level: intermediate 51214099cc6bSBarry Smith 51224099cc6bSBarry Smith .seealso: PCSetType(), VecSetType(), MatCreate(), MatType, Mat 51234099cc6bSBarry Smith @*/ 51244099cc6bSBarry Smith PetscErrorCode MatSeqAIJSetType(Mat mat, MatType matype) 51254099cc6bSBarry Smith { 5126fd9d3c67SJed Brown PetscErrorCode ierr,(*r)(Mat,MatType,MatReuse,Mat*); 51274099cc6bSBarry Smith PetscBool sametype; 51284099cc6bSBarry Smith 51294099cc6bSBarry Smith PetscFunctionBegin; 51304099cc6bSBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 51314099cc6bSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)mat,matype,&sametype);CHKERRQ(ierr); 51324099cc6bSBarry Smith if (sametype) PetscFunctionReturn(0); 51334099cc6bSBarry Smith 51344099cc6bSBarry Smith ierr = PetscFunctionListFind(MatSeqAIJList,matype,&r);CHKERRQ(ierr); 51354099cc6bSBarry Smith if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown Mat type given: %s",matype); 51364099cc6bSBarry Smith ierr = (*r)(mat,matype,MAT_INPLACE_MATRIX,&mat);CHKERRQ(ierr); 51374099cc6bSBarry Smith PetscFunctionReturn(0); 51384099cc6bSBarry Smith } 51394099cc6bSBarry Smith 51404099cc6bSBarry Smith 51414099cc6bSBarry Smith /*@C 51424099cc6bSBarry Smith MatSeqAIJRegister - - Adds a new sub-matrix type for sequential AIJ matrices 51434099cc6bSBarry Smith 51444099cc6bSBarry Smith Not Collective 51454099cc6bSBarry Smith 51464099cc6bSBarry Smith Input Parameters: 51474099cc6bSBarry Smith + name - name of a new user-defined matrix type, for example MATSEQAIJCRL 51484099cc6bSBarry Smith - function - routine to convert to subtype 51494099cc6bSBarry Smith 51504099cc6bSBarry Smith Notes: 51514099cc6bSBarry Smith MatSeqAIJRegister() may be called multiple times to add several user-defined solvers. 51524099cc6bSBarry Smith 51534099cc6bSBarry Smith 51544099cc6bSBarry Smith Then, your matrix can be chosen with the procedural interface at runtime via the option 51554099cc6bSBarry Smith $ -mat_seqaij_type my_mat 51564099cc6bSBarry Smith 51574099cc6bSBarry Smith Level: advanced 51584099cc6bSBarry Smith 51594099cc6bSBarry Smith .seealso: MatSeqAIJRegisterAll() 51604099cc6bSBarry Smith 51614099cc6bSBarry Smith 51624099cc6bSBarry Smith Level: advanced 51634099cc6bSBarry Smith @*/ 5164388d47a6SSatish Balay PetscErrorCode MatSeqAIJRegister(const char sname[],PetscErrorCode (*function)(Mat,MatType,MatReuse,Mat *)) 51654099cc6bSBarry Smith { 51664099cc6bSBarry Smith PetscErrorCode ierr; 51674099cc6bSBarry Smith 51684099cc6bSBarry Smith PetscFunctionBegin; 51699cc31a68SJed Brown ierr = MatInitializePackage();CHKERRQ(ierr); 51704099cc6bSBarry Smith ierr = PetscFunctionListAdd(&MatSeqAIJList,sname,function);CHKERRQ(ierr); 51714099cc6bSBarry Smith PetscFunctionReturn(0); 51724099cc6bSBarry Smith } 51734099cc6bSBarry Smith 51744099cc6bSBarry Smith PetscBool MatSeqAIJRegisterAllCalled = PETSC_FALSE; 51754099cc6bSBarry Smith 51764099cc6bSBarry Smith /*@C 51774099cc6bSBarry Smith MatSeqAIJRegisterAll - Registers all of the matrix subtypes of SeqAIJ 51784099cc6bSBarry Smith 51794099cc6bSBarry Smith Not Collective 51804099cc6bSBarry Smith 51814099cc6bSBarry Smith Level: advanced 51824099cc6bSBarry Smith 5183f719121fSJed Brown Developers Note: CUSPARSE does not yet support the MatConvert_SeqAIJ..() paradigm and thus cannot be registered here 51844099cc6bSBarry Smith 51854099cc6bSBarry Smith .seealso: MatRegisterAll(), MatSeqAIJRegister() 51864099cc6bSBarry Smith @*/ 51874099cc6bSBarry Smith PetscErrorCode MatSeqAIJRegisterAll(void) 51884099cc6bSBarry Smith { 51894099cc6bSBarry Smith PetscErrorCode ierr; 51904099cc6bSBarry Smith 51914099cc6bSBarry Smith PetscFunctionBegin; 51924099cc6bSBarry Smith if (MatSeqAIJRegisterAllCalled) PetscFunctionReturn(0); 51934099cc6bSBarry Smith MatSeqAIJRegisterAllCalled = PETSC_TRUE; 51944099cc6bSBarry Smith 51954099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJCRL, MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 51964099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATSEQAIJPERM, MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 51974dfdc2d9SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJSELL, MatConvert_SeqAIJ_SeqAIJSELL);CHKERRQ(ierr); 51989779e05dSSatish Balay #if defined(PETSC_HAVE_MKL_SPARSE) 51996b62b571SRichard Tran Mills ierr = MatSeqAIJRegister(MATSEQAIJMKL, MatConvert_SeqAIJ_SeqAIJMKL);CHKERRQ(ierr); 5200485f9817SRichard Tran Mills #endif 52014099cc6bSBarry Smith #if defined(PETSC_HAVE_VIENNACL) && defined(PETSC_HAVE_VIENNACL_NO_CUDA) 52024099cc6bSBarry Smith ierr = MatSeqAIJRegister(MATMPIAIJVIENNACL, MatConvert_SeqAIJ_SeqAIJViennaCL);CHKERRQ(ierr); 52034099cc6bSBarry Smith #endif 52044099cc6bSBarry Smith PetscFunctionReturn(0); 52054099cc6bSBarry Smith } 520653dd7562SDmitry Karpeev 520753dd7562SDmitry Karpeev /* 520881824310SBarry Smith Special version for direct calls from Fortran 520981824310SBarry Smith */ 5210af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 521181824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 521281824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 521381824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 521481824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 521581824310SBarry Smith #endif 521681824310SBarry Smith 521781824310SBarry Smith /* Change these macros so can be used in void function */ 521881824310SBarry Smith #undef CHKERRQ 5219ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 522081824310SBarry Smith #undef SETERRQ2 5221e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 52224994cf47SJed Brown #undef SETERRQ3 52234994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 522481824310SBarry Smith 522519caf8f3SSatish Balay PETSC_EXTERN void matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 522681824310SBarry Smith { 522781824310SBarry Smith Mat A = *AA; 522881824310SBarry Smith PetscInt m = *mm, n = *nn; 522981824310SBarry Smith InsertMode is = *isis; 523081824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 523181824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 523281824310SBarry Smith PetscInt *imax,*ai,*ailen; 523381824310SBarry Smith PetscErrorCode ierr; 523481824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 523554f21887SBarry Smith MatScalar *ap,value,*aa; 5236ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 5237ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 523881824310SBarry Smith 523981824310SBarry Smith PetscFunctionBegin; 52404994cf47SJed Brown MatCheckPreallocated(A,1); 524181824310SBarry Smith imax = a->imax; 524281824310SBarry Smith ai = a->i; 524381824310SBarry Smith ailen = a->ilen; 524481824310SBarry Smith aj = a->j; 524581824310SBarry Smith aa = a->a; 524681824310SBarry Smith 524781824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 524881824310SBarry Smith row = im[k]; 524981824310SBarry Smith if (row < 0) continue; 5250cf9c20a2SJed Brown if (PetscUnlikelyDebug(row >= A->rmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 525181824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 525281824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 525381824310SBarry Smith low = 0; 525481824310SBarry Smith high = nrow; 525581824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 525681824310SBarry Smith if (in[l] < 0) continue; 5257cf9c20a2SJed Brown if (PetscUnlikelyDebug(in[l] >= A->cmap->n)) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 525881824310SBarry Smith col = in[l]; 52592205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 52602205254eSKarl Rupp else value = v[k + l*m]; 52612205254eSKarl Rupp 526281824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 526381824310SBarry Smith 52642205254eSKarl Rupp if (col <= lastcol) low = 0; 52652205254eSKarl Rupp else high = nrow; 526681824310SBarry Smith lastcol = col; 526781824310SBarry Smith while (high-low > 5) { 526881824310SBarry Smith t = (low+high)/2; 526981824310SBarry Smith if (rp[t] > col) high = t; 527081824310SBarry Smith else low = t; 527181824310SBarry Smith } 527281824310SBarry Smith for (i=low; i<high; i++) { 527381824310SBarry Smith if (rp[i] > col) break; 527481824310SBarry Smith if (rp[i] == col) { 527581824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 527681824310SBarry Smith else ap[i] = value; 527781824310SBarry Smith goto noinsert; 527881824310SBarry Smith } 527981824310SBarry Smith } 528081824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 528181824310SBarry Smith if (nonew == 1) goto noinsert; 5282ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 5283fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 528481824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 528581824310SBarry Smith /* shift up all the later entries in this row */ 528681824310SBarry Smith for (ii=N; ii>=i; ii--) { 528781824310SBarry Smith rp[ii+1] = rp[ii]; 528881824310SBarry Smith ap[ii+1] = ap[ii]; 528981824310SBarry Smith } 529081824310SBarry Smith rp[i] = col; 529181824310SBarry Smith ap[i] = value; 5292e56f5c9eSBarry Smith A->nonzerostate++; 529381824310SBarry Smith noinsert:; 529481824310SBarry Smith low = i + 1; 529581824310SBarry Smith } 529681824310SBarry Smith ailen[row] = nrow; 529781824310SBarry Smith } 529881824310SBarry Smith PetscFunctionReturnVoid(); 529981824310SBarry Smith } 5300