xref: /petsc/src/mat/utils/convert.c (revision dad23ff5a4f5c52bc6bb9bd0a07d18e754452cee)
156fe5c5cSLois Curfman McInnes #ifndef lint
2*dad23ff5SLois Curfman McInnes static char vcid[] = "$Id: convert.c,v 1.31 1995/10/27 01:11:01 curfman Exp curfman $";
356fe5c5cSLois Curfman McInnes #endif
456fe5c5cSLois Curfman McInnes 
52399e097SLois Curfman McInnes /* This file contains implementation-specific matrix conversion routines.
62399e097SLois Curfman McInnes    For now, this has been implemented only for AIJ.  See MatConvert() for
72399e097SLois Curfman McInnes    generic conversion code. */
856fe5c5cSLois Curfman McInnes 
956fe5c5cSLois Curfman McInnes #include "mpiaij.h"
1056fe5c5cSLois Curfman McInnes 
1156fe5c5cSLois Curfman McInnes /*
12ec8511deSBarry Smith   MatConvert_SeqAIJ - Converts from MATSEQAIJ format to another format. For
1344ae05bdSLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
1456fe5c5cSLois Curfman McInnes  */
152399e097SLois Curfman McInnes int MatConvert_SeqAIJ(Mat A, MatType newtype, Mat *B)
1656fe5c5cSLois Curfman McInnes {
172399e097SLois Curfman McInnes   Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data;
1856fe5c5cSLois Curfman McInnes   Scalar     *vwork;
192399e097SLois Curfman McInnes   int        i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
2056fe5c5cSLois Curfman McInnes 
2156fe5c5cSLois Curfman McInnes   switch (newtype) {
22ec8511deSBarry Smith     case MATSEQROW:
232399e097SLois Curfman McInnes       ierr = MatCreateSeqRow(A->comm,m,n,0,a->ilen,B); CHKERRQ(ierr);
24416022c9SBarry Smith       break;
2544ae05bdSLois Curfman McInnes     case MATMPIROW:
2644ae05bdSLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
272399e097SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
28416022c9SBarry Smith       break;
29ec8511deSBarry Smith     case MATMPIROWBS:
302399e097SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqAIJ:MATMPIROWBS matrix must be square");
312399e097SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr);
32416022c9SBarry Smith       break;
3344ae05bdSLois Curfman McInnes     case MATMPIAIJ:
3444ae05bdSLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
352399e097SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
36416022c9SBarry Smith       break;
37ec8511deSBarry Smith     case MATSEQDENSE:
382399e097SLois Curfman McInnes       ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr);
392399e097SLois Curfman McInnes       break;
402399e097SLois Curfman McInnes     case MATMPIDENSE:
412399e097SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
422399e097SLois Curfman McInnes                                m,n,B); CHKERRQ(ierr);
43416022c9SBarry Smith       break;
44ec8511deSBarry Smith     case MATSEQBDIAG:
45416022c9SBarry Smith       {
4658154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
47df60cc22SBarry Smith       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
482399e097SLois Curfman McInnes       ierr = MatCreateSeqBDiag(A->comm,m,n,0,nb,0,0,B); CHKERRQ(ierr);
4944ae05bdSLois Curfman McInnes       break;
5044ae05bdSLois Curfman McInnes       }
5144ae05bdSLois Curfman McInnes     case MATMPIBDIAG:
52416022c9SBarry Smith       {
5358154824SLois Curfman McInnes       int nb = 1; /* Default block size = 1 */
5444ae05bdSLois Curfman McInnes       OptionsGetInt(0,"-mat_bdiag_bsize",&nb);
552399e097SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,0,nb,0,0,B);
5678b31e54SBarry Smith       CHKERRQ(ierr);
57416022c9SBarry Smith       break;
5856fe5c5cSLois Curfman McInnes       }
59f3ba505bSLois Curfman McInnes     default:
60ec8511deSBarry Smith       SETERRQ(1,"MatConvert_SeqAIJ:Matrix type is not currently supported");
61f3ba505bSLois Curfman McInnes   }
622399e097SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
6344ae05bdSLois Curfman McInnes   for (i=rstart; i<rend; i++) {
642399e097SLois Curfman McInnes     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
652399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
662399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
6756fe5c5cSLois Curfman McInnes   }
682399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
692399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
7056fe5c5cSLois Curfman McInnes   return 0;
7156fe5c5cSLois Curfman McInnes }
7256fe5c5cSLois Curfman McInnes /* ------------------------------------------------------------------ */
7356fe5c5cSLois Curfman McInnes /*
741fb19edaSLois Curfman McInnes   MatConvert_MPIAIJ - Converts from MATMPIAIJ format to another
7556fe5c5cSLois Curfman McInnes   parallel format.
7656fe5c5cSLois Curfman McInnes  */
772399e097SLois Curfman McInnes int MatConvert_MPIAIJ(Mat A, MatType newtype, Mat *B)
7856fe5c5cSLois Curfman McInnes {
792399e097SLois Curfman McInnes   Mat_MPIAIJ *a = (Mat_MPIAIJ *) A->data;
802399e097SLois Curfman McInnes   Mat_SeqAIJ *Ad = (Mat_SeqAIJ *)(a->A->data), *Bd = (Mat_SeqAIJ *)(a->B->data);
812399e097SLois Curfman McInnes   int        ierr, nz, i, ig, rstart = a->rstart, m = a->m, *cwork;
8256fe5c5cSLois Curfman McInnes   Scalar     *vwork;
8356fe5c5cSLois Curfman McInnes 
8456fe5c5cSLois Curfman McInnes   switch (newtype) {
851fb19edaSLois Curfman McInnes     case MATMPIROW:
862399e097SLois Curfman McInnes       ierr = MatCreateMPIRow(A->comm,m,a->n,a->M,a->N,0,Ad->ilen,
872399e097SLois Curfman McInnes 			0,Bd->ilen,B); CHKERRQ(ierr);
88abc0e9e4SLois Curfman McInnes       break;
8956fe5c5cSLois Curfman McInnes     default:
90bbb6d6a8SBarry Smith       SETERRQ(1,"MatConvert_MPIAIJ:Only MATMPIROW is currently suported");
9156fe5c5cSLois Curfman McInnes   }
92abc0e9e4SLois Curfman McInnes   /* Each processor converts its local rows */
9356fe5c5cSLois Curfman McInnes   for (i=0; i<m; i++) {
9456fe5c5cSLois Curfman McInnes     ig   = i + rstart;
952399e097SLois Curfman McInnes     ierr = MatGetRow(A,ig,&nz,&cwork,&vwork);	CHKERRQ(ierr);
962399e097SLois Curfman McInnes     ierr = MatSetValues(*B,1,&ig,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
972399e097SLois Curfman McInnes     ierr = MatRestoreRow(A,ig,&nz,&cwork,&vwork); CHKERRQ(ierr);
9856fe5c5cSLois Curfman McInnes   }
992399e097SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
1002399e097SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
10156fe5c5cSLois Curfman McInnes   return 0;
10256fe5c5cSLois Curfman McInnes }
103ec8511deSBarry Smith 
104567e79a1SLois Curfman McInnes #include "mpibdiag.h"
105ec8511deSBarry Smith 
106567e79a1SLois Curfman McInnes /*
107567e79a1SLois Curfman McInnes   MatConvert_SeqBDiag - Converts from MATSEQBDiag format to another format. For
108567e79a1SLois Curfman McInnes   parallel formats, the new matrix distribution is determined by PETSc.
109567e79a1SLois Curfman McInnes  */
110567e79a1SLois Curfman McInnes int MatConvert_SeqBDiag(Mat A, MatType newtype, Mat *B)
111567e79a1SLois Curfman McInnes {
112567e79a1SLois Curfman McInnes   Mat_SeqBDiag *a = (Mat_SeqBDiag *) A->data;
113567e79a1SLois Curfman McInnes   Scalar       *vwork;
114567e79a1SLois Curfman McInnes   int          i, ierr, nz, m = a->m, n = a->n, *cwork, rstart, rend;
115567e79a1SLois Curfman McInnes 
116*dad23ff5SLois Curfman McInnes   /* rough over-estimate; could refine for individual rows */
117*dad23ff5SLois Curfman McInnes   nz = PETSCMIN(n,a->nd*a->nb);
118567e79a1SLois Curfman McInnes   switch (newtype) {
119567e79a1SLois Curfman McInnes     case MATSEQAIJ:
120567e79a1SLois Curfman McInnes       ierr = MatCreateSeqAIJ(A->comm,m,n,nz,0,B); CHKERRQ(ierr);
121567e79a1SLois Curfman McInnes       break;
122567e79a1SLois Curfman McInnes     case MATSEQROW:
123567e79a1SLois Curfman McInnes       ierr = MatCreateSeqRow(A->comm,m,n,nz,0,B); CHKERRQ(ierr);
124567e79a1SLois Curfman McInnes       break;
125567e79a1SLois Curfman McInnes     case MATMPIROW:
126567e79a1SLois Curfman McInnes       ierr = MatCreateMPIRow(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
127567e79a1SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
128567e79a1SLois Curfman McInnes       break;
129567e79a1SLois Curfman McInnes     case MATMPIROWBS:
130567e79a1SLois Curfman McInnes       if (m != n) SETERRQ(1,"MatConvert_SeqBDiag:MATMPIROWBS matrix must be square");
131567e79a1SLois Curfman McInnes       ierr = MatCreateMPIRowbs(MPI_COMM_WORLD,PETSC_DECIDE,m,0,0,0,B); CHKERRQ(ierr);
132567e79a1SLois Curfman McInnes       break;
133567e79a1SLois Curfman McInnes     case MATMPIAIJ:
134567e79a1SLois Curfman McInnes       ierr = MatCreateMPIAIJ(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
135567e79a1SLois Curfman McInnes                              m,n,0,0,0,0,B); CHKERRQ(ierr);
136567e79a1SLois Curfman McInnes       break;
137567e79a1SLois Curfman McInnes     case MATSEQDENSE:
138567e79a1SLois Curfman McInnes       ierr = MatCreateSeqDense(A->comm,m,n,B); CHKERRQ(ierr);
139567e79a1SLois Curfman McInnes       break;
140567e79a1SLois Curfman McInnes     case MATMPIDENSE:
141567e79a1SLois Curfman McInnes       ierr = MatCreateMPIDense(MPI_COMM_WORLD,PETSC_DECIDE,PETSC_DECIDE,
142567e79a1SLois Curfman McInnes                                m,n,B); CHKERRQ(ierr);
143567e79a1SLois Curfman McInnes       break;
144567e79a1SLois Curfman McInnes     case MATMPIBDIAG:
145567e79a1SLois Curfman McInnes       {
146567e79a1SLois Curfman McInnes       ierr = MatCreateMPIBDiag(MPI_COMM_WORLD,PETSC_DECIDE,m,n,a->nd,a->nb,0,0,B);
147567e79a1SLois Curfman McInnes       CHKERRQ(ierr);
148567e79a1SLois Curfman McInnes       break;
149567e79a1SLois Curfman McInnes       }
150567e79a1SLois Curfman McInnes     default:
151567e79a1SLois Curfman McInnes       SETERRQ(1,"MatConvert_SeqBDiag:Matrix type is not currently supported");
152567e79a1SLois Curfman McInnes   }
153567e79a1SLois Curfman McInnes   ierr = MatGetOwnershipRange(*B,&rstart,&rend); CHKERRQ(ierr);
154567e79a1SLois Curfman McInnes   for (i=rstart; i<rend; i++) {
155567e79a1SLois Curfman McInnes     ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
156567e79a1SLois Curfman McInnes     ierr = MatSetValues(*B,1,&i,nz,cwork,vwork,INSERT_VALUES); CHKERRQ(ierr);
157567e79a1SLois Curfman McInnes     ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr);
158567e79a1SLois Curfman McInnes   }
159567e79a1SLois Curfman McInnes   ierr = MatAssemblyBegin(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
160567e79a1SLois Curfman McInnes   ierr = MatAssemblyEnd(*B,FINAL_ASSEMBLY); CHKERRQ(ierr);
161567e79a1SLois Curfman McInnes   return 0;
162567e79a1SLois Curfman McInnes }
163