xref: /petsc/src/mat/utils/convert.c (revision 6d84be18fbb99ba69be7b8bdde5411a66955b7ea)
156fe5c5cSLois Curfman McInnes #ifndef lint
2*6d84be18SBarry Smith static char vcid[] = "$Id: convert.c,v 1.46 1996/02/13 23:30:02 bsmith Exp bsmith $";
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;
1825cdf11fSBarry Smith   int    ierr, i, nz, m, n, *cwork, rstart, rend,flg;
1925cdf11fSBarry Smith 
208b6375c0SLois Curfman McInnes   ierr = MatGetSize(mat,&m,&n); CHKERRQ(ierr);
217181dc05SLois Curfman McInnes   if (newtype == MATSAME) newtype = (MatType)mat->type;
228b6375c0SLois Curfman McInnes   switch (newtype) {
238b6375c0SLois Curfman McInnes     case MATSEQAIJ:
24b4fd4287SBarry Smith       ierr = MatCreateSeqAIJ(mat->comm,m,n,0,PETSC_NULL,M); CHKERRQ(ierr);
258b6375c0SLois Curfman McInnes       break;
268b6375c0SLois Curfman McInnes     case MATMPIROWBS:
278b6375c0SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert:MATMPIROWBS matrix must be square");
28b4fd4287SBarry Smith       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PETSC_NULL,
29b4fd4287SBarry Smith              PETSC_NULL,M); CHKERRQ(ierr);
308b6375c0SLois Curfman McInnes       break;
318b6375c0SLois Curfman McInnes     case MATMPIAIJ:
328b6375c0SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
33b4fd4287SBarry Smith              m,n,0,PETSC_NULL,0,PETSC_NULL,M); CHKERRQ(ierr);
348b6375c0SLois Curfman McInnes       break;
358b6375c0SLois Curfman McInnes     case MATSEQDENSE:
36b4fd4287SBarry Smith       ierr = MatCreateSeqDense(mat->comm,m,n,PETSC_NULL,M); CHKERRQ(ierr);
378b6375c0SLois Curfman McInnes       break;
388b6375c0SLois Curfman McInnes     case MATMPIDENSE:
398b6375c0SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
40b4fd4287SBarry Smith              m,n,PETSC_NULL,M); CHKERRQ(ierr);
418b6375c0SLois Curfman McInnes       break;
428b6375c0SLois Curfman McInnes     case MATSEQBDIAG:
438b6375c0SLois Curfman McInnes       {
448b6375c0SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
4535aab85fSBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);  CHKERRQ(ierr);
46b4fd4287SBarry Smith       ierr = MatCreateSeqBDiag(mat->comm,m,n,0,nb,PETSC_NULL,PETSC_NULL,M); CHKERRQ(ierr);
478b6375c0SLois Curfman McInnes       break;
488b6375c0SLois Curfman McInnes       }
498b6375c0SLois Curfman McInnes     case MATMPIBDIAG:
508b6375c0SLois Curfman McInnes       {
518b6375c0SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
5235aab85fSBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr);
53b4fd4287SBarry Smith       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PETSC_NULL,
54b4fd4287SBarry Smith              PETSC_NULL,M); CHKERRQ(ierr);
558b6375c0SLois Curfman McInnes       break;
568b6375c0SLois Curfman McInnes       }
578b6375c0SLois Curfman McInnes     default:
588b6375c0SLois Curfman McInnes       SETERRQ(1,"MatConvert:Matrix type is not currently supported");
598b6375c0SLois Curfman McInnes   }
608b6375c0SLois Curfman McInnes   ierr = MatGetOwnershipRange(*M,&rstart,&rend); CHKERRQ(ierr);
618b6375c0SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
628b6375c0SLois Curfman McInnes     ierr = MatGetRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
638b6375c0SLois Curfman McInnes     ierr = MatSetValues(*M,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
648b6375c0SLois Curfman McInnes     ierr = MatRestoreRow(mat,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
658b6375c0SLois Curfman McInnes   }
668b6375c0SLois Curfman McInnes   ierr = MatAssemblyBegin(*M,FINAL_ASSEMBLY); CHKERRQ(ierr);
678b6375c0SLois Curfman McInnes   ierr = MatAssemblyEnd(*M,FINAL_ASSEMBLY); CHKERRQ(ierr);
688b6375c0SLois Curfman McInnes   return 0;
698b6375c0SLois Curfman McInnes }
708b6375c0SLois Curfman McInnes /* -------------------------------------------------------------- */
7156fe5c5cSLois Curfman McInnes /*
72ec8511deSBarry Smith   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
7344ae05bdSLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
7456fe5c5cSLois Curfman McInnes  */
752399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B)
7656fe5c5cSLois Curfman McInnes {
772399e097SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
7856fe5c5cSLois Curfman McInnes   Scalar     *vwork;
795dd7a6c7SBarry Smith   int        i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend,flg;
8056fe5c5cSLois Curfman McInnes 
8156fe5c5cSLois Curfman McInnes   switch (newtype) {
82ec8511deSBarry Smith     case MATMPIROWBS:
832399e097SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square");
84b4fd4287SBarry Smith       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL,B);
85ed2daf61SLois Curfman McInnes              CHKERRQ(ierr);
86416022c9SBarry Smith       break;
8744ae05bdSLois Curfman McInnes     case MATMPIAIJ:
8844ae05bdSLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
89b4fd4287SBarry Smith              m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr);
90416022c9SBarry Smith       break;
91ec8511deSBarry Smith     case MATSEQDENSE:
92b4fd4287SBarry Smith       ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr);
932399e097SLois Curfman McInnes       break;
942399e097SLois Curfman McInnes     case MATMPIDENSE:
952399e097SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
96b4fd4287SBarry Smith              m,n,PETSC_NULL,B); CHKERRQ(ierr);
97416022c9SBarry Smith       break;
98ec8511deSBarry Smith     case MATSEQBDIAG:
99416022c9SBarry Smith       {
10058154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
10135aab85fSBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr);
102b4fd4287SBarry Smith       ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,PETSC_NULL,PETSC_NULL,B);CHKERRQ(ierr);
10344ae05bdSLois Curfman McInnes       break;
10444ae05bdSLois Curfman McInnes       }
10544ae05bdSLois Curfman McInnes     case MATMPIBDIAG:
106416022c9SBarry Smith       {
10758154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
10835aab85fSBarry Smith       ierr = OptionsGetInt(PETSC_NULL,"-mat_block_size",&nb,&flg);CHKERRQ(ierr);
10935aab85fSBarry Smith              CHKERRQ(ierr);
110b4fd4287SBarry Smith       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,PETSC_NULL,
111b4fd4287SBarry Smith              PETSC_NULL,B); CHKERRQ(ierr);
112416022c9SBarry Smith       break;
11356fe5c5cSLois Curfman McInnes       }
114f3ba505bSLois Curfman McInnes     default:
115ec8511deSBarry Smith       SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported");
116f3ba505bSLois Curfman McInnes   }
1172399e097SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
11844ae05bdSLois Curfman McInnes   for (i=rstart; i<rend; i++) {
1192399e097SLois Curfman McInnes     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
1202399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1212399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
12256fe5c5cSLois Curfman McInnes   }
1232399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1242399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
12556fe5c5cSLois Curfman McInnes   return 0;
12656fe5c5cSLois Curfman McInnes }
12756fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */
12856fe5c5cSLois Curfman McInnes /*
1291fb19edaSLois Curfman McInnes   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
13056fe5c5cSLois Curfman McInnes   parallel format.
13156fe5c5cSLois Curfman McInnes  */
1322399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B)
13356fe5c5cSLois Curfman McInnes {
134c456f294SBarry Smith   SETERRQ(1,"MatConvert_MPIAIJ:Not currently suported");
135c456f294SBarry Smith 
136abc0e9e4SLois Curfman McInnes   /* Each processor converts its local rows */
1370ff6cd27SBarry Smith /* ----------------------------------------------------
138d9ce839aSLois Curfman McInnes   Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data;
139d9ce839aSLois Curfman McInnes   int        ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork;
140d9ce839aSLois Curfman McInnes   Scalar     *vwork;
141d9ce839aSLois Curfman McInnes 
14256fe5c5cSLois Curfman McInnes   for (i=0; i<m; i++) {
14356fe5c5cSLois Curfman McInnes     ig   = i + rstart;
1442399e097SLois Curfman McInnes     ierr = MatGetRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
1452399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
1462399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
14756fe5c5cSLois Curfman McInnes   }
1482399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1492399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
15056fe5c5cSLois Curfman McInnes   return 0;
1510ff6cd27SBarry Smith ---------------------------------------------------------*/
15256fe5c5cSLois Curfman McInnes }
1538b6375c0SLois Curfman McInnes /* ------------------------------------------------------------------ */
154567e79a1SLois Curfman McInnes /*
155567e79a1SLois Curfman McInnes   MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For
156567e79a1SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
157567e79a1SLois Curfman McInnes  */
158567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B)
159567e79a1SLois Curfman McInnes {
160567e79a1SLois Curfman McInnes   Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data;
1618b6375c0SLois Curfman McInnes   Scalar       *vwork, *vw2;
162567e79a1SLois Curfman McInnes   int          i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
1638b6375c0SLois Curfman McInnes   int          j, *cw2, ict;
164567e79a1SLois Curfman McInnes 
165dad23ff5SLois Curfman McInnes   /* rough over-estimate; could refine for individual rows */
1660452661fSBarry Smith   nz = PetscMin(n,a->nd*a->nb);
167567e79a1SLois Curfman McInnes   switch (newtype) {
168567e79a1SLois Curfman McInnes     case MATSEQAIJ:
169b4fd4287SBarry Smith       ierr = MatCreateSeqAIJ(A->comm,m,n,nz,PETSC_NULL,B); CHKERRQ(ierr);
170567e79a1SLois Curfman McInnes       break;
171567e79a1SLois Curfman McInnes     case MATMPIROWBS:
172567e79a1SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square");
173b4fd4287SBarry Smith       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,PETSC_NULL,PETSC_NULL,
174ed2daf61SLois Curfman McInnes              B); CHKERRQ(ierr);
175567e79a1SLois Curfman McInnes       break;
176567e79a1SLois Curfman McInnes     case MATMPIAIJ:
177567e79a1SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
178b4fd4287SBarry Smith                              m,n,0,PETSC_NULL,0,PETSC_NULL,B); CHKERRQ(ierr);
179567e79a1SLois Curfman McInnes       break;
180567e79a1SLois Curfman McInnes     case MATSEQDENSE:
181b4fd4287SBarry Smith       ierr = MatCreateSeqDense(A->comm,m,n,PETSC_NULL,B); CHKERRQ(ierr);
182567e79a1SLois Curfman McInnes       break;
183567e79a1SLois Curfman McInnes     case MATMPIDENSE:
184567e79a1SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
185b4fd4287SBarry Smith                                m,n,PETSC_NULL,B); CHKERRQ(ierr);
186567e79a1SLois Curfman McInnes       break;
187567e79a1SLois Curfman McInnes     case MATMPIBDIAG:
188567e79a1SLois Curfman McInnes       {
189ed2daf61SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,
190b4fd4287SBarry Smith              PETSC_NULL,PETSC_NULL,B); CHKERRQ(ierr);
191567e79a1SLois Curfman McInnes       break;
192567e79a1SLois Curfman McInnes       }
193567e79a1SLois Curfman McInnes     default:
194567e79a1SLois Curfman McInnes       SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported");
195567e79a1SLois Curfman McInnes   }
196567e79a1SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
1978b6375c0SLois Curfman McInnes 
1980452661fSBarry Smith   cw2 = (int *)PetscMalloc( n * sizeof(int) ); CHKPTRQ(cw2);
1990452661fSBarry Smith   vw2 = (Scalar *)PetscMalloc( n * sizeof(Scalar) ); CHKPTRQ(vw2);
200567e79a1SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
201567e79a1SLois Curfman McInnes    ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
2028b6375c0SLois Curfman McInnes    ict = 0; /* strip out the zero elements ... is this what we really want? */
2038b6375c0SLois Curfman McInnes    for (j=0; j<nz; j++) {
2048b6375c0SLois Curfman McInnes      if (vwork[j] != 0) {vw2[ict] = vwork[j]; cw2[ict] = cwork[j]; ict++;}
2058b6375c0SLois Curfman McInnes    }
206*6d84be18SBarry Smith    if (ict) {
207*6d84be18SBarry Smith      ierr = MatSetValues(*B,1,&i,ict,cw2,vw2,INSERT_VALUES); CHKERRQ(ierr);
208*6d84be18SBarry Smith    }
209567e79a1SLois Curfman McInnes    ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
210567e79a1SLois Curfman McInnes   }
2110452661fSBarry Smith   PetscFree(cw2); PetscFree(vw2);
212567e79a1SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
213567e79a1SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
214567e79a1SLois Curfman McInnes   return 0;
215567e79a1SLois Curfman McInnes }
216