xref: /petsc/src/mat/utils/getcolv.c (revision e8aa55a48f1e7a2d1b208d8f55db49fa3b2bfe2a)
1 /*$Id: getcolv.c,v 1.23 2001/08/08 15:47:19 bsmith Exp $*/
2 
3 #include "src/mat/matimpl.h"  /*I   "petscmat.h"  I*/
4 
5 #undef __FUNCT__
6 #define __FUNCT__ "MatGetColumnVector"
7 /*@
8    MatGetColumnVector - Gets the values from a given column of a matrix.
9 
10    Not Collective
11 
12    Input Parameters:
13 +  A - the matrix
14 .  yy - the vector
15 -  c - the column requested (in global numbering)
16 
17    Level: advanced
18 
19    Notes:
20    Each processor for which this is called gets the values for its rows.
21 
22    Since PETSc matrices are usually stored in compressed row format, this routine
23    will generally be slow.
24 
25    The vector must have the same parallel row layout as the matrix.
26 
27    Contributed by: Denis Vanderstraeten
28 
29 .keywords: matrix, column, get
30 
31 .seealso: MatGetRow(), MatGetDiagonal()
32 
33 @*/
34 int MatGetColumnVector(Mat A,Vec yy,int col)
35 {
36   PetscScalar   *y,*v,zero = 0.0;
37   int      ierr,i,j,nz,*idx,N,Rs,Re,rs,re;
38   MPI_Comm comm;
39 
40   PetscFunctionBegin;
41   PetscValidHeaderSpecific(A,MAT_COOKIE);
42   PetscValidHeaderSpecific(yy,VEC_COOKIE);
43 
44   if (col < 0)  SETERRQ1(1,"Requested negative column: %d",col);
45   ierr = MatGetSize(A,PETSC_NULL,&N);CHKERRQ(ierr);
46   if (col >= N)  SETERRQ2(1,"Requested column %d larger than number columns in matrix %d",col,N);
47 
48   ierr = MatGetOwnershipRange(A,&Rs,&Re);CHKERRQ(ierr);
49 
50   ierr = PetscObjectGetComm((PetscObject)yy,&comm);CHKERRQ(ierr);
51   ierr = VecGetOwnershipRange(yy,&rs,&re);CHKERRQ(ierr);
52   if (Rs != rs || Re != re) SETERRQ4(1,"Matrix %d %d does not have same ownership range (size) as vector %d %d",Rs,Re,rs,re);
53 
54   ierr = VecSet(&zero,yy);CHKERRQ(ierr);
55   ierr = VecGetArray(yy,&y);CHKERRQ(ierr);
56 
57   for (i=Rs; i<Re; i++) {
58     ierr = MatGetRow(A,i,&nz,&idx,&v);CHKERRQ(ierr);
59     if (nz && idx[0] <= col) {
60       /*
61           Should use faster search here
62       */
63       for (j=0; j<nz; j++) {
64         if (idx[j] >= col) {
65           if (idx[j] == col) y[i-rs] = v[j];
66           break;
67         }
68       }
69     }
70     ierr = MatRestoreRow(A,i,&nz,&idx,&v);CHKERRQ(ierr);
71   }
72 
73   ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr);
74   PetscFunctionReturn(0);
75 }
76