xref: /petsc/src/mat/utils/convert.c (revision ed2daf618d39a4e4da77b7c71505379737a539fc)
156fe5c5cSLois Curfman McInnes #ifndef lint
2*ed2daf61SLois Curfman McInnes static char vcid[] = "$Id: convert.c,v 1.38 1995/11/30 22:34:51 bsmith Exp curfman $";
356fe5c5cSLois Curfman McInnes #endif
456fe5c5cSLois Curfman McInnes 
556fe5c5cSLois Curfman McInnes #include "mpiaij.h"
68b6375c0SLois Curfman McInnes #include "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 
118b6375c0SLois Curfman McInnes /*
128b6375c0SLois Curfman McInnes   MatConvert_Basic - Converts from any input format to another format. For
138b6375c0SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
148b6375c0SLois Curfman McInnes  */
158b6375c0SLois Curfman McInnes int MatConvert_Basic(Mat mat,MatType newtype,Mat *M)
168b6375c0SLois Curfman McInnes {
178b6375c0SLois Curfman McInnes   Scalar *vwork;
188b6375c0SLois Curfman McInnes   int    ierr, i, nz, m, n, *cwork, rstart, rend;
198b6375c0SLois Curfman McInnes   ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr);
207181dc05SLois Curfman McInnes   if (newtype == MATSAME) newtype = (MatType)mat->type;
218b6375c0SLois Curfman McInnes   switch (newtype) {
228b6375c0SLois Curfman McInnes     case MATSEQAIJ:
23*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqAIJ(mat->comm,m,n,0,PetscNull,M); CHKERRQ(ierr);
248b6375c0SLois Curfman McInnes       break;
258b6375c0SLois Curfman McInnes     case MATSEQROW:
26*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqRow(mat->comm,m,n,0,PetscNull,M); CHKERRQ(ierr);
278b6375c0SLois Curfman McInnes       break;
288b6375c0SLois Curfman McInnes     case MATMPIROW:
298b6375c0SLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
30*ed2daf61SLois Curfman McInnes              m,n,0,PetscNull,0,PetscNull,M); CHKERRQ(ierr);
318b6375c0SLois Curfman McInnes       break;
328b6375c0SLois Curfman McInnes     case MATMPIROWBS:
338b6375c0SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert:MATMPIROWBS matrix must be square");
34*ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PetscNull,
35*ed2daf61SLois Curfman McInnes              PetscNull,M); CHKERRQ(ierr);
368b6375c0SLois Curfman McInnes       break;
378b6375c0SLois Curfman McInnes     case MATMPIAIJ:
388b6375c0SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
39*ed2daf61SLois Curfman McInnes              m,n,0,PetscNull,0,PetscNull,M); CHKERRQ(ierr);
408b6375c0SLois Curfman McInnes       break;
418b6375c0SLois Curfman McInnes     case MATSEQDENSE:
42*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqDense(mat->comm,m,n,PetscNull,M); CHKERRQ(ierr);
438b6375c0SLois Curfman McInnes       break;
448b6375c0SLois Curfman McInnes     case MATMPIDENSE:
458b6375c0SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
46*ed2daf61SLois Curfman McInnes              m,n,PetscNull,M); CHKERRQ(ierr);
478b6375c0SLois Curfman McInnes       break;
488b6375c0SLois Curfman McInnes     case MATSEQBDIAG:
498b6375c0SLois Curfman McInnes       {
508b6375c0SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
512f8a729cSBarry Smith       OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb);
52*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,PetscNull,PetscNull,M); CHKERRQ(ierr);
538b6375c0SLois Curfman McInnes       break;
548b6375c0SLois Curfman McInnes       }
558b6375c0SLois Curfman McInnes     case MATMPIBDIAG:
568b6375c0SLois Curfman McInnes       {
578b6375c0SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
582f8a729cSBarry Smith       OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb);
59*ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PetscNull,
60*ed2daf61SLois Curfman McInnes              PetscNull,M); CHKERRQ(ierr);
618b6375c0SLois Curfman McInnes       break;
628b6375c0SLois Curfman McInnes       }
638b6375c0SLois Curfman McInnes     default:
648b6375c0SLois Curfman McInnes       SETERRQ(1,"MatConvert:Matrix type is not currently supported");
658b6375c0SLois Curfman McInnes   }
668b6375c0SLois Curfman McInnes   ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr);
678b6375c0SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
688b6375c0SLois Curfman McInnes     ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
698b6375c0SLois Curfman McInnes     ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
708b6375c0SLois Curfman McInnes     ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
718b6375c0SLois Curfman McInnes   }
728b6375c0SLois Curfman McInnes   ierr = MatAssemblyBegin(*M,FINAL_ASSEMBLY); CHKERRQ(ierr);
738b6375c0SLois Curfman McInnes   ierr = MatAssemblyEnd(*M,FINAL_ASSEMBLY); CHKERRQ(ierr);
748b6375c0SLois Curfman McInnes   return 0;
758b6375c0SLois Curfman McInnes }
768b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */
7756fe5c5cSLois Curfman McInnes /*
78ec8511deSBarry Smith   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
7944ae05bdSLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
8056fe5c5cSLois Curfman McInnes  */
812399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B)
8256fe5c5cSLois Curfman McInnes {
832399e097SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
8456fe5c5cSLois Curfman McInnes   Scalar     *vwork;
852399e097SLois Curfman McInnes   int        i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
8656fe5c5cSLois Curfman McInnes 
8756fe5c5cSLois Curfman McInnes   switch (newtype) {
88ec8511deSBarry Smith     case MATSEQROW:
892399e097SLois Curfman McInnes       ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr);
90416022c9SBarry Smith       break;
9144ae05bdSLois Curfman McInnes     case MATMPIROW:
9244ae05bdSLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
93*ed2daf61SLois Curfman McInnes              m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr);
94416022c9SBarry Smith       break;
95ec8511deSBarry Smith     case MATMPIROWBS:
962399e097SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square");
97*ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PetscNull,PetscNull,B);
98*ed2daf61SLois Curfman McInnes              CHKERRQ(ierr);
99416022c9SBarry Smith       break;
10044ae05bdSLois Curfman McInnes     case MATMPIAIJ:
10144ae05bdSLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
102*ed2daf61SLois Curfman McInnes              m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr);
103416022c9SBarry Smith       break;
104ec8511deSBarry Smith     case MATSEQDENSE:
105*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqDense(A->comm,m,n,PetscNull,B); CHKERRQ(ierr);
1062399e097SLois Curfman McInnes       break;
1072399e097SLois Curfman McInnes     case MATMPIDENSE:
1082399e097SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
109*ed2daf61SLois Curfman McInnes              m,n,PetscNull,B); CHKERRQ(ierr);
110416022c9SBarry Smith       break;
111ec8511deSBarry Smith     case MATSEQBDIAG:
112416022c9SBarry Smith       {
11358154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
1142f8a729cSBarry Smith       OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb);
115*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,PetscNull,PetscNull,B); CHKERRQ(ierr);
11644ae05bdSLois Curfman McInnes       break;
11744ae05bdSLois Curfman McInnes       }
11844ae05bdSLois Curfman McInnes     case MATMPIBDIAG:
119416022c9SBarry Smith       {
12058154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
1212f8a729cSBarry Smith       OptionsGetInt(PetscNull,"-mat_bdiag_bsize",&nb);
122*ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PetscNull,
123*ed2daf61SLois Curfman McInnes              PetscNull,B); CHKERRQ(ierr);
124416022c9SBarry Smith       break;
12556fe5c5cSLois Curfman McInnes       }
126f3ba505bSLois Curfman McInnes     default:
127ec8511deSBarry Smith       SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported");
128f3ba505bSLois Curfman McInnes   }
1292399e097SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
13044ae05bdSLois Curfman McInnes   for (i=rstart; i<rend; i++) {
1312399e097SLois Curfman McInnes     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1322399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1332399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
13456fe5c5cSLois Curfman McInnes   }
1352399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1362399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
13756fe5c5cSLois Curfman McInnes   return 0;
13856fe5c5cSLois Curfman McInnes }
13956fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */
14056fe5c5cSLois Curfman McInnes /*
1411fb19edaSLois Curfman McInnes   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
14256fe5c5cSLois Curfman McInnes   parallel format.
14356fe5c5cSLois Curfman McInnes  */
1442399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B)
14556fe5c5cSLois Curfman McInnes {
1462399e097SLois Curfman McInnes   Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data;
1472399e097SLois Curfman McInnes   Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data);
1482399e097SLois Curfman McInnes   int        ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork;
14956fe5c5cSLois Curfman McInnes   Scalar     *vwork;
15056fe5c5cSLois Curfman McInnes 
15156fe5c5cSLois Curfman McInnes   switch (newtype) {
1521fb19edaSLois Curfman McInnes     case MATMPIROW:
1532399e097SLois Curfman McInnes       ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen,
1542399e097SLois Curfman McInnes              0,Bd->ilen,B); CHKERRQ(ierr);
155abc0e9e4SLois Curfman McInnes       break;
15656fe5c5cSLois Curfman McInnes     default:
157bbb6d6a8SBarry Smith       SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported");
15856fe5c5cSLois Curfman McInnes   }
159abc0e9e4SLois Curfman McInnes   /* Each processor converts its local rows */
16056fe5c5cSLois Curfman McInnes   for (i=0; i<m; i++) {
16156fe5c5cSLois Curfman McInnes     ig   = i + rstart;
1622399e097SLois Curfman McInnes     ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
1632399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1642399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
16556fe5c5cSLois Curfman McInnes   }
1662399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1672399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
16856fe5c5cSLois Curfman McInnes   return 0;
16956fe5c5cSLois Curfman McInnes }
1708b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */
171567e79a1SLois Curfman McInnes /*
172567e79a1SLois Curfman McInnes   MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For
173567e79a1SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
174567e79a1SLois Curfman McInnes  */
175567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B)
176567e79a1SLois Curfman McInnes {
177567e79a1SLois Curfman McInnes   Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data;
1788b6375c0SLois Curfman McInnes   Scalar       *vwork, *vw2;
179567e79a1SLois Curfman McInnes   int          i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
1808b6375c0SLois Curfman McInnes   int          j, *cw2, ict;
181567e79a1SLois Curfman McInnes 
182dad23ff5SLois Curfman McInnes   /* rough over-estimate; could refine for individual rows */
1830452661fSBarry Smith   nz = PetscMin(n,a->nd*a->nb);
184567e79a1SLois Curfman McInnes   switch (newtype) {
185567e79a1SLois Curfman McInnes     case MATSEQAIJ:
186*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqAIJ(A->comm,m,n,nz,PetscNull,B); CHKERRQ(ierr);
187567e79a1SLois Curfman McInnes       break;
188567e79a1SLois Curfman McInnes     case MATSEQROW:
189*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqRow(A->comm,m,n,nz,PetscNull,B); CHKERRQ(ierr);
190567e79a1SLois Curfman McInnes       break;
191567e79a1SLois Curfman McInnes     case MATMPIROW:
192567e79a1SLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
193*ed2daf61SLois Curfman McInnes                              m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr);
194567e79a1SLois Curfman McInnes       break;
195567e79a1SLois Curfman McInnes     case MATMPIROWBS:
196567e79a1SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square");
197*ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PetscNull,PetscNull,
198*ed2daf61SLois Curfman McInnes              B); CHKERRQ(ierr);
199567e79a1SLois Curfman McInnes       break;
200567e79a1SLois Curfman McInnes     case MATMPIAIJ:
201567e79a1SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
202*ed2daf61SLois Curfman McInnes                              m,n,0,PetscNull,0,PetscNull,B); CHKERRQ(ierr);
203567e79a1SLois Curfman McInnes       break;
204567e79a1SLois Curfman McInnes     case MATSEQDENSE:
205*ed2daf61SLois Curfman McInnes       ierr = MatCreateSeqDense(A->comm,m,n,PetscNull,B); CHKERRQ(ierr);
206567e79a1SLois Curfman McInnes       break;
207567e79a1SLois Curfman McInnes     case MATMPIDENSE:
208567e79a1SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
209*ed2daf61SLois Curfman McInnes                                m,n,PetscNull,B); CHKERRQ(ierr);
210567e79a1SLois Curfman McInnes       break;
211567e79a1SLois Curfman McInnes     case MATMPIBDIAG:
212567e79a1SLois Curfman McInnes       {
213*ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,
214*ed2daf61SLois Curfman McInnes              PetscNull,PetscNull,B); CHKERRQ(ierr);
215567e79a1SLois Curfman McInnes       break;
216567e79a1SLois Curfman McInnes       }
217567e79a1SLois Curfman McInnes     default:
218567e79a1SLois Curfman McInnes       SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported");
219567e79a1SLois Curfman McInnes   }
220567e79a1SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
2218b6375c0SLois Curfman McInnes 
2220452661fSBarry Smith   cw2 = (int *)PetscMalloc( n * sizeof(int) ); CHKPTRQ(cw2);
2230452661fSBarry Smith   vw2 = (Scalar *)PetscMalloc( n * sizeof(Scalar) ); CHKPTRQ(vw2);
224567e79a1SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
225567e79a1SLois Curfman McInnes    ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
2268b6375c0SLois Curfman McInnes    ict = 0; /* strip out the zero elements ... is this what we really want? */
2278b6375c0SLois Curfman McInnes    for (j=0; j<nz; j++) {
2288b6375c0SLois Curfman McInnes      if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;}
2298b6375c0SLois Curfman McInnes    }
2308b6375c0SLois Curfman McInnes    if (ict)
2318b6375c0SLois Curfman McInnes      {ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr);}
232567e79a1SLois Curfman McInnes    ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
233567e79a1SLois Curfman McInnes   }
2340452661fSBarry Smith   PetscFree(cw2); PetscFree(vw2);
235567e79a1SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
236567e79a1SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
237567e79a1SLois Curfman McInnes   return 0;
238567e79a1SLois Curfman McInnes }
239