void PetscMatrix<Scalar>::alloc() { assert(this->pages != nullptr); // calc nnz int *nnz_array = malloc_with_check(this->size, this); // fill in nnz_array int aisize = this->get_num_indices(); int *ai = malloc_with_check(aisize, this); // sort the indices and remove duplicities, insert into ai int pos = 0; for (unsigned int i = 0; i < this->size; i++) { nnz_array[i] = this->sort_and_store_indices(this->pages[i], ai + pos, ai + aisize); pos += nnz_array[i]; } // stote the number of nonzeros nnz = pos; free_with_check(this->pages; this->pages = nullptr); free_with_check(ai); // MatCreateSeqAIJ(PETSC_COMM_SELF, this->size, this->size, 0, nnz_array, &matrix); // MatSetOption(matrix, MAT_ROW_ORIENTED); // MatSetOption(matrix, MAT_ROWS_SORTED); free_with_check(nnz_array); inited = true; }
int main(int argc,char **args) { const PetscInt inds[] = {0,1}; PetscScalar avals[] = {2,3,5,7}; Mat S; User user; PetscErrorCode ierr; Vec base; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscNew(&user);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,2,2,2,NULL,&user->B);CHKERRQ(ierr); ierr = MatSetUp(user->B);CHKERRQ(ierr); ierr = MatSetValues(user->B,2,inds,2,inds,avals,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(user->B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(user->B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatCreateVecs(user->B,&base,NULL);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,2,2,2,2,user,&S);CHKERRQ(ierr); ierr = MatSetUp(S);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User);CHKERRQ(ierr); ierr = MatShellTestMult(S,MyFunction,base,user,NULL);CHKERRQ(ierr); ierr = MatShellTestMultTranspose(S,MyFunction,base,user,NULL);CHKERRQ(ierr); ierr = VecDestroy(&base);CHKERRQ(ierr); ierr = MatDestroy(&user->B);CHKERRQ(ierr); ierr = MatDestroy(&S);CHKERRQ(ierr); ierr = PetscFree(user);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
void PetscMatrix::alloc() { _F_ #ifdef WITH_PETSC assert(pages != NULL); // calc nnz int *nnz_array = new int[size]; MEM_CHECK(nnz_array); // fill in nnz_array int aisize = get_num_indices(); int *ai = new int[aisize]; MEM_CHECK(ai); // sort the indices and remove duplicities, insert into ai int pos = 0; for (unsigned int i = 0; i < size; i++) { nnz_array[i] = sort_and_store_indices(pages[i], ai + pos, ai + aisize); pos += nnz_array[i]; } // stote the number of nonzeros nnz = pos; delete [] pages; pages = NULL; delete [] ai; // MatCreateSeqAIJ(PETSC_COMM_SELF, size, size, 0, nnz_array, &matrix); // MatSetOption(matrix, MAT_ROW_ORIENTED); // MatSetOption(matrix, MAT_ROWS_SORTED); delete [] nnz_array; inited = true; #endif }
int main(int argc,char **args) { PC pc; PetscErrorCode ierr; PetscInt n = 5; Mat mat; ierr = PetscInitialize(&argc,&args,(char*)0,help); if (ierr) return ierr; ierr = PCCreate(PETSC_COMM_WORLD,&pc); CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE); CHKERRQ(ierr); /* Vector and matrix must be set before calling PCSetUp */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,&mat); CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat); CHKERRQ(ierr); ierr = PCSetUp(pc); CHKERRQ(ierr); ierr = MatDestroy(&mat); CHKERRQ(ierr); ierr = PCDestroy(&pc); CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **argv) { Mat A,B,As; const PetscInt *ai,*aj; PetscInt i,j,k,nz,n,asi[]={0,2,3,4,6,7}; PetscInt asj[]={0,4,1,2,3,4,4}; PetscScalar asa[7],*aa; PetscRandom rctx; PetscErrorCode ierr; PetscMPIInt size; PetscBool flg; PetscInitialize(&argc,&argv,(char *)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!"); /* Create a aij matrix for checking */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,5,5,2,PETSC_NULL,&A);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_WORLD,&rctx);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rctx);CHKERRQ(ierr); k = 0; for (i=0; i<5; i++) { nz = asi[i+1] - asi[i]; /* length of i_th row of A */ for (j=0; j<nz; j++){ ierr = PetscRandomGetValue(rctx,&asa[k]);CHKERRQ(ierr); ierr = MatSetValues(A,1,&i,1,&asj[k],&asa[k],INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(A,1,&i,1,&asj[k],&asa[k],INSERT_VALUES);CHKERRQ(ierr); if (i != asj[k]){ /* insert symmetric entry */ ierr = MatSetValues(A,1,&asj[k],1,&i,&asa[k],INSERT_VALUES);CHKERRQ(ierr); } k++; } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Create a baij matrix using MatCreateSeqBAIJWithArrays() */ ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ai,&aj,&flg);CHKERRQ(ierr); ierr = MatSeqAIJGetArray(A,&aa);CHKERRQ(ierr); /* WARNING: This sharing is dangerous if either A or B is later assembled */ ierr = MatCreateSeqBAIJWithArrays(PETSC_COMM_SELF,1,5,5,(PetscInt*)ai,(PetscInt*)aj,aa,&B);CHKERRQ(ierr); ierr = MatSeqAIJRestoreArray(A,&aa);CHKERRQ(ierr); ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ai,&aj,&flg);CHKERRQ(ierr); ierr = MatMultEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"MatMult(A,B) are NOT equal"); /* Create a sbaij matrix using MatCreateSeqSBAIJWithArrays() */ ierr = MatCreateSeqSBAIJWithArrays(PETSC_COMM_SELF,1,5,5,asi,asj,asa,&As);CHKERRQ(ierr); ierr = MatMultEqual(A,As,10,&flg);CHKERRQ(ierr); if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMETYPE,"MatMult(A,As) are NOT equal"); /* Free spaces */ ierr = PetscRandomDestroy(&rctx);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&As);CHKERRQ(ierr); ierr = PetscFinalize(); return(0); }
PetscErrorCode InitializeProblem(AppCtx *user) { PetscErrorCode ierr; PetscFunctionBegin; user->n = 2; ierr = VecCreateSeq(PETSC_COMM_SELF,user->n,&user->x); CHKERRQ(ierr); ierr = VecDuplicate(user->x,&user->xl); CHKERRQ(ierr); ierr = VecDuplicate(user->x,&user->xu); CHKERRQ(ierr); ierr = VecSet(user->x,0.0); CHKERRQ(ierr); ierr = VecSet(user->xl,-1.0); CHKERRQ(ierr); ierr = VecSet(user->xu,2.0); CHKERRQ(ierr); user->ne = 1; ierr = VecCreateSeq(PETSC_COMM_SELF,user->ne,&user->ce); CHKERRQ(ierr); user->ni = 2; ierr = VecCreateSeq(PETSC_COMM_SELF,user->ni,&user->ci); CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,user->ne,user->n,user->n,NULL,&user->Ae); CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,user->ni,user->n,user->n,NULL,&user->Ai); CHKERRQ(ierr); ierr = MatSetFromOptions(user->Ae); CHKERRQ(ierr); ierr = MatSetFromOptions(user->Ai); CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,user->n,user->n,1,NULL,&user->H); CHKERRQ(ierr); ierr = MatSetFromOptions(user->H); CHKERRQ(ierr); CHKERRQ(ierr); PetscFunctionReturn(0); }
void Field_solver::alloc_petsc_matrix_seqaij( Mat *A, PetscInt nrow, PetscInt ncol, PetscInt nonzero_per_row ) { PetscErrorCode ierr; ierr = MatCreateSeqAIJ( PETSC_COMM_SELF, nrow, ncol, nonzero_per_row, NULL, A ); CHKERRXX( ierr ); ierr = MatSetUp( *A ); CHKERRXX( ierr ); return; }
int main(int argc,char **args) { Mat A,B,*Bsub; PetscInt i,j,m = 6,n = 6,N = 36,Ii,J; PetscErrorCode ierr; PetscScalar v; IS isrow; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,N,N,5,NULL,&A);CHKERRQ(ierr); for (i=0; i<m; i++) { for (j=0; j<n; j++) { v = -1.0; Ii = j + n*i; if (i>0) {J = Ii - n; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(A,1,&Ii,1,&Ii,&v,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatView(A,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); /* take the first diagonal block */ ierr = ISCreateStride(PETSC_COMM_WORLD,m,0,1,&isrow);CHKERRQ(ierr); ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&Bsub);CHKERRQ(ierr); B = *Bsub; ierr = PetscFree(Bsub);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); /* take a strided block */ ierr = ISCreateStride(PETSC_COMM_WORLD,m,0,2,&isrow);CHKERRQ(ierr); ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&Bsub);CHKERRQ(ierr); B = *Bsub; ierr = PetscFree(Bsub);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); /* take the last block */ ierr = ISCreateStride(PETSC_COMM_WORLD,m,N-m-1,1,&isrow);CHKERRQ(ierr); ierr = MatGetSubMatrices(A,1,&isrow,&isrow,MAT_INITIAL_MATRIX,&Bsub);CHKERRQ(ierr); B = *Bsub; ierr = PetscFree(Bsub);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = MatView(B,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = MatDestroy(&B);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
void FEMAssemble2DElasticity(MPI_Comm comm, Mesh *mesh, Mat &A, Vec &b, PetscReal E, PetscReal mi, PetscReal(*dens)(Element *), void(*f)(Element*, PetscReal, PetscReal*)) { PetscInt rank; MPI_Comm_rank(comm, &rank); PetscInt size = mesh->vetrices.size(); MatCreateSeqAIJ(PETSC_COMM_SELF, size * 2, size * 2, 14, PETSC_NULL, &A); VecCreateMPI(comm, size * 2, PETSC_DECIDE, &b); for (std::map<PetscInt, Element*>::iterator e = mesh->elements.begin(); e != mesh->elements.end(); e++) { Point* vetrices[3]; PetscInt vIndex[3]; for (int i = 0; i < 3; i++) { vIndex[i] = e->second->vetrices[i]; vetrices[i] = mesh->vetrices[vIndex[i]]; } PetscReal lStiff[36]; PetscReal bLoc[6]; //Local stiffness matrix and force vector assembly PetscReal fs[2]; f(e->second, dens(e->second), fs); elastLoc(vetrices, E, mi, fs, lStiff, bLoc); PetscInt idx[6], idxLoc[6]; for (int i = 0; i < 3; i++) { idx[i * 2] = vIndex[i] * 2; idx[i * 2 + 1] = vIndex[i] * 2 + 1; idxLoc[i * 2] = vIndex[i] * 2 - mesh->startIndexes[rank] * 2; idxLoc[i * 2 + 1] = vIndex[i] * 2 + 1 - mesh->startIndexes[rank] * 2; } MatSetValues(A, 6, idxLoc, 6, idxLoc, lStiff, ADD_VALUES); VecSetValues(b, 6, idx, bLoc, ADD_VALUES); } VecAssemblyBegin(b); VecAssemblyEnd(b); MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); }
int main(int argc,char **args) { const PetscScalar xvals[] = {11,13},yvals[] = {17,19}; const PetscInt inds[] = {0,1}; PetscScalar avals[] = {2,3,5,7}; Mat S1,S2; Vec X,Y; User user; PetscErrorCode ierr; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = PetscNew(&user);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,2,2,2,NULL,&user->A);CHKERRQ(ierr); ierr = MatSetUp(user->A);CHKERRQ(ierr); ierr = MatSetValues(user->A,2,inds,2,inds,avals,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(user->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(user->A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_WORLD,2,&X);CHKERRQ(ierr); ierr = VecSetValues(X,2,inds,xvals,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(X);CHKERRQ(ierr); ierr = VecAssemblyEnd(X);CHKERRQ(ierr); ierr = VecDuplicate(X,&Y);CHKERRQ(ierr); ierr = VecSetValues(Y,2,inds,yvals,INSERT_VALUES);CHKERRQ(ierr); ierr = VecAssemblyBegin(Y);CHKERRQ(ierr); ierr = VecAssemblyEnd(Y);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,2,2,2,2,user,&S1);CHKERRQ(ierr); ierr = MatSetUp(S1);CHKERRQ(ierr); ierr = MatShellSetOperation(S1,MATOP_MULT,(void (*)(void))MatMult_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S1,MATOP_COPY,(void (*)(void))MatCopy_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S1,MATOP_DESTROY,(void (*)(void))MatDestroy_User);CHKERRQ(ierr); ierr = MatCreateShell(PETSC_COMM_WORLD,2,2,2,2,NULL,&S2);CHKERRQ(ierr); ierr = MatSetUp(S2);CHKERRQ(ierr); ierr = MatShellSetOperation(S2,MATOP_MULT,(void (*)(void))MatMult_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S2,MATOP_COPY,(void (*)(void))MatCopy_User);CHKERRQ(ierr); ierr = MatShellSetOperation(S2,MATOP_DESTROY,(void (*)(void))MatDestroy_User);CHKERRQ(ierr); ierr = MatScale(S1,31);CHKERRQ(ierr); ierr = MatShift(S1,37);CHKERRQ(ierr); ierr = MatDiagonalScale(S1,X,Y);CHKERRQ(ierr); ierr = MatCopy(S1,S2,SAME_NONZERO_PATTERN);CHKERRQ(ierr); ierr = MatMult(S1,X,Y);CHKERRQ(ierr); ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatMult(S2,X,Y);CHKERRQ(ierr); ierr = VecView(Y,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatDestroy(&S1);CHKERRQ(ierr); ierr = MatDestroy(&S2);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&Y);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
PetscErrorCode PadMatrix(Mat A,Vec v,PetscScalar c,Mat *B) { PetscErrorCode ierr; PetscInt n = A->rmap->n,i,*cnt,*indices; Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; PetscScalar *vv; PetscFunctionBegin; ierr = VecGetArray(v,&vv); CHKERRQ(ierr); ierr = PetscMalloc(n*sizeof(PetscInt),&indices); CHKERRQ(ierr); for (i=0; i<n; i++) indices[i] = i; /* determine number of nonzeros per row in the new matrix */ ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cnt); CHKERRQ(ierr); for (i=0; i<n; i++) { cnt[i] = aij->i[i+1] - aij->i[i] + (vv[i] != 0.0); } cnt[n] = 1; for (i=0; i<n; i++) { cnt[n] += (vv[i] != 0.0); } ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n+1,n+1,0,cnt,B); CHKERRQ(ierr); ierr = MatSetOption(*B,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE); CHKERRQ(ierr); /* copy over the matrix entries from the matrix and then the vector */ for (i=0; i<n; i++) { ierr = MatSetValues(*B,1,&i,aij->i[i+1] - aij->i[i],aij->j + aij->i[i],aij->a + aij->i[i],INSERT_VALUES); CHKERRQ(ierr); } ierr = MatSetValues(*B,1,&n,n,indices,vv,INSERT_VALUES); CHKERRQ(ierr); ierr = MatSetValues(*B,n,indices,1,&n,vv,INSERT_VALUES); CHKERRQ(ierr); ierr = MatSetValues(*B,1,&n,1,&n,&c,INSERT_VALUES); CHKERRQ(ierr); ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = VecRestoreArray(v,&vv); CHKERRQ(ierr); ierr = PetscFree(cnt); CHKERRQ(ierr); ierr = PetscFree(indices); CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode TaoPounders(AppCtx *user) { PetscErrorCode ierr; Tao tao; Vec X, F; Mat J; char buf[1024]; PetscFunctionBegin; /* Set the values for the algorithm options we want to use */ sprintf(buf,"%d",user->nfmax); ierr = PetscOptionsSetValue(NULL,"-tao_max_funcs",buf);CHKERRQ(ierr); sprintf(buf,"%d",user->npmax); ierr = PetscOptionsSetValue(NULL,"-tao_pounders_npmax",buf);CHKERRQ(ierr); sprintf(buf,"%5.4e",user->delta); ierr = PetscOptionsSetValue(NULL,"-tao_pounders_delta",buf);CHKERRQ(ierr); /* Create the TAO objects and set the type */ ierr = TaoCreate(PETSC_COMM_SELF,&tao);CHKERRQ(ierr); /* Create starting point and initialize */ ierr = VecCreateSeq(PETSC_COMM_SELF,user->n,&X);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)X,"X0");CHKERRQ(ierr); ierr = PetscMatlabEngineGet(user->mengine,(PetscObject)X);CHKERRQ(ierr); ierr = TaoSetInitialVector(tao,X);CHKERRQ(ierr); /* Create residuals vector and set residual function */ ierr = VecCreateSeq(PETSC_COMM_SELF,user->m,&F);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)F,"F");CHKERRQ(ierr); ierr = TaoSetResidualRoutine(tao,F,EvaluateResidual,(void*)user);CHKERRQ(ierr); /* Create Jacobian matrix and set residual Jacobian routine */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,user->m,user->n,user->n,NULL,&J);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)J,"J");CHKERRQ(ierr); ierr = TaoSetResidualJacobianRoutine(tao,J,J,EvaluateJacobian,(void*)user);CHKERRQ(ierr); /* Solve the problem */ ierr = TaoSetType(tao,TAOPOUNDERS);CHKERRQ(ierr); ierr = TaoSetFromOptions(tao);CHKERRQ(ierr); ierr = TaoSolve(tao);CHKERRQ(ierr); /* Finish the problem */ ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = TaoDestroy(&tao);CHKERRQ(ierr); PetscFunctionReturn(0); }
int MatRead(char *fileA, PetscInt& n, Mat& A) { PetscInt *arrayIA, *arrayJA, // arrays of rows and columns of A *nnzA, // number of nonzeros in each row nzA; // number of nonzeros in matrix A PetscScalar *arrayVA; // array of values of A int read_error = 0; if (readSparseMatrix(fileA, n, nzA, nnzA, arrayIA, arrayJA, arrayVA)) { // read_error in reading in the vector, set read_error to 1 read_error = 1; } /*--------------------------------------------------------------------------- * set up the matrix A *---------------------------------------------------------------------------*/ MatCreateSeqAIJ(MPI_COMM_SELF, n, n, nzA, nnzA, &A); /*--------------------------------------------------------------------------- * set the values of matrix A *---------------------------------------------------------------------------*/ /* PetscMalloc1(n * sizeof(PetscInt), &idx); for (PetscInt i = 0; i < n; ++i) { idx[i] = i; } MatSetValues(A, n, idx, n, idx, arrayA, INSERT_VALUES); */ for (PetscInt i = 0; i < nzA; ++i) { MatSetValue(A, arrayIA[i], arrayJA[i], arrayVA[i], INSERT_VALUES); if (arrayIA[i] != arrayJA[i]) { MatSetValue(A, arrayJA[i], arrayIA[i], arrayVA[i], INSERT_VALUES); } } /*--------------------------------------------------------------------------- * assemble the matrix A *---------------------------------------------------------------------------*/ MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY); free(nnzA); free(arrayIA); free(arrayJA); free(arrayVA); }
PetscErrorCode AssemblePoissonPC2(int m, int n, Mat *A) { PetscErrorCode ierr; double *x, *y; PetscFunctionBegin; ierr = MatCreateSeqAIJ(PETSC_COMM_SELF, m*n, m*n, 5, PETSC_NULL, A); CHKERRQ(ierr); ierr = PetscMalloc2(m, double, &x, n, double, &y); CHKERRQ(ierr); for (int i = 0; i < m; i++) x[i] = cos(i * PI / (m - 1)); for (int j = 0; j < n; j++) y[j] = cos(j * PI / (n - 1)); // Strong Dirichlet everywhere, then overwrite with correct values in the interior. for (int I = 0; I < m*n; I++) { ierr = MatSetValue(*A, I, I, 1.0, INSERT_VALUES); CHKERRQ(ierr); } ierr = MatAssemblyBegin(*A,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*A,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); int J[5]; double v[5]; for (int i = 1; i < m - 1; i++) { for (int j = 1; j < n - 1; j++) { const int I = i * n + j; const bool f = true; // const double X = x[I], Y = y[I]; // J[0] = I - n; J[1] = I - 1; J[2] = I; J[3] = I + 1; J[4] = I + n; int k=0; if (f && i != 1) { J[k] = I-n; v[k++] = -1.0 / ((x[i-1] - x[i]) * (x[i-1] - x[i+1])); } if (f && j != 1) { J[k] = I-1; v[k++] = -1.0 / ((y[j-1] - y[j]) * (y[j-1] - y[j+1])); } J[k] = I; v[k++] = -( 1.0 / ((x[i] - x[i-1]) * (x[i] - x[i+1])) + 1.0 / ((y[j] - y[j-1]) * (y[j] - y[j+1]))); if (f && j != n-2) { J[k] = I+1; v[k++] = -1.0 / ((y[j+1] - y[j-1]) * (y[j+1] - y[j])); } if (f && i != m-2) { J[k] = I+n; v[k++] = -1.0 / ((x[i+1] - x[i-1]) * (x[i+1] - x[i])); } ierr = MatSetValues(*A, 1, &I, k, J, v, INSERT_VALUES); CHKERRQ(ierr); } } ierr = MatAssemblyBegin(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscFree2(x, y); CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { PC pc; PetscErrorCode ierr; PetscInt n = 5; Mat mat; PetscInitialize(&argc,&args,(char *)0,help); ierr = PCCreate(PETSC_COMM_WORLD,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCNONE);CHKERRQ(ierr); /* Vector and matrix must be set before calling PCSetUp */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,PETSC_NULL,&mat);CHKERRQ(ierr); ierr = PCSetOperators(pc,mat,mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = PCSetUp(pc);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); ierr = PCDestroy(&pc); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
op_mat op_decl_mat( op_sparsity sparsity, int dim, char const * type, int type_size, char const * name ) { assert( sparsity ); op_mat mat = op_decl_mat_core ( sparsity->rowmap->to, sparsity->colmap->to, dim, type, type_size, name ); Mat p_mat; // Create a PETSc CSR sparse matrix and pre-allocate storage MatCreateSeqAIJ(PETSC_COMM_SELF, sparsity->nrows, sparsity->ncols, sparsity->max_nonzeros, (const PetscInt*)sparsity->nnz, &p_mat); // Set the column indices (FIXME: benchmark if this is worth it) MatSeqAIJSetColumnIndices(p_mat, (PetscInt*)sparsity->colidx); MatZeroEntries(p_mat); mat->mat = p_mat; return mat; }
PetscErrorCode Create1dLaplacian(PetscInt n,Mat *mat) { PetscScalar mone = -1.0,two = 2.0; PetscInt i,idx; PetscErrorCode ierr; PetscFunctionBegin; ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,n,n,3,NULL,mat);CHKERRQ(ierr); idx = n-1; ierr = MatSetValues(*mat,1,&idx,1,&idx,&two,INSERT_VALUES);CHKERRQ(ierr); for (i=0; i<n-1; i++) { ierr = MatSetValues(*mat,1,&i,1,&i,&two,INSERT_VALUES);CHKERRQ(ierr); idx = i+1; ierr = MatSetValues(*mat,1,&idx,1,&i,&mone,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(*mat,1,&i,1,&idx,&mone,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat A; PetscErrorCode ierr; PetscInt m = 100,n = 11,js[11],i,j,cnt; PetscScalar values[11]; PetscViewer view; PetscInitialize(&argc,&args,(char *)0,help); ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,m,n,20,0,&A);CHKERRQ(ierr); for (i=0; i<n; i++) values[i] = (PetscReal)i; for (i=0; i<m; i++) { cnt = 0; if (i % 2) { for (j=0; j<n; j += 2) { js[cnt++] = j; } } else { ; } ierr = MatSetValues(A,1,&i,cnt,js,values,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,"rect",FILE_MODE_WRITE,&view);CHKERRQ(ierr); ierr = MatView(A,view);CHKERRQ(ierr); ierr = PetscViewerDestroy(&view);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat C,A; PetscInt i,j,m = 5,n = 5,Ii,J; PetscErrorCode ierr; PetscScalar v,five = 5.0,one = 1.0; IS isrow,row,col; Vec x,u,b; PetscReal norm; MatFactorInfo info; PetscInitialize(&argc,&args,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,"-n",&n,NULL);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,m*n,m*n,5,NULL,&C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); /* create the matrix for the five point stencil, YET AGAIN*/ for (i=0; i<m; i++) { for (j=0; j<n; j++) { v = -1.0; Ii = j + n*i; if (i>0) {J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (i<m-1) {J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j>0) {J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} if (j<n-1) {J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES);CHKERRQ(ierr);} v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = ISCreateStride(PETSC_COMM_SELF,(m*n)/2,0,2,&isrow);CHKERRQ(ierr); ierr = MatZeroRowsIS(C,isrow,five,0,0);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,m*n,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&x);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecSet(u,one);CHKERRQ(ierr); ierr = MatMultTranspose(C,u,b);CHKERRQ(ierr); /* Set default ordering to be Quotient Minimum Degree; also read orderings from the options database */ ierr = MatGetOrdering(C,MATORDERINGQMD,&row,&col);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info);CHKERRQ(ierr); ierr = MatGetFactor(C,MATSOLVERPETSC,MAT_FACTOR_LU,&A);CHKERRQ(ierr); ierr = MatLUFactorSymbolic(A,C,row,col,&info);CHKERRQ(ierr); ierr = MatLUFactorNumeric(A,C,&info);CHKERRQ(ierr); ierr = MatSolveTranspose(A,b,x);CHKERRQ(ierr); ierr = ISView(row,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); ierr = VecAXPY(x,-1.0,u);CHKERRQ(ierr); ierr = VecNorm(x,NORM_2,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Norm of error %g\n",(double)norm);CHKERRQ(ierr); ierr = ISDestroy(&row);CHKERRQ(ierr); ierr = ISDestroy(&col);CHKERRQ(ierr); ierr = ISDestroy(&isrow);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Mat C; PetscErrorCode ierr; PetscInt i,m = 2,N,M,idx[4],Nsub1,Nsub2,ol=1,x1,x2; PetscScalar Ke[16]; PetscReal x,y,h; IS *is1,*is2; PetscBool flg; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL); CHKERRQ(ierr); N = (m+1)*(m+1); /* dimension of matrix */ M = m*m; /* number of elements */ h = 1.0/m; /* mesh width */ x1= (m+1)/2; x2= x1; ierr = PetscOptionsGetInt(PETSC_NULL,"-x1",&x1,PETSC_NULL); CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-x2",&x2,PETSC_NULL); CHKERRQ(ierr); /* create stiffness matrix */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,N,N,9,PETSC_NULL,&C); CHKERRQ(ierr); /* forms the element stiffness for the Laplacian */ ierr = FormElementStiffness(h*h,Ke); CHKERRQ(ierr); for (i=0; i<M; i++) { /* location of lower left corner of element */ x = h*(i % m); y = h*(i/m); /* node numbers for the four corners of element */ idx[0] = (m+1)*(i/m) + (i % m); idx[1] = idx[0]+1; idx[2] = idx[1] + m + 1; idx[3] = idx[2] - 1; ierr = MatSetValues(C,4,idx,4,idx,Ke,ADD_VALUES); CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); for (ol=0; ol<m+2; ++ol) { ierr = PCASMCreateSubdomains2D(m+1,m+1,x1,x2,1,0,&Nsub1,&is1); CHKERRQ(ierr); ierr = MatIncreaseOverlap(C,Nsub1,is1,ol); CHKERRQ(ierr); ierr = PCASMCreateSubdomains2D(m+1,m+1,x1,x2,1,ol,&Nsub2,&is2); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"flg == 1 => both index sets are same\n"); CHKERRQ(ierr); if(Nsub1 != Nsub2) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: No of indes sets don't match\n"); CHKERRQ(ierr); } for (i=0; i<Nsub1; ++i) { ierr = ISEqual(is1[i],is2[i],&flg); CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"i = %D,flg = %d \n",i,(int)flg); CHKERRQ(ierr); } for (i=0; i<Nsub1; ++i) { ierr = ISDestroy(&&is1[i]); CHKERRQ(ierr); } for (i=0; i<Nsub2; ++i) { ierr = ISDestroy(&&is2[i]); CHKERRQ(ierr); } ierr = PetscFree(is1); CHKERRQ(ierr); ierr = PetscFree(is2); CHKERRQ(ierr); } ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
/* GetElasticityMatrix - Forms 3D linear elasticity matrix. */ PetscErrorCode GetElasticityMatrix(PetscInt m,Mat *newmat) { PetscInt i,j,k,i1,i2,j_1,j2,k1,k2,h1,h2,shiftx,shifty,shiftz; PetscInt ict,nz,base,r1,r2,N,*rowkeep,nstart; PetscErrorCode ierr; IS iskeep; PetscReal **K,norm; Mat mat,submat = 0,*submatb; MatType type = MATSEQBAIJ; m /= 2; /* This is done just to be consistent with the old example */ N = 3*(2*m+1)*(2*m+1)*(2*m+1); ierr = PetscPrintf(PETSC_COMM_SELF,"m = %D, N=%D\n",m,N);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,N,N,80,PETSC_NULL,&mat);CHKERRQ(ierr); /* Form stiffness for element */ ierr = PetscMalloc(81*sizeof(PetscReal *),&K);CHKERRQ(ierr); for (i=0; i<81; i++) { ierr = PetscMalloc(81*sizeof(PetscReal),&K[i]);CHKERRQ(ierr); } ierr = Elastic20Stiff(K);CHKERRQ(ierr); /* Loop over elements and add contribution to stiffness */ shiftx = 3; shifty = 3*(2*m+1); shiftz = 3*(2*m+1)*(2*m+1); for (k=0; k<m; k++) { for (j=0; j<m; j++) { for (i=0; i<m; i++) { h1 = 0; base = 2*k*shiftz + 2*j*shifty + 2*i*shiftx; for (k1=0; k1<3; k1++) { for (j_1=0; j_1<3; j_1++) { for (i1=0; i1<3; i1++) { h2 = 0; r1 = base + i1*shiftx + j_1*shifty + k1*shiftz; for (k2=0; k2<3; k2++) { for (j2=0; j2<3; j2++) { for (i2=0; i2<3; i2++) { r2 = base + i2*shiftx + j2*shifty + k2*shiftz; ierr = AddElement(mat,r1,r2,K,h1,h2);CHKERRQ(ierr); h2 += 3; } } } h1 += 3; } } } } } } for (i=0; i<81; i++) { ierr = PetscFree(K[i]);CHKERRQ(ierr); } ierr = PetscFree(K);CHKERRQ(ierr); ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Exclude any superfluous rows and columns */ nstart = 3*(2*m+1)*(2*m+1); ict = 0; ierr = PetscMalloc((N-nstart)*sizeof(PetscInt),&rowkeep);CHKERRQ(ierr); for (i=nstart; i<N; i++) { ierr = MatGetRow(mat,i,&nz,0,0);CHKERRQ(ierr); if (nz) rowkeep[ict++] = i; ierr = MatRestoreRow(mat,i,&nz,0,0);CHKERRQ(ierr); } ierr = ISCreateGeneral(PETSC_COMM_SELF,ict,rowkeep,PETSC_COPY_VALUES,&iskeep);CHKERRQ(ierr); ierr = MatGetSubMatrices(mat,1,&iskeep,&iskeep,MAT_INITIAL_MATRIX,&submatb);CHKERRQ(ierr); submat = *submatb; ierr = PetscFree(submatb);CHKERRQ(ierr); ierr = PetscFree(rowkeep);CHKERRQ(ierr); ierr = ISDestroy(&iskeep);CHKERRQ(ierr); ierr = MatDestroy(&mat);CHKERRQ(ierr); /* Convert storage formats -- just to demonstrate conversion to various formats (in particular, block diagonal storage). This is NOT the recommended means to solve such a problem. */ ierr = MatConvert(submat,type,MAT_INITIAL_MATRIX,newmat);CHKERRQ(ierr); ierr = MatDestroy(&submat);CHKERRQ(ierr); ierr = PetscViewerSetFormat(PETSC_VIEWER_STDOUT_WORLD,PETSC_VIEWER_ASCII_INFO);CHKERRQ(ierr); ierr = MatView(*newmat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = MatNorm(*newmat,NORM_1,&norm);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"matrix 1 norm = %G\n",norm);CHKERRQ(ierr); return 0; }
int main(int argc,char **args) { Mat C,Cperm; PetscInt i,j,m = 5,n = 5,Ii,J,ncols; PetscErrorCode ierr; PetscScalar v; PetscMPIInt size; IS rperm,cperm,icperm; const PetscInt *rperm_ptr,*cperm_ptr,*cols; const PetscScalar *vals; PetscBool TestMyorder=PETSC_FALSE; PetscInitialize(&argc,&args,(char*)0,help); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,PETSC_ERR_SUP,"This is a uniprocessor example only!"); /* create the matrix for the five point stencil, YET AGAIN */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,m*n,m*n,5,NULL,&C); ierr = MatSetUp(C); CHKERRQ(ierr); for (i=0; i<m; i++) { for (j=0; j<n; j++) { v = -1.0; Ii = j + n*i; if (i>0) { J = Ii - n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES); CHKERRQ(ierr); } if (i<m-1) { J = Ii + n; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES); CHKERRQ(ierr); } if (j>0) { J = Ii - 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES); CHKERRQ(ierr); } if (j<n-1) { J = Ii + 1; ierr = MatSetValues(C,1,&Ii,1,&J,&v,INSERT_VALUES); CHKERRQ(ierr); } v = 4.0; ierr = MatSetValues(C,1,&Ii,1,&Ii,&v,INSERT_VALUES); CHKERRQ(ierr); } } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatGetOrdering(C,MATORDERINGND,&rperm,&cperm); CHKERRQ(ierr); ierr = ISView(rperm,PETSC_VIEWER_STDOUT_SELF); CHKERRQ(ierr); ierr = ISDestroy(&rperm); CHKERRQ(ierr); ierr = ISDestroy(&cperm); CHKERRQ(ierr); ierr = MatGetOrdering(C,MATORDERINGRCM,&rperm,&cperm); CHKERRQ(ierr); ierr = ISView(rperm,PETSC_VIEWER_STDOUT_SELF); CHKERRQ(ierr); ierr = ISDestroy(&rperm); CHKERRQ(ierr); ierr = ISDestroy(&cperm); CHKERRQ(ierr); ierr = MatGetOrdering(C,MATORDERINGQMD,&rperm,&cperm); CHKERRQ(ierr); ierr = ISView(rperm,PETSC_VIEWER_STDOUT_SELF); CHKERRQ(ierr); ierr = ISDestroy(&rperm); CHKERRQ(ierr); ierr = ISDestroy(&cperm); CHKERRQ(ierr); /* create Cperm = rperm*C*icperm */ ierr = PetscOptionsGetBool(NULL,"-testmyordering",&TestMyorder,NULL); CHKERRQ(ierr); if (TestMyorder) { ierr = MatGetOrdering_myordering(C,MATORDERINGQMD,&rperm,&cperm); CHKERRQ(ierr); printf("myordering's rperm:\n"); ierr = ISView(rperm,PETSC_VIEWER_STDOUT_SELF); CHKERRQ(ierr); ierr = ISInvertPermutation(cperm,PETSC_DECIDE,&icperm); CHKERRQ(ierr); ierr = ISGetIndices(rperm,&rperm_ptr); CHKERRQ(ierr); ierr = ISGetIndices(icperm,&cperm_ptr); CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,m*n,m*n,5,NULL,&Cperm); CHKERRQ(ierr); for (i=0; i<m*n; i++) { ierr = MatGetRow(C,rperm_ptr[i],&ncols,&cols,&vals); CHKERRQ(ierr); for (j=0; j<ncols; j++) { /* printf(" (%d %d %g)\n",i,cperm_ptr[cols[j]],vals[j]); */ ierr = MatSetValues(Cperm,1,&i,1,&cperm_ptr[cols[j]],&vals[j],INSERT_VALUES); CHKERRQ(ierr); } } ierr = MatAssemblyBegin(Cperm,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = MatAssemblyEnd(Cperm,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); ierr = ISRestoreIndices(rperm,&rperm_ptr); CHKERRQ(ierr); ierr = ISRestoreIndices(icperm,&cperm_ptr); CHKERRQ(ierr); ierr = ISDestroy(&rperm); CHKERRQ(ierr); ierr = ISDestroy(&cperm); CHKERRQ(ierr); ierr = ISDestroy(&icperm); CHKERRQ(ierr); ierr = MatDestroy(&Cperm); CHKERRQ(ierr); } ierr = MatDestroy(&C); CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **argv) { KSP ksp; PC pc; Mat A,M; Vec X,B,D; MPI_Comm comm; PetscScalar v; KSPConvergedReason reason; PetscInt i,j,its; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscInitialize(&argc,&argv,0,help);CHKERRQ(ierr); ierr = PetscOptionsSetValue("-options_left",PETSC_NULL);CHKERRQ(ierr); comm = MPI_COMM_SELF; /* * Construct the Kershaw matrix * and a suitable rhs / initial guess */ ierr = MatCreateSeqAIJ(comm,4,4,4,0,&A);CHKERRQ(ierr); ierr = VecCreateSeq(comm,4,&B);CHKERRQ(ierr); ierr = VecDuplicate(B,&X);CHKERRQ(ierr); for (i=0; i<4; i++) { v=3; ierr = MatSetValues(A,1,&i,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); v=1; ierr = VecSetValues(B,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = VecSetValues(X,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); } i=0; v=0; ierr = VecSetValues(X,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); for (i=0; i<3; i++) { v=-2; j=i+1; ierr = MatSetValues(A,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(A,1,&j,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); } i=0; j=3; v=2; ierr = MatSetValues(A,1,&i,1,&j,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(A,1,&j,1,&i,&v,INSERT_VALUES);CHKERRQ(ierr); ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = VecAssemblyBegin(B);CHKERRQ(ierr); ierr = VecAssemblyEnd(B);CHKERRQ(ierr); printf("\nThe Kershaw matrix:\n\n"); MatView(A,0); /* * A Conjugate Gradient method * with ILU(0) preconditioning */ ierr = KSPCreate(comm,&ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,A,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPSetType(ksp,KSPCG);CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); /* * ILU preconditioner; * The iterative method will break down unless you comment in the SetShift * line below, or use the -pc_factor_shift_positive_definite option. * Run the code twice: once as given to see the negative pivot and the * divergence behaviour, then comment in the Shift line, or add the * command line option, and see that the pivots are all positive and * the method converges. */ ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr); ierr = PCSetType(pc,PCICC);CHKERRQ(ierr); /* ierr = PCFactorSetShiftType(prec,MAT_SHIFT_POSITIVE_DEFINITE);CHKERRQ(ierr); */ ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetUp(ksp);CHKERRQ(ierr); /* * Now that the factorisation is done, show the pivots; * note that the last one is negative. This in itself is not an error, * but it will make the iterative method diverge. */ ierr = PCFactorGetMatrix(pc,&M);CHKERRQ(ierr); ierr = VecDuplicate(B,&D);CHKERRQ(ierr); ierr = MatGetDiagonal(M,D);CHKERRQ(ierr); printf("\nPivots:\n\n"); VecView(D,0); /* * Solve the system; * without the shift this will diverge with * an indefinite preconditioner */ ierr = KSPSolve(ksp,B,X);CHKERRQ(ierr); ierr = KSPGetConvergedReason(ksp,&reason);CHKERRQ(ierr); if (reason==KSP_DIVERGED_INDEFINITE_PC) { printf("\nDivergence because of indefinite preconditioner;\n"); printf("Run the executable again but with -pc_factor_shift_positive_definite option.\n"); } else if (reason<0) { printf("\nOther kind of divergence: this should not happen.\n"); } else { ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); printf("\nConvergence in %d iterations.\n",(int)its); } printf("\n"); ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = VecDestroy(&B);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&D);CHKERRQ(ierr); PetscFinalize(); PetscFunctionReturn(0); }
int main(int argc,char **args) { Mat C; PetscErrorCode ierr; PetscInt i,m = 2,N,M,its,idx[4],count,*rows; PetscScalar val,Ke[16],r[4]; PetscReal x,y,h,norm,tol=1.e-14; Vec u,ustar,b; KSP ksp; PetscInitialize(&argc,&args,(char*)0,help); ierr = PetscOptionsGetInt(NULL,"-m",&m,NULL);CHKERRQ(ierr); N = (m+1)*(m+1); /* dimension of matrix */ M = m*m; /* number of elements */ h = 1.0/m; /* mesh width */ /* create stiffness matrix */ ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,N,N,9,NULL,&C);CHKERRQ(ierr); ierr = MatSetUp(C);CHKERRQ(ierr); /* forms the element stiffness for the Laplacian */ ierr = FormElementStiffness(h*h,Ke);CHKERRQ(ierr); for (i=0; i<M; i++) { /* location of lower left corner of element */ x = h*(i % m); y = h*(i/m); /* node numbers for the four corners of element */ idx[0] = (m+1)*(i/m) + (i % m); idx[1] = idx[0]+1; idx[2] = idx[1] + m + 1; idx[3] = idx[2] - 1; ierr = MatSetValues(C,4,idx,4,idx,Ke,ADD_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* create right hand side and solution */ ierr = VecCreateSeq(PETSC_COMM_SELF,N,&u);CHKERRQ(ierr); ierr = VecDuplicate(u,&b);CHKERRQ(ierr); ierr = VecDuplicate(b,&ustar);CHKERRQ(ierr); ierr = VecSet(u,0.0);CHKERRQ(ierr); ierr = VecSet(b,0.0);CHKERRQ(ierr); for (i=0; i<M; i++) { /* location of lower left corner of element */ x = h*(i % m); y = h*(i/m); /* node numbers for the four corners of element */ idx[0] = (m+1)*(i/m) + (i % m); idx[1] = idx[0]+1; idx[2] = idx[1] + m + 1; idx[3] = idx[2] - 1; ierr = FormElementRhs(x,y,h*h,r);CHKERRQ(ierr); ierr = VecSetValues(b,4,idx,r,ADD_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); /* modify matrix and rhs for Dirichlet boundary conditions */ ierr = PetscMalloc1((4*m+1),&rows);CHKERRQ(ierr); for (i=0; i<m+1; i++) { rows[i] = i; /* bottom */ rows[3*m - 1 +i] = m*(m+1) + i; /* top */ } count = m+1; /* left side */ for (i=m+1; i<m*(m+1); i+= m+1) rows[count++] = i; count = 2*m; /* left side */ for (i=2*m+1; i<m*(m+1); i+= m+1) rows[count++] = i; for (i=0; i<4*m; i++) { x = h*(rows[i] % (m+1)); y = h*(rows[i]/(m+1)); val = y; ierr = VecSetValues(u,1,&rows[i],&val,INSERT_VALUES);CHKERRQ(ierr); ierr = VecSetValues(b,1,&rows[i],&val,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatZeroRows(C,4*m,rows,1.0,0,0);CHKERRQ(ierr); ierr = PetscFree(rows);CHKERRQ(ierr); ierr = VecAssemblyBegin(u);CHKERRQ(ierr); ierr = VecAssemblyEnd(u);CHKERRQ(ierr); ierr = VecAssemblyBegin(b);CHKERRQ(ierr); ierr = VecAssemblyEnd(b);CHKERRQ(ierr); /* solve linear system */ ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr); ierr = KSPSetOperators(ksp,C,C,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr); ierr = KSPSetInitialGuessNonzero(ksp,PETSC_TRUE);CHKERRQ(ierr); ierr = KSPSolve(ksp,b,u);CHKERRQ(ierr); /* check error */ for (i=0; i<N; i++) { x = h*(i % (m+1)); y = h*(i/(m+1)); val = y; ierr = VecSetValues(ustar,1,&i,&val,INSERT_VALUES);CHKERRQ(ierr); } ierr = VecAssemblyBegin(ustar);CHKERRQ(ierr); ierr = VecAssemblyEnd(ustar);CHKERRQ(ierr); ierr = VecAXPY(u,-1.0,ustar);CHKERRQ(ierr); ierr = VecNorm(u,NORM_2,&norm);CHKERRQ(ierr); ierr = KSPGetIterationNumber(ksp,&its);CHKERRQ(ierr); if (norm > tol) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error %G Iterations %D\n",norm*h,its);CHKERRQ(ierr); } ierr = KSPDestroy(&ksp);CHKERRQ(ierr); ierr = VecDestroy(&ustar);CHKERRQ(ierr); ierr = VecDestroy(&u);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = MatDestroy(&C);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
int main(int argc,char **args) { Vec x,y,b; Mat A; /* linear system matrix */ Mat sA,sC; /* symmetric part of the matrices */ PetscInt n,mbs=16,bs=1,nz=3,prob=1,i,j,col[3],block, row,Ii,J,n1,lvl; PetscErrorCode ierr; PetscMPIInt size; PetscReal norm2,tol=1.e-10,err[10]; PetscScalar neg_one = -1.0,four=4.0,value[3]; IS perm,cperm; PetscRandom rdm; PetscBool reorder = PETSC_FALSE,displ = PETSC_FALSE; MatFactorInfo factinfo; PetscBool equal; PetscBool TestAIJ = PETSC_FALSE,TestBAIJ = PETSC_TRUE; PetscInt TestShift=0; ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr; ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size != 1) SETERRQ(PETSC_COMM_WORLD,1,"This is a uniprocessor example only!"); ierr = PetscOptionsGetInt(NULL,NULL,"-bs",&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-mbs",&mbs,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-reorder",&reorder,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-testaij",&TestAIJ,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(NULL,NULL,"-testShift",&TestShift,NULL);CHKERRQ(ierr); ierr = PetscOptionsGetBool(NULL,NULL,"-displ",&displ,NULL);CHKERRQ(ierr); n = mbs*bs; if (TestAIJ) { /* A is in aij format */ ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,n,n,nz,NULL,&A);CHKERRQ(ierr); TestBAIJ = PETSC_FALSE; } else { /* A is in baij format */ ierr =MatCreateSeqBAIJ(PETSC_COMM_WORLD,bs,n,n,nz,NULL,&A);CHKERRQ(ierr); TestAIJ = PETSC_FALSE; } /* Assemble matrix */ if (bs == 1) { ierr = PetscOptionsGetInt(NULL,NULL,"-test_problem",&prob,NULL);CHKERRQ(ierr); if (prob == 1) { /* tridiagonal matrix */ value[0] = -1.0; value[1] = 2.0; value[2] = -1.0; for (i=1; i<n-1; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = n - 1; col[0]=0; col[1] = n - 2; col[2] = n - 1; value[0]= 0.1; value[1]=-1; value[2]=2; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0; col[0] = 0; col[1] = 1; col[2]=n-1; value[0] = 2.0; value[1] = -1.0; value[2]=0.1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } else if (prob ==2) { /* matrix for the five point stencil */ n1 = (PetscInt) (PetscSqrtReal((PetscReal)n) + 0.001); if (n1*n1 - n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"sqrt(n) must be a positive interger!"); for (i=0; i<n1; i++) { for (j=0; j<n1; j++) { Ii = j + n1*i; if (i>0) { J = Ii - n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (i<n1-1) { J = Ii + n1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (j>0) { J = Ii - 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } if (j<n1-1) { J = Ii + 1; ierr = MatSetValues(A,1,&Ii,1,&J,&neg_one,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatSetValues(A,1,&Ii,1,&Ii,&four,INSERT_VALUES);CHKERRQ(ierr); } } } } else { /* bs > 1 */ for (block=0; block<n/bs; block++) { /* diagonal blocks */ value[0] = -1.0; value[1] = 4.0; value[2] = -1.0; for (i=1+block*bs; i<bs-1+block*bs; i++) { col[0] = i-1; col[1] = i; col[2] = i+1; ierr = MatSetValues(A,1,&i,3,col,value,INSERT_VALUES);CHKERRQ(ierr); } i = bs - 1+block*bs; col[0] = bs - 2+block*bs; col[1] = bs - 1+block*bs; value[0]=-1.0; value[1]=4.0; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); i = 0+block*bs; col[0] = 0+block*bs; col[1] = 1+block*bs; value[0]=4.0; value[1] = -1.0; ierr = MatSetValues(A,1,&i,2,col,value,INSERT_VALUES);CHKERRQ(ierr); } /* off-diagonal blocks */ value[0]=-1.0; for (i=0; i<(n/bs-1)*bs; i++) { col[0]=i+bs; ierr = MatSetValues(A,1,&i,1,col,value,INSERT_VALUES);CHKERRQ(ierr); col[0]=i; row=i+bs; ierr = MatSetValues(A,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } if (TestShift) { /* set diagonals in the 0-th block as 0 for testing shift numerical factor */ for (i=0; i<bs; i++) { row = i; col[0] = i; value[0] = 0.0; ierr = MatSetValues(A,1,&row,1,col,value,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatConvert */ ierr = MatSetOption(A,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); ierr = MatConvert(A,MATSEQSBAIJ,MAT_INITIAL_MATRIX,&sA);CHKERRQ(ierr); ierr = MatMultEqual(A,sA,20,&equal);CHKERRQ(ierr); if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"A != sA"); /* Test MatGetOwnershipRange() */ ierr = MatGetOwnershipRange(A,&Ii,&J);CHKERRQ(ierr); ierr = MatGetOwnershipRange(sA,&i,&j);CHKERRQ(ierr); if (i-Ii || j-J) { PetscPrintf(PETSC_COMM_SELF,"Error: MatGetOwnershipRange() in MatSBAIJ format\n");CHKERRQ(ierr); } /* Vectors */ ierr = PetscRandomCreate(PETSC_COMM_SELF,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,n,&x);CHKERRQ(ierr); ierr = VecDuplicate(x,&b);CHKERRQ(ierr); ierr = VecDuplicate(x,&y);CHKERRQ(ierr); ierr = VecSetRandom(x,rdm);CHKERRQ(ierr); /* Test MatReordering() - not work on sbaij matrix */ if (reorder) { ierr = MatGetOrdering(A,MATORDERINGRCM,&perm,&cperm);CHKERRQ(ierr); } else { ierr = MatGetOrdering(A,MATORDERINGNATURAL,&perm,&cperm);CHKERRQ(ierr); } ierr = ISDestroy(&cperm);CHKERRQ(ierr); /* initialize factinfo */ ierr = MatFactorInfoInitialize(&factinfo);CHKERRQ(ierr); if (TestShift == 1) { factinfo.shifttype = (PetscReal)MAT_SHIFT_NONZERO; factinfo.shiftamount = 0.1; } else if (TestShift == 2) { factinfo.shifttype = (PetscReal)MAT_SHIFT_POSITIVE_DEFINITE; } /* Test MatCholeskyFactor(), MatICCFactor() */ /*------------------------------------------*/ /* Test aij matrix A */ if (TestAIJ) { if (displ) { ierr = PetscPrintf(PETSC_COMM_WORLD,"AIJ: \n");CHKERRQ(ierr); } i = 0; for (lvl=-1; lvl<10; lvl++) { if (lvl==-1) { /* Cholesky factor */ factinfo.fill = 5.0; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sC);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lvl; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_ICC,&sC);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sC,A,&factinfo);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatSolve(sC,b,y);CHKERRQ(ierr); ierr = MatDestroy(&sC);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (displ) { ierr = PetscPrintf(PETSC_COMM_WORLD," lvl: %D, error: %g\n", lvl,(double)norm2);CHKERRQ(ierr); } err[i++] = norm2; } } /* Test baij matrix A */ if (TestBAIJ) { if (displ) { ierr = PetscPrintf(PETSC_COMM_WORLD,"BAIJ: \n");CHKERRQ(ierr); } i = 0; for (lvl=-1; lvl<10; lvl++) { if (lvl==-1) { /* Cholesky factor */ factinfo.fill = 5.0; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sC);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lvl; ierr = MatGetFactor(A,MATSOLVERPETSC,MAT_FACTOR_ICC,&sC);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sC,A,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sC,A,&factinfo);CHKERRQ(ierr); ierr = MatMult(A,x,b);CHKERRQ(ierr); ierr = MatSolve(sC,b,y);CHKERRQ(ierr); ierr = MatDestroy(&sC);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (displ) { ierr = PetscPrintf(PETSC_COMM_WORLD," lvl: %D, error: %g\n", lvl,(double)norm2);CHKERRQ(ierr); } err[i++] = norm2; } } /* Test sbaij matrix sA */ if (displ) { ierr = PetscPrintf(PETSC_COMM_WORLD,"SBAIJ: \n");CHKERRQ(ierr); } i = 0; for (lvl=-1; lvl<10; lvl++) { if (lvl==-1) { /* Cholesky factor */ factinfo.fill = 5.0; ierr = MatGetFactor(sA,MATSOLVERPETSC,MAT_FACTOR_CHOLESKY,&sC);CHKERRQ(ierr); ierr = MatCholeskyFactorSymbolic(sC,sA,perm,&factinfo);CHKERRQ(ierr); } else { /* incomplete Cholesky factor */ factinfo.fill = 5.0; factinfo.levels = lvl; ierr = MatGetFactor(sA,MATSOLVERPETSC,MAT_FACTOR_ICC,&sC);CHKERRQ(ierr); ierr = MatICCFactorSymbolic(sC,sA,perm,&factinfo);CHKERRQ(ierr); } ierr = MatCholeskyFactorNumeric(sC,sA,&factinfo);CHKERRQ(ierr); if (lvl==0 && bs==1) { /* Test inplace ICC(0) for sbaij sA - does not work for new datastructure */ /* Mat B; ierr = MatDuplicate(sA,MAT_COPY_VALUES,&B);CHKERRQ(ierr); ierr = MatICCFactor(B,perm,&factinfo);CHKERRQ(ierr); ierr = MatEqual(sC,B,&equal);CHKERRQ(ierr); if (!equal) { SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"in-place Cholesky factor != out-place Cholesky factor"); } ierr = MatDestroy(&B);CHKERRQ(ierr); */ } ierr = MatMult(sA,x,b);CHKERRQ(ierr); ierr = MatSolve(sC,b,y);CHKERRQ(ierr); /* Test MatSolves() */ if (bs == 1) { Vecs xx,bb; ierr = VecsCreateSeq(PETSC_COMM_SELF,n,4,&xx);CHKERRQ(ierr); ierr = VecsDuplicate(xx,&bb);CHKERRQ(ierr); ierr = MatSolves(sC,bb,xx);CHKERRQ(ierr); ierr = VecsDestroy(xx);CHKERRQ(ierr); ierr = VecsDestroy(bb);CHKERRQ(ierr); } ierr = MatDestroy(&sC);CHKERRQ(ierr); /* Check the error */ ierr = VecAXPY(y,neg_one,x);CHKERRQ(ierr); ierr = VecNorm(y,NORM_2,&norm2);CHKERRQ(ierr); if (displ) { ierr = PetscPrintf(PETSC_COMM_WORLD," lvl: %D, error: %g\n", lvl,(double)norm2);CHKERRQ(ierr); } err[i] -= norm2; if (err[i] > tol) SETERRQ2(PETSC_COMM_WORLD,PETSC_ERR_USER," level: %d, err: %g\n", lvl,(double)err[i]); } ierr = ISDestroy(&perm);CHKERRQ(ierr); ierr = MatDestroy(&A);CHKERRQ(ierr); ierr = MatDestroy(&sA);CHKERRQ(ierr); ierr = VecDestroy(&x);CHKERRQ(ierr); ierr = VecDestroy(&y);CHKERRQ(ierr); ierr = VecDestroy(&b);CHKERRQ(ierr); ierr = PetscRandomDestroy(&rdm);CHKERRQ(ierr); ierr = PetscFinalize(); return ierr; }
int main(int argc,char **args) { Mat A,B; Vec xx,s1,s2,yy; PetscErrorCode ierr; PetscInt m=45,rows[2],cols[2],bs=1,i,row,col,*idx,M; PetscScalar rval,vals1[4],vals2[4]; PetscRandom rdm; IS is1,is2; PetscReal s1norm,s2norm,rnorm,tol = 1.e-4; PetscTruth flg; MatFactorInfo info; PetscInitialize(&argc,&args,(char *)0,help); /* Test MatSetValues() and MatGetValues() */ ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,PETSC_NULL);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-mat_size",&m,PETSC_NULL);CHKERRQ(ierr); M = m*bs; ierr = MatCreateSeqBAIJ(PETSC_COMM_SELF,bs,M,M,1,PETSC_NULL,&A);CHKERRQ(ierr); ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,M,M,15,PETSC_NULL,&B);CHKERRQ(ierr); ierr = PetscRandomCreate(PETSC_COMM_SELF,&rdm);CHKERRQ(ierr); ierr = PetscRandomSetFromOptions(rdm);CHKERRQ(ierr); ierr = VecCreateSeq(PETSC_COMM_SELF,M,&xx);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s1);CHKERRQ(ierr); ierr = VecDuplicate(xx,&s2);CHKERRQ(ierr); ierr = VecDuplicate(xx,&yy);CHKERRQ(ierr); /* For each row add atleast 15 elements */ for (row=0; row<M; row++) { for (i=0; i<25*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); col = (PetscInt)(PetscRealPart(rval)*M); ierr = MatSetValues(A,1,&row,1,&col,&rval,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,1,&row,1,&col,&rval,INSERT_VALUES);CHKERRQ(ierr); } } /* Now set blocks of values */ for (i=0; i<20*bs; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = (PetscInt)(PetscRealPart(rval)*M); vals1[0] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[1] = (PetscInt)(PetscRealPart(rval)*M); vals1[1] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = (PetscInt)(PetscRealPart(rval)*M); vals1[2] = rval; ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[1] = (PetscInt)(PetscRealPart(rval)*M); vals1[3] = rval; ierr = MatSetValues(A,2,rows,2,cols,vals1,INSERT_VALUES);CHKERRQ(ierr); ierr = MatSetValues(B,2,rows,2,cols,vals1,INSERT_VALUES);CHKERRQ(ierr); } ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); /* Test MatNorm() */ ierr = MatNorm(A,NORM_FROBENIUS,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_FROBENIUS,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_FROBENIUS()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_INFINITY,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_INFINITY,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_INFINITY()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } ierr = MatNorm(A,NORM_1,&s1norm);CHKERRQ(ierr); ierr = MatNorm(B,NORM_1,&s2norm);CHKERRQ(ierr); rnorm = PetscAbsScalar(s2norm-s1norm)/s2norm; if ( rnorm>tol ) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatNorm_NORM_1()- NormA=%16.14e NormB=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } /* MatShift() */ rval = 10*s1norm; ierr = MatShift(A,rval);CHKERRQ(ierr); ierr = MatShift(B,rval);CHKERRQ(ierr); /* Test MatTranspose() */ ierr = MatTranspose(A,MAT_REUSE_MATRIX,&A);CHKERRQ(ierr); ierr = MatTranspose(B,MAT_REUSE_MATRIX,&B);CHKERRQ(ierr); /* Now do MatGetValues() */ for (i=0; i<30; i++) { ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[0] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); cols[1] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[0] = (PetscInt)(PetscRealPart(rval)*M); ierr = PetscRandomGetValue(rdm,&rval);CHKERRQ(ierr); rows[1] = (PetscInt)(PetscRealPart(rval)*M); ierr = MatGetValues(A,2,rows,2,cols,vals1);CHKERRQ(ierr); ierr = MatGetValues(B,2,rows,2,cols,vals2);CHKERRQ(ierr); ierr = PetscMemcmp(vals1,vals2,4*sizeof(PetscScalar),&flg);CHKERRQ(ierr); if (!flg) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatGetValues bs = %D\n",bs);CHKERRQ(ierr); } } /* Test MatMult(), MatMultAdd() */ for (i=0; i<40; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSet(s2,0.0);CHKERRQ(ierr); ierr = MatMult(A,xx,s1);CHKERRQ(ierr); ierr = MatMultAdd(A,xx,s2,s2);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"MatMult not equal to MatMultAdd Norm1=%e Norm2=%e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatMult() */ ierr = MatMultEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMult()\n");CHKERRQ(ierr); } /* Test MatMultAdd() */ ierr = MatMultAddEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultAdd()\n");CHKERRQ(ierr); } /* Test MatMultTranspose() */ ierr = MatMultTransposeEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultTranspose()\n");CHKERRQ(ierr); } /* Test MatMultTransposeAdd() */ ierr = MatMultTransposeAddEqual(A,B,10,&flg);CHKERRQ(ierr); if (!flg){ ierr = PetscPrintf(PETSC_COMM_SELF,"Error: MatMultTransposeAdd()\n");CHKERRQ(ierr); } /* Do LUFactor() on both the matrices */ ierr = PetscMalloc(M*sizeof(PetscInt),&idx);CHKERRQ(ierr); for (i=0; i<M; i++) idx[i] = i; ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,&is1);CHKERRQ(ierr); ierr = ISCreateGeneral(PETSC_COMM_SELF,M,idx,&is2);CHKERRQ(ierr); ierr = PetscFree(idx);CHKERRQ(ierr); ierr = ISSetPermutation(is1);CHKERRQ(ierr); ierr = ISSetPermutation(is2);CHKERRQ(ierr); ierr = MatFactorInfoInitialize(&info);CHKERRQ(ierr); info.fill = 2.0; info.dtcol = 0.0; info.zeropivot = 1.e-14; info.pivotinblocks = 1.0; ierr = MatLUFactor(B,is1,is2,&info);CHKERRQ(ierr); ierr = MatLUFactor(A,is1,is2,&info);CHKERRQ(ierr); /* Test MatSolveAdd() */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSetRandom(yy,rdm);CHKERRQ(ierr); ierr = MatSolveAdd(B,xx,yy,s2);CHKERRQ(ierr); ierr = MatSolveAdd(A,xx,yy,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveAdd - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolveAdd() when x = A'b +x */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = VecSetRandom(s1,rdm);CHKERRQ(ierr); ierr = VecCopy(s2,s1);CHKERRQ(ierr); ierr = MatSolveAdd(B,xx,s2,s2);CHKERRQ(ierr); ierr = MatSolveAdd(A,xx,s1,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveAdd(same) - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolve() */ for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatSolve(B,xx,s2);CHKERRQ(ierr); ierr = MatSolve(A,xx,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolve - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } /* Test MatSolveTranspose() */ if (bs < 8) { for (i=0; i<10; i++) { ierr = VecSetRandom(xx,rdm);CHKERRQ(ierr); ierr = MatSolveTranspose(B,xx,s2);CHKERRQ(ierr); ierr = MatSolveTranspose(A,xx,s1);CHKERRQ(ierr); ierr = VecNorm(s1,NORM_2,&s1norm);CHKERRQ(ierr); ierr = VecNorm(s2,NORM_2,&s2norm);CHKERRQ(ierr); rnorm = s2norm-s1norm; if (rnorm<-tol || rnorm>tol) { ierr = PetscPrintf(PETSC_COMM_SELF,"Error:MatSolveTranspose - Norm1=%16.14e Norm2=%16.14e bs = %D\n",s1norm,s2norm,bs);CHKERRQ(ierr); } } } ierr = MatDestroy(A);CHKERRQ(ierr); ierr = MatDestroy(B);CHKERRQ(ierr); ierr = VecDestroy(xx);CHKERRQ(ierr); ierr = VecDestroy(s1);CHKERRQ(ierr); ierr = VecDestroy(s2);CHKERRQ(ierr); ierr = VecDestroy(yy);CHKERRQ(ierr); ierr = ISDestroy(is1);CHKERRQ(ierr); ierr = ISDestroy(is2);CHKERRQ(ierr); ierr = PetscRandomDestroy(rdm);CHKERRQ(ierr); ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
PetscErrorCode testPTAPRectangular(void) { const int rows = 3; const int cols = 5; PetscErrorCode _ierr; int i; Mat A; Mat P; Mat C; PetscFunctionBegin; /* set up A */ _ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, rows, 1, PETSC_NULL, &A); PETSc_CHKERRQ(_ierr); for (i=0; i<rows; i++) { _ierr = MatSetValue(A, i, i, 1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); } _ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY); PETSc_CHKERRQ(_ierr); _ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY); PETSc_CHKERRQ(_ierr); /* set up P */ _ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD, rows, cols, 5, PETSC_NULL, &P); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 0, 0, 1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 0, 1, 2.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 0, 2, 0.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 0, 3, -1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 1, 0, 0.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 1, 1, -1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 1, 2, 1.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 2, 0, 3.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 2, 1, 0.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatSetValue(P, 2, 2, -3.0, INSERT_VALUES); PETSc_CHKERRQ(_ierr); _ierr = MatAssemblyBegin(P,MAT_FINAL_ASSEMBLY); PETSc_CHKERRQ(_ierr); _ierr = MatAssemblyEnd(P,MAT_FINAL_ASSEMBLY); PETSc_CHKERRQ(_ierr); /* compute C */ _ierr = MatPtAP( A, P, MAT_INITIAL_MATRIX, 1.0, &C); PETSc_CHKERRQ(_ierr); _ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); PETSc_CHKERRQ(_ierr); _ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); PETSc_CHKERRQ(_ierr); /* compare results */ /* printf("C:\n"); _ierr = MatView(C,PETSC_VIEWER_STDOUT_WORLD);PETSc_CHKERRQ(_ierr); blitz::Array<double,2> actualC(cols, cols); actualC = 0.0; for (int i=0; i<cols; i++) { for (int j=0; j<cols; j++) { _ierr = MatGetValues(C, 1, &i, 1, &j, &actualC(i,j) ); PETSc_CHKERRQ(_ierr); ; } } blitz::Array<double,2> expectedC(cols, cols); expectedC = 0.0; expectedC(0,0) = 10.0; expectedC(0,1) = 2.0; expectedC(0,2) = -9.0; expectedC(0,3) = -1.0; expectedC(1,0) = 2.0; expectedC(1,1) = 5.0; expectedC(1,2) = -1.0; expectedC(1,3) = -2.0; expectedC(2,0) = -9.0; expectedC(2,1) = -1.0; expectedC(2,2) = 10.0; expectedC(2,3) = 0.0; expectedC(3,0) = -1.0; expectedC(3,1) = -2.0; expectedC(3,2) = 0.0; expectedC(3,3) = 1.0; int check = areBlitzArrays2NumericallyEqual(actualC,expectedC); validateEqualsWithParams3(check, -1 , "testPTAPRectangular()", check, actualC(check), expectedC(check)); */ _ierr = MatDestroy(&A); PETSc_CHKERRQ(_ierr); _ierr = MatDestroy(&P); PETSc_CHKERRQ(_ierr); _ierr = MatDestroy(&C); PETSc_CHKERRQ(_ierr); PetscFunctionReturn(0); }
PetscErrorCode MatLoad_BlockMat(Mat newmat, PetscViewer viewer) { PetscErrorCode ierr; Mat tmpA; PetscInt i,j,m,n,bs = 1,ncols,*lens,currentcol,mbs,**ii,*ilens,nextcol,*llens,cnt = 0; const PetscInt *cols; const PetscScalar *values; PetscBool flg = PETSC_FALSE,notdone; Mat_SeqAIJ *a; Mat_BlockMat *amat; PetscFunctionBegin; ierr = MatCreate(PETSC_COMM_SELF,&tmpA);CHKERRQ(ierr); ierr = MatSetType(tmpA,MATSEQAIJ);CHKERRQ(ierr); ierr = MatLoad_SeqAIJ(tmpA,viewer);CHKERRQ(ierr); ierr = MatGetLocalSize(tmpA,&m,&n);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_SELF,NULL,"Options for loading BlockMat matrix 1","Mat");CHKERRQ(ierr); ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); ierr = PetscOptionsBool("-matload_symmetric","Store the matrix as symmetric","MatLoad",flg,&flg,NULL);CHKERRQ(ierr); ierr = PetscOptionsEnd();CHKERRQ(ierr); /* Determine number of nonzero blocks for each block row */ a = (Mat_SeqAIJ*) tmpA->data; mbs = m/bs; ierr = PetscMalloc3(mbs,&lens,bs,&ii,bs,&ilens);CHKERRQ(ierr); ierr = PetscMemzero(lens,mbs*sizeof(PetscInt));CHKERRQ(ierr); for (i=0; i<mbs; i++) { for (j=0; j<bs; j++) { ii[j] = a->j + a->i[i*bs + j]; ilens[j] = a->i[i*bs + j + 1] - a->i[i*bs + j]; } currentcol = -1; notdone = PETSC_TRUE; while (PETSC_TRUE) { notdone = PETSC_FALSE; nextcol = 1000000000; for (j=0; j<bs; j++) { while ((ilens[j] > 0 && ii[j][0]/bs <= currentcol)) { ii[j]++; ilens[j]--; } if (ilens[j] > 0) { notdone = PETSC_TRUE; nextcol = PetscMin(nextcol,ii[j][0]/bs); } } if (!notdone) break; if (!flg || (nextcol >= i)) lens[i]++; currentcol = nextcol; } } if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) { ierr = MatSetSizes(newmat,m,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); } ierr = MatBlockMatSetPreallocation(newmat,bs,0,lens);CHKERRQ(ierr); if (flg) { ierr = MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } amat = (Mat_BlockMat*)(newmat)->data; /* preallocate the submatrices */ ierr = PetscMalloc1(bs,&llens);CHKERRQ(ierr); for (i=0; i<mbs; i++) { /* loops for block rows */ for (j=0; j<bs; j++) { ii[j] = a->j + a->i[i*bs + j]; ilens[j] = a->i[i*bs + j + 1] - a->i[i*bs + j]; } currentcol = 1000000000; for (j=0; j<bs; j++) { /* loop over rows in block finding first nonzero block */ if (ilens[j] > 0) { currentcol = PetscMin(currentcol,ii[j][0]/bs); } } notdone = PETSC_TRUE; while (PETSC_TRUE) { /* loops over blocks in block row */ notdone = PETSC_FALSE; nextcol = 1000000000; ierr = PetscMemzero(llens,bs*sizeof(PetscInt));CHKERRQ(ierr); for (j=0; j<bs; j++) { /* loop over rows in block */ while ((ilens[j] > 0 && ii[j][0]/bs <= currentcol)) { /* loop over columns in row */ ii[j]++; ilens[j]--; llens[j]++; } if (ilens[j] > 0) { notdone = PETSC_TRUE; nextcol = PetscMin(nextcol,ii[j][0]/bs); } } if (cnt >= amat->maxnz) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Number of blocks found greater than expected %D",cnt); if (!flg || currentcol >= i) { amat->j[cnt] = currentcol; ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,bs,bs,0,llens,amat->a+cnt++);CHKERRQ(ierr); } if (!notdone) break; currentcol = nextcol; } amat->ilen[i] = lens[i]; } ierr = PetscFree3(lens,ii,ilens);CHKERRQ(ierr); ierr = PetscFree(llens);CHKERRQ(ierr); /* copy over the matrix, one row at a time */ for (i=0; i<m; i++) { ierr = MatGetRow(tmpA,i,&ncols,&cols,&values);CHKERRQ(ierr); ierr = MatSetValues(newmat,1,&i,ncols,cols,values,INSERT_VALUES);CHKERRQ(ierr); ierr = MatRestoreRow(tmpA,i,&ncols,&cols,&values);CHKERRQ(ierr); } ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); PetscFunctionReturn(0); }
PetscErrorCode MatSetValues_BlockMat(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) { Mat_BlockMat *a = (Mat_BlockMat*)A->data; PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,lastcol = -1; PetscInt *imax=a->imax,*ai=a->i,*ailen=a->ilen; PetscInt *aj =a->j,nonew=a->nonew,bs=A->rmap->bs,brow,bcol; PetscErrorCode ierr; PetscInt ridx,cidx; PetscBool roworiented=a->roworiented; MatScalar value; Mat *ap,*aa = a->a; PetscFunctionBegin; for (k=0; k<m; k++) { /* loop over added rows */ row = im[k]; brow = row/bs; if (row < 0) continue; #if defined(PETSC_USE_DEBUG) 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); #endif rp = aj + ai[brow]; ap = aa + ai[brow]; rmax = imax[brow]; nrow = ailen[brow]; low = 0; high = nrow; for (l=0; l<n; l++) { /* loop over added columns */ if (in[l] < 0) continue; #if defined(PETSC_USE_DEBUG) 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); #endif col = in[l]; bcol = col/bs; if (A->symmetric && brow > bcol) continue; ridx = row % bs; cidx = col % bs; if (roworiented) value = v[l + k*n]; else value = v[k + l*m]; if (col <= lastcol) low = 0; else high = nrow; lastcol = col; while (high-low > 7) { t = (low+high)/2; if (rp[t] > bcol) high = t; else low = t; } for (i=low; i<high; i++) { if (rp[i] > bcol) break; if (rp[i] == bcol) goto noinsert1; } if (nonew == 1) goto noinsert1; if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero (%D, %D) in the matrix", row, col); MatSeqXAIJReallocateAIJ(A,a->mbs,1,nrow,brow,bcol,rmax,aa,ai,aj,rp,ap,imax,nonew,Mat); N = nrow++ - 1; high++; /* shift up all the later entries in this row */ for (ii=N; ii>=i; ii--) { rp[ii+1] = rp[ii]; ap[ii+1] = ap[ii]; } if (N>=i) ap[i] = 0; rp[i] = bcol; a->nz++; A->nonzerostate++; noinsert1:; if (!*(ap+i)) { ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,bs,bs,0,0,ap+i);CHKERRQ(ierr); } ierr = MatSetValues(ap[i],1,&ridx,1,&cidx,&value,is);CHKERRQ(ierr); low = i; } ailen[brow] = nrow; } PetscFunctionReturn(0); }
int main(int argc,char **argv) { PetscErrorCode ierr; PetscInitialize(&argc,&argv,(char*)0,help); const int d = 2; // d = DOF Mat A, Aminus; // these are dense d x d sequential matrices, unrelated to the grid // (each processor owns whole matrix) ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,d,d,d,NULL,&A); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(A,"A_"); CHKERRQ(ierr); ierr = MatSetFromOptions(A); CHKERRQ(ierr); // fill A double val[d][d], c = 3.0; val[0][0] = 0.0; val[0][1] = c; val[1][0] = c; val[1][1] = 0.0; ierr = fillsmallmat(2,val,A); CHKERRQ(ierr); // fill Aminus; see getAminus.m for computation of Aminus from A ierr = MatDuplicate(A,MAT_SHARE_NONZERO_PATTERN,&Aminus); CHKERRQ(ierr); ierr = MatSetOptionsPrefix(Aminus,"Aminus_"); CHKERRQ(ierr); val[0][0] = -1.5; val[0][1] = 1.5; val[1][0] = 1.5; val[1][1] = -1.5; ierr = fillsmallmat(2,val,Aminus); CHKERRQ(ierr); // set up the grid DM da; ierr = DMDACreate1d(PETSC_COMM_WORLD, DM_BOUNDARY_PERIODIC, -50, // override with -da_grid_x or -da_refine d, 1, NULL, // dof = 1 and stencil width = 1 &da); CHKERRQ(ierr); // determine grid locations (cell-centered grid) DMDALocalInfo info; double L = 10.0, dx; ierr = DMDAGetLocalInfo(da,&info); CHKERRQ(ierr); dx = L / (double)(info.mx); ierr = DMDASetUniformCoordinates(da,dx/2,L-dx/2,-1.0,-1.0,-1.0,-1.0);CHKERRQ(ierr); // u = u(t_n), unew = u(t_n+1) Vec u, unew, F; ierr = DMCreateLocalVector(da,&u);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)u,"solution u"); CHKERRQ(ierr); ierr = VecDuplicate(u,&F);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)F,"flux F"); CHKERRQ(ierr); ierr = DMCreateGlobalVector(da,&unew);CHKERRQ(ierr); ierr = PetscObjectSetName((PetscObject)unew,"updated solution unew"); CHKERRQ(ierr); ierr = VecSet(unew,0.0); CHKERRQ(ierr); // at each cell we will need to compute Fcell = A qleft + Aminus dq Vec dq, qleft, tmp, Fcell; ierr = VecCreateSeq(PETSC_COMM_WORLD,d,&dq); CHKERRQ(ierr); ierr = VecDuplicate(dq,&qleft); CHKERRQ(ierr); ierr = VecDuplicate(dq,&tmp); CHKERRQ(ierr); ierr = VecDuplicate(dq,&Fcell); CHKERRQ(ierr); // view the solution graphically; control with -draw_pause PetscViewer viewer; ierr = PetscViewerDrawOpen(PETSC_COMM_WORLD,NULL,"solution u", PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,PETSC_DECIDE,&viewer); CHKERRQ(ierr); /* time-stepping loop */ double t = 0.0, tf = 10.0, dt, nu; int n, NN = 10; dt = tf / NN; nu = dt / dx; for (n = 0; n < NN; ++n) { ierr = PetscPrintf(PETSC_COMM_WORLD, " time[%3d]=%6g: \n", n, t); CHKERRQ(ierr); ierr = DMGlobalToLocalBegin(da,unew,INSERT_VALUES,u); CHKERRQ(ierr); ierr = DMGlobalToLocalEnd(da,unew,INSERT_VALUES,u); CHKERRQ(ierr); ierr = VecView(u,viewer); CHKERRQ(ierr); double **au, **aunew, **aF; int j, p; ierr = DMDAVecGetArrayDOF(da, u, &au);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, F, &aF);CHKERRQ(ierr); for (j=info.xs; j<info.xs+info.xm; j++) { double *adq, *aqleft, *aFcell; ierr = VecGetArray(dq,&adq); CHKERRQ(ierr); ierr = VecGetArray(qleft,&aqleft); CHKERRQ(ierr); for (p = 0; p < d; p++) { adq[p] = au[j+1][p] - au[j][p]; aqleft[p] = au[j][p]; } ierr = VecRestoreArray(dq,&adq); CHKERRQ(ierr); ierr = VecRestoreArray(qleft,&aqleft); CHKERRQ(ierr); // tmp = A qleft // Fcell = tmp + Aminus dq ierr = MatMult(A,qleft,tmp); CHKERRQ(ierr); ierr = MatMultAdd(Aminus,dq,tmp,Fcell); CHKERRQ(ierr); ierr = VecGetArray(Fcell,&aFcell); CHKERRQ(ierr); for (p = 0; p < d; p++) aF[j][p] = aFcell[p]; ierr = VecRestoreArray(Fcell,&aFcell); CHKERRQ(ierr); } ierr = DMDAVecRestoreArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMLocalToLocalBegin(da,F,INSERT_VALUES,F); CHKERRQ(ierr); ierr = DMLocalToLocalEnd(da,F,INSERT_VALUES,F); CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMDAVecGetArrayDOF(da, unew, &aunew);CHKERRQ(ierr); for (j=info.xs; j<info.xs+info.xm; j++) { for (p = 0; p < d; p++) aunew[j][p] = au[j][p] - nu * (aF[j+1][p] - aF[j][p]); } ierr = DMDAVecRestoreArrayDOF(da, u, &au);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, F, &aF);CHKERRQ(ierr); ierr = DMDAVecRestoreArrayDOF(da, unew, &aunew);CHKERRQ(ierr); t += dt; } // clean up ierr = VecDestroy(&u); CHKERRQ(ierr); ierr = VecDestroy(&unew); CHKERRQ(ierr); ierr = VecDestroy(&F); CHKERRQ(ierr); ierr = VecDestroy(&dq); CHKERRQ(ierr); ierr = VecDestroy(&qleft); CHKERRQ(ierr); ierr = VecDestroy(&tmp); CHKERRQ(ierr); ierr = VecDestroy(&Fcell); CHKERRQ(ierr); ierr = MatDestroy(&A); CHKERRQ(ierr); ierr = MatDestroy(&Aminus); CHKERRQ(ierr); ierr = PetscViewerDestroy(&viewer); CHKERRQ(ierr); ierr = DMDestroy(&da); CHKERRQ(ierr); ierr = PetscFinalize(); CHKERRQ(ierr); return 0; }