xref: /petsc/src/mat/utils/convert.c (revision dad23ff5a4f5c52bc6bb9bd0a07d18e754452cee)
1 #ifndef lint
2 static char vcid[] = "$Id: convert.c,v 1.31 1995/10/27 01:11:01 curfman Exp curfman $";
3 #endif
4 
5 /* This file contains implementation-specific matrix conversion routines.
6    For now, this has been implemented only for AIJ.  See MatConvert() for
7    generic conversion code. */
8 
9 #include "mpiaij.h"
10 
11 /*
12   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
13   parallel formats, the new matrix distribution is determined by PETSc.
14  */
15 int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B)
16 {
17   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
18   Scalar     *vwork;
19   int        i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
20 
21   switch (newtype) {
22     case MATSEQROW:
23       ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr);
24       break;
25     case MATMPIROW:
26       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
27                              m,n,0,0,0,0,B); CHKERRQ(ierr);
28       break;
29     case MATMPIROWBS:
30       if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square");
31       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr);
32       break;
33     case MATMPIAIJ:
34       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
35                              m,n,0,0,0,0,B); CHKERRQ(ierr);
36       break;
37     case MATSEQDENSE:
38       ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr);
39       break;
40     case MATMPIDENSE:
41       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
42                                m,n,B); CHKERRQ(ierr);
43       break;
44     case MATSEQBDIAG:
45       {
46       int nb = 1; /* Default block size = 1 */
47       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
48       ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,0,0,B); CHKERRQ(ierr);
49       break;
50       }
51     case MATMPIBDIAG:
52       {
53       int nb = 1; /* Default block size = 1 */
54       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
55       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,B);
56       CHKERRQ(ierr);
57       break;
58       }
59     default:
60       SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported");
61   }
62   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
63   for (i=rstart; i<rend; i++) {
64     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
65     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
66     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
67   }
68   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
69   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
70   return 0;
71 }
72 /* ------------------------------------------------------------------ */
73 /*
74   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
75   parallel format.
76  */
77 int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B)
78 {
79   Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data;
80   Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data);
81   int        ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork;
82   Scalar     *vwork;
83 
84   switch (newtype) {
85     case MATMPIROW:
86       ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen,
87 			0,Bd->ilen,B); CHKERRQ(ierr);
88       break;
89     default:
90       SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported");
91   }
92   /* Each processor converts its local rows */
93   for (i=0; i<m; i++) {
94     ig   = i + rstart;
95     ierr = MatGetRow(A,ig,&nz,&cwork,&vwork);	CHKERRQ(ierr);
96     ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
97     ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
98   }
99   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
100   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
101   return 0;
102 }
103 
104 #include "mpibdiag.h"
105 
106 /*
107   MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For
108   parallel formats, the new matrix distribution is determined by PETSc.
109  */
110 int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B)
111 {
112   Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data;
113   Scalar       *vwork;
114   int          i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
115 
116   /* rough over-estimate; could refine for individual rows */
117   nz = PETSCMIN(n,a->nd*a->nb);
118   switch (newtype) {
119     case MATSEQAIJ:
120       ierr = MatCreateSeqAIJ(A->comm,m,n,nz,0,B); CHKERRQ(ierr);
121       break;
122     case MATSEQROW:
123       ierr = MatCreateSeqRow(A->comm,m,n,nz,0,B); CHKERRQ(ierr);
124       break;
125     case MATMPIROW:
126       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
127                              m,n,0,0,0,0,B); CHKERRQ(ierr);
128       break;
129     case MATMPIROWBS:
130       if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square");
131       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr);
132       break;
133     case MATMPIAIJ:
134       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
135                              m,n,0,0,0,0,B); CHKERRQ(ierr);
136       break;
137     case MATSEQDENSE:
138       ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr);
139       break;
140     case MATMPIDENSE:
141       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
142                                m,n,B); CHKERRQ(ierr);
143       break;
144     case MATMPIBDIAG:
145       {
146       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,0,0,B);
147       CHKERRQ(ierr);
148       break;
149       }
150     default:
151       SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported");
152   }
153   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
154   for (i=rstart; i<rend; i++) {
155     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
156     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
157     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
158   }
159   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
160   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
161   return 0;
162 }
163