xref: /petsc/src/mat/utils/convert.c (revision 5615d1e584023db9367fb782d85b1b4ebbb8df18)
156fe5c5cSLois Curfman McInnes #ifndef lint
2*5615d1e5SSatish Balay static char vcid[] = "$Id: convert.c,v 1.56 1997/01/01 03:38:57 bsmith Exp balay $";
356fe5c5cSLois Curfman McInnes #endif
456fe5c5cSLois Curfman McInnes 
570f55243SBarry Smith #include "src/mat/impls/aij/mpi/mpiaij.h"
670f55243SBarry Smith #include "src/mat/impls/bdiag/mpi/mpibdiag.h"
756fe5c5cSLois Curfman McInnes 
88b6375c0SLois Curfman McInnes /* This file contains a generic conversion routine and implementation specific
98b6375c0SLois Curfman McInnes    versions for increased efficiency. */
108b6375c0SLois Curfman McInnes 
11*5615d1e5SSatish Balay #undef __FUNC__
12*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_Basic"
138b6375c0SLois Curfman McInnes /*
148b6375c0SLois Curfman McInnes   MatConvert_Basic - Converts from any input format to another format. For
158b6375c0SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
168b6375c0SLois Curfman McInnes  */
178b6375c0SLois Curfman McInnes int MatConvert_Basic(Mat mat,MatType newtype,Mat *M)
188b6375c0SLois Curfman McInnes {
198b6375c0SLois Curfman McInnes   Scalar *vwork;
2025cdf11fSBarry Smith   int    ierr, i, nz, m, n, *cwork, rstart, rend,flg;
2125cdf11fSBarry Smith 
228b6375c0SLois Curfman McInnes   ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr);
237181dc05SLois Curfman McInnes   if (newtype == MATSAME) newtype = (MatType)mat->type;
248b6375c0SLois Curfman McInnes   switch (newtype) {
258b6375c0SLois Curfman McInnes     case MATSEQAIJ:
26b4fd4287SBarry Smith       ierr = MatCreateSeqAIJ(mat->comm,m,n,0,PETSC_NULL,M); CHKERRQ(ierr);
278b6375c0SLois Curfman McInnes       break;
288b6375c0SLois Curfman McInnes     case MATMPIROWBS:
29e3372554SBarry Smith       if (m != n) SETERRQ(1,0,"MATMPIROWBS matrix must be square");
303b2fbd54SBarry Smith       ierr = MatCreateMPIRowbs(mat->comm,PETSC_DECIDE,m,0,PETSC_NULL,
31b4fd4287SBarry Smith              PETSC_NULL,M); CHKERRQ(ierr);
328b6375c0SLois Curfman McInnes       break;
338b6375c0SLois Curfman McInnes     case MATMPIAIJ:
343b2fbd54SBarry Smith       ierr = MatCreateMPIAIJ(mat->comm,PETSC_DECIDE,PETSC_DECIDE,
35b4fd4287SBarry Smith              m,n,0,PETSC_NULL,0,PETSC_NULL,M); CHKERRQ(ierr);
368b6375c0SLois Curfman McInnes       break;
378b6375c0SLois Curfman McInnes     case MATSEQDENSE:
38b4fd4287SBarry Smith       ierr = MatCreateSeqDense(mat->comm,m,n,PETSC_NULL,M); CHKERRQ(ierr);
398b6375c0SLois Curfman McInnes       break;
408b6375c0SLois Curfman McInnes     case MATMPIDENSE:
413b2fbd54SBarry Smith       ierr = MatCreateMPIDense(mat->comm,PETSC_DECIDE,PETSC_DECIDE,
42b4fd4287SBarry Smith              m,n,PETSC_NULL,M); CHKERRQ(ierr);
438b6375c0SLois Curfman McInnes       break;
448b6375c0SLois Curfman McInnes     case MATSEQBDIAG:
458b6375c0SLois Curfman McInnes       {
46537820f0SBarry Smith       int bs = 1; /* Default block size = 1 */
47537820f0SBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
48537820f0SBarry Smith       ierr = MatCreateSeqBDiag(mat->comm,m,n,0,bs,PETSC_NULL,PETSC_NULL,M);CHKERRQ(ierr);
498b6375c0SLois Curfman McInnes       break;
508b6375c0SLois Curfman McInnes       }
518b6375c0SLois Curfman McInnes     case MATMPIBDIAG:
528b6375c0SLois Curfman McInnes       {
53537820f0SBarry Smith       int bs = 1; /* Default block size = 1 */
54537820f0SBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
553b2fbd54SBarry Smith       ierr = MatCreateMPIBDiag(mat->comm,PETSC_DECIDE,m,n,0,bs,PETSC_NULL,
56b4fd4287SBarry Smith              PETSC_NULL,M); CHKERRQ(ierr);
578b6375c0SLois Curfman McInnes       break;
588b6375c0SLois Curfman McInnes       }
598b6375c0SLois Curfman McInnes     default:
60e3372554SBarry Smith       SETERRQ(1,0,"Matrix type is not currently supported");
618b6375c0SLois Curfman McInnes   }
628b6375c0SLois Curfman McInnes   ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr);
638b6375c0SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
648b6375c0SLois Curfman McInnes     ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
658b6375c0SLois Curfman McInnes     ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
668b6375c0SLois Curfman McInnes     ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
678b6375c0SLois Curfman McInnes   }
686d4a8577SBarry Smith   ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
696d4a8577SBarry Smith   ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
708b6375c0SLois Curfman McInnes   return 0;
718b6375c0SLois Curfman McInnes }
728b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */
73*5615d1e5SSatish Balay #undef __FUNC__
74*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_SeqAIJ"
7556fe5c5cSLois Curfman McInnes /*
76ec8511deSBarry Smith   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
7744ae05bdSLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
7856fe5c5cSLois Curfman McInnes  */
792399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B)
8056fe5c5cSLois Curfman McInnes {
812399e097SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
8256fe5c5cSLois Curfman McInnes   Scalar     *vwork;
835dd7a6c7SBarry Smith   int        i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend,flg;
8456fe5c5cSLois Curfman McInnes 
8556fe5c5cSLois Curfman McInnes   switch (newtype) {
86ec8511deSBarry Smith     case MATMPIROWBS:
87e3372554SBarry Smith       if (m != n) SETERRQ(1,0,"MATMPIROWBS matrix must be square");
883b2fbd54SBarry Smith       ierr = MatCreateMPIRowbs(A->comm,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL,B);
89ed2daf61SLois Curfman McInnes              CHKERRQ(ierr);
90416022c9SBarry Smith       break;
9144ae05bdSLois Curfman McInnes     case MATMPIAIJ:
923b2fbd54SBarry Smith       ierr = MatCreateMPIAIJ(A->comm,PETSC_DECIDE,PETSC_DECIDE,
93b4fd4287SBarry Smith              m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr);
94416022c9SBarry Smith       break;
95ec8511deSBarry Smith     case MATSEQDENSE:
96b4fd4287SBarry Smith       ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr);
972399e097SLois Curfman McInnes       break;
982399e097SLois Curfman McInnes     case MATMPIDENSE:
993b2fbd54SBarry Smith       ierr = MatCreateMPIDense(A->comm,PETSC_DECIDE,PETSC_DECIDE,
100b4fd4287SBarry Smith              m,n,PETSC_NULL,B); CHKERRQ(ierr);
101416022c9SBarry Smith       break;
102ec8511deSBarry Smith     case MATSEQBDIAG:
103416022c9SBarry Smith       {
104537820f0SBarry Smith       int bs = 1; /* Default block size = 1 */
105537820f0SBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
106537820f0SBarry Smith       ierr = MatCreateSeqBDiag(A->comm,m,n,0,bs,PETSC_NULL,PETSC_NULL,B);
107a2ce50c7SBarry Smith              CHKERRQ(ierr);
10844ae05bdSLois Curfman McInnes       break;
10944ae05bdSLois Curfman McInnes       }
11044ae05bdSLois Curfman McInnes     case MATMPIBDIAG:
111416022c9SBarry Smith       {
112537820f0SBarry Smith       int bs = 1; /* Default block size = 1 */
113537820f0SBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&bs,&flg);CHKERRQ(ierr);
11435aab85fSBarry Smith              CHKERRQ(ierr);
1153b2fbd54SBarry Smith       ierr = MatCreateMPIBDiag(A->comm,PETSC_DECIDE,m,n,0,bs,PETSC_NULL,
116b4fd4287SBarry Smith              PETSC_NULL,B); CHKERRQ(ierr);
117416022c9SBarry Smith       break;
11856fe5c5cSLois Curfman McInnes       }
119f3ba505bSLois Curfman McInnes     default:
120e3372554SBarry Smith       SETERRQ(1,0,"Matrix type is not currently supported");
121f3ba505bSLois Curfman McInnes   }
1222399e097SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
12344ae05bdSLois Curfman McInnes   for (i=rstart; i<rend; i++) {
1242399e097SLois Curfman McInnes     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1252399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1262399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
12756fe5c5cSLois Curfman McInnes   }
1286d4a8577SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1296d4a8577SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
13056fe5c5cSLois Curfman McInnes   return 0;
13156fe5c5cSLois Curfman McInnes }
13256fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */
133*5615d1e5SSatish Balay #undef __FUNC__
134*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_MPIAIJ"
13556fe5c5cSLois Curfman McInnes /*
1361fb19edaSLois Curfman McInnes   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
13756fe5c5cSLois Curfman McInnes   parallel format.
13856fe5c5cSLois Curfman McInnes  */
1392399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B)
14056fe5c5cSLois Curfman McInnes {
141e3372554SBarry Smith   SETERRQ(1,0,"Not currently suported");
142c456f294SBarry Smith 
143abc0e9e4SLois Curfman McInnes   /* Each processor converts its local rows */
1440ff6cd27SBarry Smith /* ----------------------------------------------------
145d9ce839aSLois Curfman McInnes   Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data;
146d9ce839aSLois Curfman McInnes   int        ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork;
147d9ce839aSLois Curfman McInnes   Scalar     *vwork;
148d9ce839aSLois Curfman McInnes 
14956fe5c5cSLois Curfman McInnes   for (i=0; i<m; i++) {
15056fe5c5cSLois Curfman McInnes     ig   = i + rstart;
1512399e097SLois Curfman McInnes     ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
1522399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1532399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
15456fe5c5cSLois Curfman McInnes   }
1556d4a8577SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
1566d4a8577SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
15756fe5c5cSLois Curfman McInnes   return 0;
1580ff6cd27SBarry Smith ---------------------------------------------------------*/
15956fe5c5cSLois Curfman McInnes }
1608b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */
161*5615d1e5SSatish Balay #undef __FUNC__
162*5615d1e5SSatish Balay #define __FUNC__ "MatConvert_SeqBDiag"
163567e79a1SLois Curfman McInnes /*
164567e79a1SLois Curfman McInnes   MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For
165567e79a1SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
166567e79a1SLois Curfman McInnes  */
167567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B)
168567e79a1SLois Curfman McInnes {
169567e79a1SLois Curfman McInnes   Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data;
1708b6375c0SLois Curfman McInnes   Scalar       *vwork, *vw2;
171567e79a1SLois Curfman McInnes   int          i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
1728b6375c0SLois Curfman McInnes   int          j, *cw2, ict;
173567e79a1SLois Curfman McInnes 
174dad23ff5SLois Curfman McInnes   /* rough over-estimate; could refine for individual rows */
175537820f0SBarry Smith   nz = PetscMin(n,a->nd*a->bs);
176567e79a1SLois Curfman McInnes   switch (newtype) {
177567e79a1SLois Curfman McInnes     case MATSEQAIJ:
178b4fd4287SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,m,n,nz,PETSC_NULL,B); CHKERRQ(ierr);
179567e79a1SLois Curfman McInnes       break;
180567e79a1SLois Curfman McInnes     case MATMPIROWBS:
181e3372554SBarry Smith       if (m != n) SETERRQ(1,0,"MATMPIROWBS matrix must be square");
1823b2fbd54SBarry Smith       ierr = MatCreateMPIRowbs(A->comm,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL,
183ed2daf61SLois Curfman McInnes              B); CHKERRQ(ierr);
184567e79a1SLois Curfman McInnes       break;
185567e79a1SLois Curfman McInnes     case MATMPIAIJ:
1863b2fbd54SBarry Smith       ierr = MatCreateMPIAIJ(A->comm,PETSC_DECIDE,PETSC_DECIDE,
187b4fd4287SBarry Smith                              m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr);
188567e79a1SLois Curfman McInnes       break;
189567e79a1SLois Curfman McInnes     case MATSEQDENSE:
190b4fd4287SBarry Smith       ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr);
191567e79a1SLois Curfman McInnes       break;
192567e79a1SLois Curfman McInnes     case MATMPIDENSE:
1933b2fbd54SBarry Smith       ierr = MatCreateMPIDense(A->comm,PETSC_DECIDE,PETSC_DECIDE,
194b4fd4287SBarry Smith                                m,n,PETSC_NULL,B); CHKERRQ(ierr);
195567e79a1SLois Curfman McInnes       break;
196567e79a1SLois Curfman McInnes     case MATMPIBDIAG:
197567e79a1SLois Curfman McInnes       {
1983b2fbd54SBarry Smith       ierr = MatCreateMPIBDiag(A->comm,PETSC_DECIDE,m,n,a->nd,a->bs,
199b4fd4287SBarry Smith              PETSC_NULL,PETSC_NULL,B); CHKERRQ(ierr);
200567e79a1SLois Curfman McInnes       break;
201567e79a1SLois Curfman McInnes       }
202567e79a1SLois Curfman McInnes     default:
203e3372554SBarry Smith       SETERRQ(1,0,"Matrix type is not currently supported");
204567e79a1SLois Curfman McInnes   }
205567e79a1SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
2068b6375c0SLois Curfman McInnes 
2070452661fSBarry Smith   cw2 = (int *)PetscMalloc( n * sizeof(int) ); CHKPTRQ(cw2);
2080452661fSBarry Smith   vw2 = (Scalar *)PetscMalloc( n * sizeof(Scalar) ); CHKPTRQ(vw2);
209567e79a1SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
210567e79a1SLois Curfman McInnes    ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
2118b6375c0SLois Curfman McInnes    ict = 0; /* strip out the zero elements ... is this what we really want? */
2128b6375c0SLois Curfman McInnes    for (j=0; j<nz; j++) {
2138b6375c0SLois Curfman McInnes      if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;}
2148b6375c0SLois Curfman McInnes    }
2156d84be18SBarry Smith    if (ict) {
2166d84be18SBarry Smith      ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr);
2176d84be18SBarry Smith    }
218567e79a1SLois Curfman McInnes    ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
219567e79a1SLois Curfman McInnes   }
2200452661fSBarry Smith   PetscFree(cw2); PetscFree(vw2);
2216d4a8577SBarry Smith   ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
2226d4a8577SBarry Smith   ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr);
223567e79a1SLois Curfman McInnes   return 0;
224567e79a1SLois Curfman McInnes }
225