xref: /petsc/src/mat/tutorials/ex12.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
1c4762a1bSJed Brown 
2c4762a1bSJed Brown static char help[] = "Reads a PETSc matrix and vector from a file; expands the matrix with the vector\n\n";
3c4762a1bSJed Brown 
4c4762a1bSJed Brown /*T
5c4762a1bSJed Brown    Concepts: Mat^ordering a matrix - loading a binary matrix and vector;
6c4762a1bSJed Brown    Concepts: Mat^loading a binary matrix and vector;
7c4762a1bSJed Brown    Concepts: Vectors^loading a binary vector;
8c4762a1bSJed Brown    Concepts: PetscLog^preloading executable
9c4762a1bSJed Brown    Processors: 1
10c4762a1bSJed Brown T*/
11c4762a1bSJed Brown 
12c4762a1bSJed Brown /*
13c4762a1bSJed Brown   Include "petscmat.h" so that we can use matrices.
14c4762a1bSJed Brown   automatically includes:
15c4762a1bSJed Brown      petscsys.h       - base PETSc routines   petscvec.h    - vectors
16c4762a1bSJed Brown      petscmat.h    - matrices
17c4762a1bSJed Brown      petscis.h     - index sets            petscviewer.h - viewers
18c4762a1bSJed Brown */
19c4762a1bSJed Brown #include <petscmat.h>
20c4762a1bSJed Brown 
21c4762a1bSJed Brown /*
22c4762a1bSJed Brown 
23c4762a1bSJed Brown    Adds a new column and row to the vector (the last) containing the vector
24c4762a1bSJed Brown */
25c4762a1bSJed Brown PetscErrorCode PadMatrix(Mat A,Vec v,PetscScalar c,Mat *B)
26c4762a1bSJed Brown {
27c4762a1bSJed Brown   PetscInt          n,i,*cnt,*indices,nc;
28c4762a1bSJed Brown   const PetscInt    *aj;
29c4762a1bSJed Brown   const PetscScalar *vv,*aa;
30c4762a1bSJed Brown 
31c4762a1bSJed Brown   PetscFunctionBegin;
325f80ce2aSJacob Faibussowitsch   CHKERRQ(MatGetSize(A,&n,NULL));
335f80ce2aSJacob Faibussowitsch   CHKERRQ(VecGetArrayRead(v,&vv));
345f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(n,&indices));
35c4762a1bSJed Brown   for (i=0; i<n; i++) indices[i] = i;
36c4762a1bSJed Brown 
37c4762a1bSJed Brown   /* determine number of nonzeros per row in the new matrix */
385f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscMalloc1(n+1,&cnt));
39c4762a1bSJed Brown   for (i=0; i<n; i++) {
405f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetRow(A,i,&nc,NULL,NULL));
41c4762a1bSJed Brown     cnt[i] = nc + (vv[i] != 0.0);
425f80ce2aSJacob Faibussowitsch     CHKERRQ(MatRestoreRow(A,i,&nc,NULL,NULL));
43c4762a1bSJed Brown   }
44c4762a1bSJed Brown   cnt[n] = 1;
45c4762a1bSJed Brown   for (i=0; i<n; i++) {
46c4762a1bSJed Brown     cnt[n] += (vv[i] != 0.0);
47c4762a1bSJed Brown   }
485f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreateSeqAIJ(PETSC_COMM_SELF,n+1,n+1,0,cnt,B));
495f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetOption(*B,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE));
50c4762a1bSJed Brown 
51c4762a1bSJed Brown   /* copy over the matrix entries from the matrix and then the vector */
52c4762a1bSJed Brown   for (i=0; i<n; i++) {
535f80ce2aSJacob Faibussowitsch     CHKERRQ(MatGetRow(A,i,&nc,&aj,&aa));
545f80ce2aSJacob Faibussowitsch     CHKERRQ(MatSetValues(*B,1,&i,nc,aj,aa,INSERT_VALUES));
555f80ce2aSJacob Faibussowitsch     CHKERRQ(MatRestoreRow(A,i,&nc,&aj,&aa));
56c4762a1bSJed Brown   }
575f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetValues(*B,1,&n,n,indices,vv,INSERT_VALUES));
585f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetValues(*B,n,indices,1,&n,vv,INSERT_VALUES));
595f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetValues(*B,1,&n,1,&n,&c,INSERT_VALUES));
60c4762a1bSJed Brown 
615f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY));
625f80ce2aSJacob Faibussowitsch   CHKERRQ(MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY));
635f80ce2aSJacob Faibussowitsch   CHKERRQ(VecRestoreArrayRead(v,&vv));
645f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(cnt));
655f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(indices));
66c4762a1bSJed Brown   PetscFunctionReturn(0);
67c4762a1bSJed Brown }
68c4762a1bSJed Brown 
69c4762a1bSJed Brown int main(int argc,char **args)
70c4762a1bSJed Brown {
71c4762a1bSJed Brown   Mat            A,B;
72c4762a1bSJed Brown   PetscViewer    fd;                        /* viewer */
73c4762a1bSJed Brown   char           file[PETSC_MAX_PATH_LEN];  /* input file name */
74c4762a1bSJed Brown   PetscErrorCode ierr;
75c4762a1bSJed Brown   PetscBool      flg;
76c4762a1bSJed Brown   Vec            v;
77c4762a1bSJed Brown 
78c4762a1bSJed Brown   ierr = PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
79c4762a1bSJed Brown   /*
80c4762a1bSJed Brown      Determine files from which we read the two linear systems
81c4762a1bSJed Brown      (matrix and right-hand-side vector).
82c4762a1bSJed Brown   */
835f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetString(NULL,NULL,"-f0",file,sizeof(file),&flg));
84*28b400f6SJacob Faibussowitsch   PetscCheck(flg,PETSC_COMM_WORLD,PETSC_ERR_USER,"Must indicate binary file with the -f0 option");
85c4762a1bSJed Brown 
865f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerBinaryOpen(PETSC_COMM_WORLD,file,FILE_MODE_READ,&fd));
87c4762a1bSJed Brown 
885f80ce2aSJacob Faibussowitsch   CHKERRQ(MatCreate(PETSC_COMM_WORLD,&A));
895f80ce2aSJacob Faibussowitsch   CHKERRQ(MatSetType(A,MATSEQAIJ));
905f80ce2aSJacob Faibussowitsch   CHKERRQ(MatLoad(A,fd));
915f80ce2aSJacob Faibussowitsch   CHKERRQ(VecCreate(PETSC_COMM_WORLD,&v));
925f80ce2aSJacob Faibussowitsch   CHKERRQ(VecLoad(v,fd));
935f80ce2aSJacob Faibussowitsch   CHKERRQ(MatView(A,PETSC_VIEWER_STDOUT_SELF));
945f80ce2aSJacob Faibussowitsch   CHKERRQ(PadMatrix(A,v,3.0,&B));
955f80ce2aSJacob Faibussowitsch   CHKERRQ(MatView(B,PETSC_VIEWER_STDOUT_SELF));
965f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&B));
975f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&A));
985f80ce2aSJacob Faibussowitsch   CHKERRQ(VecDestroy(&v));
995f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscViewerDestroy(&fd));
100c4762a1bSJed Brown 
101c4762a1bSJed Brown   ierr = PetscFinalize();
102c4762a1bSJed Brown   return ierr;
103c4762a1bSJed Brown }
104c4762a1bSJed Brown 
105c4762a1bSJed Brown /*TEST
106c4762a1bSJed Brown 
107c4762a1bSJed Brown    test:
108c4762a1bSJed Brown       args: -f0 ${wPETSC_DIR}/share/petsc/datafiles/matrices/ns-real-int32-float64
109dfd57a17SPierre Jolivet       requires: double !complex !defined(PETSC_USE_64BIT_INDICES)
110c4762a1bSJed Brown 
111c4762a1bSJed Brown TEST*/
112