[petsc-users] Use MatConvert
Barry Smith
bsmith at mcs.anl.gov
Tue Mar 17 14:09:35 CDT 2015
I'm sorry, this is our fault. The code cannot correctly convert from AIJ to BAIJ for a block size > 1. The resulting BAIJ had a block size of 1 (which makes little sense in this case) hence the MatSetValuesBlocked() behaved in a way not expected. I have changed the code to generate an error in this case instead of being misleading.
Barry
> On Mar 17, 2015, at 1:34 PM, Chung-Kan Huang <ckhuangf at gmail.com> wrote:
>
> I created a short code to illustrate my problem..
> if you run the program with
> -mat_view
> -mat_view draw
> -draw_pause -1
>
> the first matrix you see has the correct structure while the one after Matconvert gives the wrong one.
>
> I think it possibly has something to do with the way I use MatSetValuesBlocked after the convert?
>
> #include <iostream>
> #include <string>
>
> #include "petscksp.h"
> #include "petscao.h"
> #include "petsc.h"
> #include "HYPRE.h"
>
> using namespace std;
>
> void preassem(Mat & J, double * P, const int & n);
>
> int main (int argc, char ** argv)
> {
> MPI_Init(&argc, &argv);
>
> PetscInitialize(PETSC_NULL,
> PETSC_NULL,
> PETSC_NULL,
> PETSC_NULL);
>
> PetscViewer viewer;
> Mat J;
> PetscInt bs = 4;
> PetscInt n = 3;
> PetscInt bssq = bs * bs;
> double P[bssq];
> PetscInt local_size = bs * n;
> for (int i = 0; i < bssq; i++) {
> P[i] = 1.;
> }
> MatCreate(PETSC_COMM_WORLD, &J);
>
> MatSetBlockSize(J, bs); // So MatSetValuesBlocked can be used
>
> MatSetType(J, MATAIJ);
>
> PetscInt d_nnz[12] = {8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 4, 4};
>
>
> MatSetSizes(J,
> local_size,
> local_size,
> PETSC_DECIDE,
> PETSC_DECIDE);
>
> MatSeqAIJSetPreallocation(J,
> PETSC_DEFAULT,
> d_nnz);
>
> preassem(J, P, n); // Shows the correct structure
>
>
>
> MatConvert(J, MATBAIJ, MAT_REUSE_MATRIX, & J);
>
> MatZeroEntries(J);
>
> preassem(J, P, n); // Shows the incorrect structurex
>
>
> // Destroy PETSc objects.
> MatDestroy(& J);
>
> PetscViewerDestroy(& viewer);
> PetscFinalize();
>
> MPI_Finalize();
>
> return 0;
> }
>
> void preassem(Mat & J, double * P, const int & n)
> {
> for (int GID = 0; GID < n; GID++) {
> MatSetValuesBlocked(J,
> 1,
> & GID,
> 1,
> & GID,
> P,
> ADD_VALUES);
> }
> int GID = 0;
> const int jGID = 2;
>
> MatSetValuesBlocked(J,
> 1,
> & GID,
> 1,
> & jGID,
> P,
> ADD_VALUES);
> MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);
> MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);
>
> }
>
>
> On Tue, Mar 17, 2015 at 12:43 PM, Barry Smith <bsmith at mcs.anl.gov> wrote:
>
> > On Mar 17, 2015, at 11:40 AM, Chung-Kan Huang <ckhuangf at gmail.com> wrote:
> >
> > Hi,
> >
> > I wonder what I did wrong when using MATConvert...
> >
> > MatCreate(* comm_, &J_);
> >
> > PetscInt * d_nnz = NULL;
> > PetscInt * o_nnz = NULL;
> > PetscMalloc(local_size * sizeof(PetscInt), & d_nnz);
> > PetscMalloc(local_size * sizeof(PetscInt), & o_nnz);
> > for (int i = 0; i < local_size; i++) {
> > d_nnz[i] = d_nnz_v[i];
> > o_nnz[i] = o_nnz_v[i];
> > }
> > MatSetSizes(J_,
> > local_size,
> > local_size,
> > PETSC_DECIDE,
> > PETSC_DECIDE);
> >
> > MatSetBlockSize(J_, M_SIZE); // So MatSetValuesBlocked can be used
> > MatSetType(J_, MATAIJ);
> >
> > if (comm_->Get_size() > 1) {
>
> You don't need to have this if here; just call both MatMPIAIJSetPreallocation and MatSeqAIJSetPreallocation() and PETSc will use the correct one and ignore the other one automatically.
>
> > // MPI
> > MatMPIAIJSetPreallocation(J_,
> > max_d_nz,
> > d_nnz,
> > max_o_nz,
> > o_nnz);
> >
> > } else {
> > // Seq
> > MatSeqAIJSetPreallocation(J_,
> > PETSC_DEFAULT,
> > d_nnz);
> > }
> >
> > PetscFree(d_nnz);
> > PetscFree(o_nnz);
> >
> >
> > // Column oriented
> > MatSetOption(J_, MAT_ROW_ORIENTED, PETSC_FALSE);
> > // Test code to check if J_ has right structure
> > preAssembeJ();
> >
> > <image.png>
> > MatAssemblyBegin(J_, MAT_FINAL_ASSEMBLY);
> > MatAssemblyEnd(J_, MAT_FINAL_ASSEMBLY);
> >
> >
> > MatConvert(J_, MATBAIJ, MAT_REUSE_MATRIX, & J_);
>
> I cannot understand what is wrong. Is it producing the wrong matrix? Please send the entire code so we can run it ourselves.
>
> Barry
>
> >
> > MatZeroEntries(J_);
> > // Test code to check if J_ has right structure
> > preAssembeJ();
> > <image.png>
> > Thanks,
> > Kan
> > Cheers
> >
>
>
>
>
> --
> Cheers
>
More information about the petsc-users
mailing list