xref: /petsc/src/mat/utils/convert.c (revision 8b6375c0f5d137eb211dcd7d93cff531fdb12c2e)
156fe5c5cSLois Curfman McInnes #ifndef lint
2*8b6375c0SLois Curfman McInnes static char vcid[] = "$Id: convert.c,v 1.32 1995/10/27 01:26:46 curfman Exp curfman $";
356fe5c5cSLois Curfman McInnes #endif
456fe5c5cSLois Curfman McInnes 
556fe5c5cSLois Curfman McInnes #include "mpiaij.h"
6*8b6375c0SLois Curfman McInnes #include "mpibdiag.h"
756fe5c5cSLois Curfman McInnes 
8*8b6375c0SLois Curfman McInnes /* This file contains a generic conversion routine and implementation specific
9*8b6375c0SLois Curfman McInnes    versions for increased efficiency. */
10*8b6375c0SLois Curfman McInnes 
11*8b6375c0SLois Curfman McInnes /*
12*8b6375c0SLois Curfman McInnes   MatConvert_Basic - Converts from any input format to another format. For
13*8b6375c0SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
14*8b6375c0SLois Curfman McInnes  */
15*8b6375c0SLois Curfman McInnes int MatConvert_Basic(Mat mat,MatType newtype,Mat *M)
16*8b6375c0SLois Curfman McInnes {
17*8b6375c0SLois Curfman McInnes   Scalar *vwork;
18*8b6375c0SLois Curfman McInnes   int    ierr, i, nz, m, n, *cwork, rstart, rend;
19*8b6375c0SLois Curfman McInnes   ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr);
20*8b6375c0SLois Curfman McInnes   switch (newtype) {
21*8b6375c0SLois Curfman McInnes     case MATSEQAIJ:
22*8b6375c0SLois Curfman McInnes       ierr = MatCreateSeqAIJ(mat->comm,m,n,0,0,M); CHKERRQ(ierr);
23*8b6375c0SLois Curfman McInnes       break;
24*8b6375c0SLois Curfman McInnes     case MATSEQROW:
25*8b6375c0SLois Curfman McInnes       ierr = MatCreateSeqRow(mat->comm,m,n,0,0,M); CHKERRQ(ierr);
26*8b6375c0SLois Curfman McInnes       break;
27*8b6375c0SLois Curfman McInnes     case MATMPIROW:
28*8b6375c0SLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
29*8b6375c0SLois Curfman McInnes                              m,n,0,0,0,0,M); CHKERRQ(ierr);
30*8b6375c0SLois Curfman McInnes       break;
31*8b6375c0SLois Curfman McInnes     case MATMPIROWBS:
32*8b6375c0SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert:MATMPIROWBS matrix must be square");
33*8b6375c0SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,M);
34*8b6375c0SLois Curfman McInnes              CHKERRQ(ierr);
35*8b6375c0SLois Curfman McInnes       break;
36*8b6375c0SLois Curfman McInnes     case MATMPIAIJ:
37*8b6375c0SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
38*8b6375c0SLois Curfman McInnes                              m,n,0,0,0,0,M); CHKERRQ(ierr);
39*8b6375c0SLois Curfman McInnes       break;
40*8b6375c0SLois Curfman McInnes     case MATSEQDENSE:
41*8b6375c0SLois Curfman McInnes       ierr = MatCreateSeqDense(mat->comm,m,n,M); CHKERRQ(ierr);
42*8b6375c0SLois Curfman McInnes       break;
43*8b6375c0SLois Curfman McInnes     case MATMPIDENSE:
44*8b6375c0SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
45*8b6375c0SLois Curfman McInnes                                m,n,M); CHKERRQ(ierr);
46*8b6375c0SLois Curfman McInnes       break;
47*8b6375c0SLois Curfman McInnes     case MATSEQBDIAG:
48*8b6375c0SLois Curfman McInnes       {
49*8b6375c0SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
50*8b6375c0SLois Curfman McInnes       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
51*8b6375c0SLois Curfman McInnes       ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,0,0,M); CHKERRQ(ierr);
52*8b6375c0SLois Curfman McInnes       break;
53*8b6375c0SLois Curfman McInnes       }
54*8b6375c0SLois Curfman McInnes     case MATMPIBDIAG:
55*8b6375c0SLois Curfman McInnes       {
56*8b6375c0SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
57*8b6375c0SLois Curfman McInnes       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
58*8b6375c0SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,M);
59*8b6375c0SLois Curfman McInnes       CHKERRQ(ierr);
60*8b6375c0SLois Curfman McInnes       break;
61*8b6375c0SLois Curfman McInnes       }
62*8b6375c0SLois Curfman McInnes     default:
63*8b6375c0SLois Curfman McInnes       SETERRQ(1,"MatConvert:Matrix type is not currently supported");
64*8b6375c0SLois Curfman McInnes   }
65*8b6375c0SLois Curfman McInnes   ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr);
66*8b6375c0SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
67*8b6375c0SLois Curfman McInnes     ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
68*8b6375c0SLois Curfman McInnes     ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
69*8b6375c0SLois Curfman McInnes     ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
70*8b6375c0SLois Curfman McInnes   }
71*8b6375c0SLois Curfman McInnes   ierr = MatAssemblyBegin(*M,FINAL_ASSEMBLY); CHKERRQ(ierr);
72*8b6375c0SLois Curfman McInnes   ierr = MatAssemblyEnd(*M,FINAL_ASSEMBLY); CHKERRQ(ierr);
73*8b6375c0SLois Curfman McInnes   return 0;
74*8b6375c0SLois Curfman McInnes }
75*8b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */
7656fe5c5cSLois Curfman McInnes /*
77ec8511deSBarry Smith   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
7844ae05bdSLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
7956fe5c5cSLois Curfman McInnes  */
802399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B)
8156fe5c5cSLois Curfman McInnes {
822399e097SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
8356fe5c5cSLois Curfman McInnes   Scalar     *vwork;
842399e097SLois Curfman McInnes   int        i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
8556fe5c5cSLois Curfman McInnes 
8656fe5c5cSLois Curfman McInnes   switch (newtype) {
87ec8511deSBarry Smith     case MATSEQROW:
882399e097SLois Curfman McInnes       ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr);
89416022c9SBarry Smith       break;
9044ae05bdSLois Curfman McInnes     case MATMPIROW:
9144ae05bdSLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
922399e097SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
93416022c9SBarry Smith       break;
94ec8511deSBarry Smith     case MATMPIROWBS:
952399e097SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square");
962399e097SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr);
97416022c9SBarry Smith       break;
9844ae05bdSLois Curfman McInnes     case MATMPIAIJ:
9944ae05bdSLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
1002399e097SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
101416022c9SBarry Smith       break;
102ec8511deSBarry Smith     case MATSEQDENSE:
1032399e097SLois Curfman McInnes       ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr);
1042399e097SLois Curfman McInnes       break;
1052399e097SLois Curfman McInnes     case MATMPIDENSE:
1062399e097SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
1072399e097SLois Curfman McInnes                                m,n,B); CHKERRQ(ierr);
108416022c9SBarry Smith       break;
109ec8511deSBarry Smith     case MATSEQBDIAG:
110416022c9SBarry Smith       {
11158154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
112df60cc22SBarry Smith       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
1132399e097SLois Curfman McInnes       ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,0,0,B); CHKERRQ(ierr);
11444ae05bdSLois Curfman McInnes       break;
11544ae05bdSLois Curfman McInnes       }
11644ae05bdSLois Curfman McInnes     case MATMPIBDIAG:
117416022c9SBarry Smith       {
11858154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
11944ae05bdSLois Curfman McInnes       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
1202399e097SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,B);
12178b31e54SBarry Smith       CHKERRQ(ierr);
122416022c9SBarry Smith       break;
12356fe5c5cSLois Curfman McInnes       }
124f3ba505bSLois Curfman McInnes     default:
125ec8511deSBarry Smith       SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported");
126f3ba505bSLois Curfman McInnes   }
1272399e097SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
12844ae05bdSLois Curfman McInnes   for (i=rstart; i<rend; i++) {
1292399e097SLois Curfman McInnes     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1302399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1312399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
13256fe5c5cSLois Curfman McInnes   }
1332399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1342399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
13556fe5c5cSLois Curfman McInnes   return 0;
13656fe5c5cSLois Curfman McInnes }
13756fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */
13856fe5c5cSLois Curfman McInnes /*
1391fb19edaSLois Curfman McInnes   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
14056fe5c5cSLois Curfman McInnes   parallel format.
14156fe5c5cSLois Curfman McInnes  */
1422399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B)
14356fe5c5cSLois Curfman McInnes {
1442399e097SLois Curfman McInnes   Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data;
1452399e097SLois Curfman McInnes   Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data);
1462399e097SLois Curfman McInnes   int        ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork;
14756fe5c5cSLois Curfman McInnes   Scalar     *vwork;
14856fe5c5cSLois Curfman McInnes 
14956fe5c5cSLois Curfman McInnes   switch (newtype) {
1501fb19edaSLois Curfman McInnes     case MATMPIROW:
1512399e097SLois Curfman McInnes       ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen,
1522399e097SLois Curfman McInnes 			0,Bd->ilen,B); CHKERRQ(ierr);
153abc0e9e4SLois Curfman McInnes       break;
15456fe5c5cSLois Curfman McInnes     default:
155bbb6d6a8SBarry Smith       SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported");
15656fe5c5cSLois Curfman McInnes   }
157abc0e9e4SLois Curfman McInnes   /* Each processor converts its local rows */
15856fe5c5cSLois Curfman McInnes   for (i=0; i<m; i++) {
15956fe5c5cSLois Curfman McInnes     ig   = i + rstart;
1602399e097SLois Curfman McInnes     ierr = MatGetRow(A,ig,&nz,&cwork,&vwork);	CHKERRQ(ierr);
1612399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1622399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
16356fe5c5cSLois Curfman McInnes   }
1642399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1652399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
16656fe5c5cSLois Curfman McInnes   return 0;
16756fe5c5cSLois Curfman McInnes }
168*8b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */
169567e79a1SLois Curfman McInnes /*
170567e79a1SLois Curfman McInnes   MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For
171567e79a1SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
172567e79a1SLois Curfman McInnes  */
173567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B)
174567e79a1SLois Curfman McInnes {
175567e79a1SLois Curfman McInnes   Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data;
176*8b6375c0SLois Curfman McInnes   Scalar       *vwork, *vw2;
177567e79a1SLois Curfman McInnes   int          i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
178*8b6375c0SLois Curfman McInnes   int          j, *cw2, ict;
179567e79a1SLois Curfman McInnes 
180dad23ff5SLois Curfman McInnes   /* rough over-estimate; could refine for individual rows */
181dad23ff5SLois Curfman McInnes   nz = PETSCMIN(n,a->nd*a->nb);
182567e79a1SLois Curfman McInnes   switch (newtype) {
183567e79a1SLois Curfman McInnes     case MATSEQAIJ:
184567e79a1SLois Curfman McInnes       ierr = MatCreateSeqAIJ(A->comm,m,n,nz,0,B); CHKERRQ(ierr);
185567e79a1SLois Curfman McInnes       break;
186567e79a1SLois Curfman McInnes     case MATSEQROW:
187567e79a1SLois Curfman McInnes       ierr = MatCreateSeqRow(A->comm,m,n,nz,0,B); CHKERRQ(ierr);
188567e79a1SLois Curfman McInnes       break;
189567e79a1SLois Curfman McInnes     case MATMPIROW:
190567e79a1SLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
191567e79a1SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
192567e79a1SLois Curfman McInnes       break;
193567e79a1SLois Curfman McInnes     case MATMPIROWBS:
194567e79a1SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square");
195567e79a1SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr);
196567e79a1SLois Curfman McInnes       break;
197567e79a1SLois Curfman McInnes     case MATMPIAIJ:
198567e79a1SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
199567e79a1SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
200567e79a1SLois Curfman McInnes       break;
201567e79a1SLois Curfman McInnes     case MATSEQDENSE:
202567e79a1SLois Curfman McInnes       ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr);
203567e79a1SLois Curfman McInnes       break;
204567e79a1SLois Curfman McInnes     case MATMPIDENSE:
205567e79a1SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
206567e79a1SLois Curfman McInnes                                m,n,B); CHKERRQ(ierr);
207567e79a1SLois Curfman McInnes       break;
208567e79a1SLois Curfman McInnes     case MATMPIBDIAG:
209567e79a1SLois Curfman McInnes       {
210567e79a1SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,0,0,B);
211567e79a1SLois Curfman McInnes       CHKERRQ(ierr);
212567e79a1SLois Curfman McInnes       break;
213567e79a1SLois Curfman McInnes       }
214567e79a1SLois Curfman McInnes     default:
215567e79a1SLois Curfman McInnes       SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported");
216567e79a1SLois Curfman McInnes   }
217567e79a1SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
218*8b6375c0SLois Curfman McInnes 
219*8b6375c0SLois Curfman McInnes   cw2 = (int *)PETSCMALLOC( n * sizeof(int) ); CHKPTRQ(cw2);
220*8b6375c0SLois Curfman McInnes   vw2 = (Scalar *)PETSCMALLOC( n * sizeof(Scalar) ); CHKPTRQ(vw2);
221567e79a1SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
222567e79a1SLois Curfman McInnes    ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
223*8b6375c0SLois Curfman McInnes    ict = 0; /* strip out the zero elements ... is this what we really want? */
224*8b6375c0SLois Curfman McInnes    for (j=0; j<nz; j++) {
225*8b6375c0SLois Curfman McInnes      if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;}
226*8b6375c0SLois Curfman McInnes    }
227*8b6375c0SLois Curfman McInnes    if (ict)
228*8b6375c0SLois Curfman McInnes      {ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr);}
229567e79a1SLois Curfman McInnes    ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
230567e79a1SLois Curfman McInnes   }
231*8b6375c0SLois Curfman McInnes   PETSCFREE(cw2); PETSCFREE(vw2);
232567e79a1SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
233567e79a1SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
234567e79a1SLois Curfman McInnes   return 0;
235567e79a1SLois Curfman McInnes }
236