xref: /petsc/src/mat/utils/convert.c (revision 08480c60afa5ef1d2e4e27b9ebdf48b02c6a2186)
1 #ifndef lint
2 static char vcid[] = "$Id: convert.c,v 1.28 1995/10/04 03:58:40 bsmith Exp curfman $";
3 #endif
4 
5 /* Matrix conversion routines.  For now, this supports only conversion from AIJ */
6 
7 #include "mpiaij.h"
8 
9 /*
10   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
11   parallel formats, the new matrix distribution is determined by PETSc.
12  */
13 int MatConvert_SeqAIJ(Mat mat, MatType newtype, Mat *newmat)
14 {
15   Mat_SeqAIJ *aij = (Mat_SeqAIJ *) mat->data;
16   Scalar     *vwork;
17   int        i, ierr, nz, m = aij->m, n = aij->n, *cwork, rstart, rend;
18 
19   switch (newtype) {
20     case MATSEQROW:
21       ierr = MatCreateSeqRow(mat->comm,m,n,0,aij->ilen,newmat);CHKERRQ(ierr);
22       break;
23     case MATMPIROW:
24       if (m != n) SETERRQ(1,"MatConvert_SeqAIJ: MPIRowbs matrix must be square");
25       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
26                              m,n,0,0,0,0,newmat); CHKERRQ(ierr);
27       break;
28     case MATMPIROWBS:
29       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,
30                                m,0,0,0,newmat);CHKERRQ(ierr);
31       break;
32     case MATMPIAIJ:
33       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
34                              m,n,0,0,0,0,newmat);CHKERRQ(ierr);
35       break;
36     case MATSEQDENSE:
37       ierr = MatCreateSeqDense(mat->comm,m,n,newmat); CHKERRQ(ierr);
38       break;
39     case MATSEQBDIAG:
40       {
41       int nb = 1; /* Default block size = 1 */
42       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
43       ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,0,0,newmat); CHKERRQ(ierr);
44       break;
45       }
46     case MATMPIBDIAG:
47       {
48       int nb = 1; /* Default block size = 1 */
49       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
50       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,newmat);
51       CHKERRQ(ierr);
52       break;
53       }
54     default:
55       SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported");
56   }
57   ierr = MatGetOwnershipRange(*newmat,&rstart,&rend); CHKERRQ(ierr);
58   for (i=rstart; i<rend; i++) {
59     ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
60     ierr = MatSetValues(*newmat,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
61     ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
62   }
63   ierr = MatAssemblyBegin(*newmat,FINAL_ASSEMBLY); CHKERRQ(ierr);
64   ierr = MatAssemblyEnd(*newmat,FINAL_ASSEMBLY); CHKERRQ(ierr);
65   return 0;
66 }
67 /* ------------------------------------------------------------------ */
68 /*
69   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
70   parallel format.
71  */
72 int MatConvert_MPIAIJ(Mat mat, MatType newtype, Mat *newmat)
73 {
74   Mat_MPIAIJ *aij = (Mat_MPIAIJ *) mat->data;
75   Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(aij->A->data), *Bd = (Mat_SeqAIJ *)(aij->B->data);
76   int        ierr, nz, i, ig,rstart = aij->rstart, m = aij->m, *cwork;
77   Scalar     *vwork;
78 
79   switch (newtype) {
80     case MATMPIROW:
81       ierr = MatCreateMPIRow(mat->comm,m,aij->n,aij->M,aij->N,0,Ad->ilen,
82 			0,Bd->ilen,newmat); CHKERRQ(ierr);
83       break;
84     default:
85       SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported");
86   }
87   /* Each processor converts its local rows */
88   for (i=0; i<m; i++) {
89     ig   = i + rstart;
90     ierr = MatGetRow(mat,ig,&nz,&cwork,&vwork);	CHKERRQ(ierr);
91     ierr = MatSetValues(*newmat,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
92     ierr = MatRestoreRow(mat,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
93   }
94   ierr = MatAssemblyBegin(*newmat,FINAL_ASSEMBLY); CHKERRQ(ierr);
95   ierr = MatAssemblyEnd(*newmat,FINAL_ASSEMBLY); CHKERRQ(ierr);
96   return 0;
97 }
98 
99 
100