1*17ab2063SBarry Smith #ifndef lint 2*17ab2063SBarry Smith static char vcid[] = "$Id: aij.c,v 1.90 1995/09/21 20:10:56 bsmith Exp bsmith $"; 3*17ab2063SBarry Smith #endif 4*17ab2063SBarry Smith 5*17ab2063SBarry Smith #include "aij.h" 6*17ab2063SBarry Smith #include "vec/vecimpl.h" 7*17ab2063SBarry Smith #include "inline/spops.h" 8*17ab2063SBarry Smith 9*17ab2063SBarry Smith extern int MatToSymmetricIJ_SeqAIJ(Mat_SeqAIJ*,int**,int**); 10*17ab2063SBarry Smith 11*17ab2063SBarry Smith static int MatGetReordering_SeqAIJ(Mat mat,MatOrdering type,IS *rperm, IS *cperm) 12*17ab2063SBarry Smith { 13*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) mat->data; 14*17ab2063SBarry Smith int ierr, *ia, *ja; 15*17ab2063SBarry Smith 16*17ab2063SBarry Smith if (!aij->assembled) 17*17ab2063SBarry Smith SETERRQ(1,"MatGetReordering_SeqAIJ:Cannot reorder unassembled matrix"); 18*17ab2063SBarry Smith 19*17ab2063SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ( aij, &ia, &ja ); CHKERRQ(ierr); 20*17ab2063SBarry Smith ierr = MatGetReordering_IJ(aij->n,ia,ja,type,rperm,cperm); CHKERRQ(ierr); 21*17ab2063SBarry Smith PETSCFREE(ia); PETSCFREE(ja); 22*17ab2063SBarry Smith return 0; 23*17ab2063SBarry Smith } 24*17ab2063SBarry Smith 25*17ab2063SBarry Smith #define CHUNCKSIZE 10 26*17ab2063SBarry Smith 27*17ab2063SBarry Smith /* This version has row oriented v */ 28*17ab2063SBarry Smith static int MatSetValues_SeqAIJ(Mat matin,int m,int *idxm,int n, 29*17ab2063SBarry Smith int *idxn,Scalar *v,InsertMode addv) 30*17ab2063SBarry Smith { 31*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 32*17ab2063SBarry Smith int *rp,k,a,b,t,ii,row,nrow,i,col,l,rmax, N, sorted = mat->sorted; 33*17ab2063SBarry Smith int *imax = mat->imax, *ai = mat->i, *ailen = mat->ilen; 34*17ab2063SBarry Smith int *aj = mat->j, nonew = mat->nonew; 35*17ab2063SBarry Smith Scalar *ap,value, *aa = mat->a; 36*17ab2063SBarry Smith int shift = mat->indexshift; 37*17ab2063SBarry Smith 38*17ab2063SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 39*17ab2063SBarry Smith row = idxm[k]; 40*17ab2063SBarry Smith if (row < 0) SETERRQ(1,"MatSetValues_SeqAIJ:Negative row"); 41*17ab2063SBarry Smith if (row >= mat->m) SETERRQ(1,"MatSetValues_SeqAIJ:Row too large"); 42*17ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 43*17ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 44*17ab2063SBarry Smith a = 0; 45*17ab2063SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 46*17ab2063SBarry Smith if (idxn[l] < 0) SETERRQ(1,"MatSetValues_SeqAIJ:Negative column"); 47*17ab2063SBarry Smith if (idxn[l] >= mat->n) 48*17ab2063SBarry Smith SETERRQ(1,"MatSetValues_SeqAIJ:Column too large"); 49*17ab2063SBarry Smith col = idxn[l] - shift; value = *v++; 50*17ab2063SBarry Smith if (!sorted) a = 0; b = nrow; 51*17ab2063SBarry Smith while (b-a > 5) { 52*17ab2063SBarry Smith t = (b+a)/2; 53*17ab2063SBarry Smith if (rp[t] > col) b = t; 54*17ab2063SBarry Smith else a = t; 55*17ab2063SBarry Smith } 56*17ab2063SBarry Smith for ( i=a; i<b; i++ ) { 57*17ab2063SBarry Smith if (rp[i] > col) break; 58*17ab2063SBarry Smith if (rp[i] == col) { 59*17ab2063SBarry Smith if (addv == ADD_VALUES) ap[i] += value; 60*17ab2063SBarry Smith else ap[i] = value; 61*17ab2063SBarry Smith goto noinsert; 62*17ab2063SBarry Smith } 63*17ab2063SBarry Smith } 64*17ab2063SBarry Smith if (nonew) goto noinsert; 65*17ab2063SBarry Smith if (nrow >= rmax) { 66*17ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 67*17ab2063SBarry Smith int new_nz = ai[mat->m] + CHUNCKSIZE,len,*new_i,*new_j; 68*17ab2063SBarry Smith Scalar *new_a; 69*17ab2063SBarry Smith 70*17ab2063SBarry Smith /* malloc new storage space */ 71*17ab2063SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(mat->m+1)*sizeof(int); 72*17ab2063SBarry Smith new_a = (Scalar *) PETSCMALLOC( len ); CHKPTRQ(new_a); 73*17ab2063SBarry Smith new_j = (int *) (new_a + new_nz); 74*17ab2063SBarry Smith new_i = new_j + new_nz; 75*17ab2063SBarry Smith 76*17ab2063SBarry Smith /* copy over old data into new slots */ 77*17ab2063SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 78*17ab2063SBarry Smith for ( ii=row+1; ii<mat->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNCKSIZE;} 79*17ab2063SBarry Smith PETSCMEMCPY(new_j,aj,(ai[row]+nrow+shift)*sizeof(int)); 80*17ab2063SBarry Smith len = (new_nz - CHUNCKSIZE - ai[row] - nrow - shift); 81*17ab2063SBarry Smith PETSCMEMCPY(new_j+ai[row]+shift+nrow+CHUNCKSIZE,aj+ai[row]+shift+nrow, 82*17ab2063SBarry Smith len*sizeof(int)); 83*17ab2063SBarry Smith PETSCMEMCPY(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar)); 84*17ab2063SBarry Smith PETSCMEMCPY(new_a+ai[row]+shift+nrow+CHUNCKSIZE,aa+ai[row]+shift+nrow, 85*17ab2063SBarry Smith len*sizeof(Scalar)); 86*17ab2063SBarry Smith /* free up old matrix storage */ 87*17ab2063SBarry Smith PETSCFREE(mat->a); if (!mat->singlemalloc) {PETSCFREE(mat->i);PETSCFREE(mat->j);} 88*17ab2063SBarry Smith aa = mat->a = new_a; ai = mat->i = new_i; aj = mat->j = new_j; 89*17ab2063SBarry Smith mat->singlemalloc = 1; 90*17ab2063SBarry Smith 91*17ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 92*17ab2063SBarry Smith rmax = imax[row] = imax[row] + CHUNCKSIZE; 93*17ab2063SBarry Smith PLogObjectMemory(matin,CHUNCKSIZE*(sizeof(int) + sizeof(Scalar))); 94*17ab2063SBarry Smith mat->maxnz += CHUNCKSIZE; 95*17ab2063SBarry Smith } 96*17ab2063SBarry Smith N = nrow++ - 1; mat->nz++; 97*17ab2063SBarry Smith /* this has too many shifts here; but alternative was slower*/ 98*17ab2063SBarry Smith for ( ii=N; ii>=i; ii-- ) {/* shift values up*/ 99*17ab2063SBarry Smith rp[ii+1] = rp[ii]; 100*17ab2063SBarry Smith ap[ii+1] = ap[ii]; 101*17ab2063SBarry Smith } 102*17ab2063SBarry Smith rp[i] = col; 103*17ab2063SBarry Smith ap[i] = value; 104*17ab2063SBarry Smith noinsert:; 105*17ab2063SBarry Smith a = i + 1; 106*17ab2063SBarry Smith } 107*17ab2063SBarry Smith ailen[row] = nrow; 108*17ab2063SBarry Smith } 109*17ab2063SBarry Smith return 0; 110*17ab2063SBarry Smith } 111*17ab2063SBarry Smith 112*17ab2063SBarry Smith #include "draw.h" 113*17ab2063SBarry Smith #include "pinclude/pviewer.h" 114*17ab2063SBarry Smith 115*17ab2063SBarry Smith static int MatView_SeqAIJ(PetscObject obj,Viewer ptr) 116*17ab2063SBarry Smith { 117*17ab2063SBarry Smith Mat aijin = (Mat) obj; 118*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 119*17ab2063SBarry Smith int ierr, i,j, m = aij->m; 120*17ab2063SBarry Smith PetscObject vobj = (PetscObject) ptr; 121*17ab2063SBarry Smith double xl,yl,xr,yr,w,h; 122*17ab2063SBarry Smith int shift = aij->indexshift; 123*17ab2063SBarry Smith 124*17ab2063SBarry Smith if (!aij->assembled) 125*17ab2063SBarry Smith SETERRQ(1,"MatView_SeqAIJ:Cannot view unassembled matrix"); 126*17ab2063SBarry Smith if (!ptr) { /* so that viewers may be used from debuggers */ 127*17ab2063SBarry Smith ptr = STDOUT_VIEWER_SELF; vobj = (PetscObject) ptr; 128*17ab2063SBarry Smith } 129*17ab2063SBarry Smith if (vobj->cookie == DRAW_COOKIE && vobj->type == NULLWINDOW) return 0; 130*17ab2063SBarry Smith if (vobj && vobj->cookie == VIEWER_COOKIE && vobj->type == MATLAB_VIEWER) { 131*17ab2063SBarry Smith return ViewerMatlabPutSparse_Private(ptr,aij->m,aij->n,aij->nz,aij->a, 132*17ab2063SBarry Smith aij->i,aij->j); 133*17ab2063SBarry Smith } 134*17ab2063SBarry Smith if (vobj && vobj->cookie == DRAW_COOKIE) { 135*17ab2063SBarry Smith DrawCtx draw = (DrawCtx) ptr; 136*17ab2063SBarry Smith xr = aij->n; yr = aij->m; h = yr/10.0; w = xr/10.0; 137*17ab2063SBarry Smith xr += w; yr += h; xl = -w; yl = -h; 138*17ab2063SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 139*17ab2063SBarry Smith /* loop over matrix elements drawing boxes */ 140*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 141*17ab2063SBarry Smith yl = m - i - 1.0; yr = yl + 1.0; 142*17ab2063SBarry Smith for ( j=aij->i[i]+shift; j<aij->i[i+1]+shift; j++ ) { 143*17ab2063SBarry Smith xl = aij->j[j] + shift; xr = xl + 1.0; 144*17ab2063SBarry Smith DrawRectangle(draw,xl,yl,xr,yr,DRAW_BLACK,DRAW_BLACK,DRAW_BLACK, 145*17ab2063SBarry Smith DRAW_BLACK); 146*17ab2063SBarry Smith } 147*17ab2063SBarry Smith } 148*17ab2063SBarry Smith DrawFlush(draw); 149*17ab2063SBarry Smith return 0; 150*17ab2063SBarry Smith } 151*17ab2063SBarry Smith else { 152*17ab2063SBarry Smith FILE *fd; 153*17ab2063SBarry Smith char *outputname; 154*17ab2063SBarry Smith int format; 155*17ab2063SBarry Smith 156*17ab2063SBarry Smith ierr = ViewerFileGetPointer_Private(ptr,&fd); CHKERRQ(ierr); 157*17ab2063SBarry Smith ierr = ViewerFileGetOutputname_Private(ptr,&outputname); CHKERRQ(ierr); 158*17ab2063SBarry Smith ierr = ViewerFileGetFormat_Private(ptr,&format); 159*17ab2063SBarry Smith if (format == FILE_FORMAT_INFO) { 160*17ab2063SBarry Smith /* do nothing for now */ 161*17ab2063SBarry Smith } 162*17ab2063SBarry Smith else if (format == FILE_FORMAT_MATLAB) { 163*17ab2063SBarry Smith int nz, nzalloc, mem; 164*17ab2063SBarry Smith MatGetInfo(aijin,MAT_LOCAL,&nz,&nzalloc,&mem); 165*17ab2063SBarry Smith fprintf(fd,"%% Size = %d %d \n",m,aij->n); 166*17ab2063SBarry Smith fprintf(fd,"%% Nonzeros = %d \n",nz); 167*17ab2063SBarry Smith fprintf(fd,"zzz = zeros(%d,3);\n",nz); 168*17ab2063SBarry Smith fprintf(fd,"zzz = [\n"); 169*17ab2063SBarry Smith 170*17ab2063SBarry Smith for (i=0; i<m; i++) { 171*17ab2063SBarry Smith for ( j=aij->i[i]+shift; j<aij->i[i+1]+shift; j++ ) { 172*17ab2063SBarry Smith #if defined(PETSC_COMPLEX) 173*17ab2063SBarry Smith fprintf(fd,"%d %d %18.16e %18.16e \n", 174*17ab2063SBarry Smith i+1,aij->j[j],real(aij->a[j]),imag(aij->a[j])); 175*17ab2063SBarry Smith #else 176*17ab2063SBarry Smith fprintf(fd,"%d %d %18.16e\n", i+1, aij->j[j], aij->a[j]); 177*17ab2063SBarry Smith #endif 178*17ab2063SBarry Smith } 179*17ab2063SBarry Smith } 180*17ab2063SBarry Smith fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname); 181*17ab2063SBarry Smith } 182*17ab2063SBarry Smith else { 183*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 184*17ab2063SBarry Smith fprintf(fd,"row %d:",i); 185*17ab2063SBarry Smith for ( j=aij->i[i]+shift; j<aij->i[i+1]+shift; j++ ) { 186*17ab2063SBarry Smith #if defined(PETSC_COMPLEX) 187*17ab2063SBarry Smith if (imag(aij->a[j]) != 0.0) { 188*17ab2063SBarry Smith fprintf(fd," %d %g + %g i", 189*17ab2063SBarry Smith aij->j[j]+shift,real(aij->a[j]),imag(aij->a[j])); 190*17ab2063SBarry Smith } 191*17ab2063SBarry Smith else { 192*17ab2063SBarry Smith fprintf(fd," %d %g ",aij->j[j]+shift,real(aij->a[j])); 193*17ab2063SBarry Smith } 194*17ab2063SBarry Smith #else 195*17ab2063SBarry Smith fprintf(fd," %d %g ",aij->j[j]+shift,aij->a[j]); 196*17ab2063SBarry Smith #endif 197*17ab2063SBarry Smith } 198*17ab2063SBarry Smith fprintf(fd,"\n"); 199*17ab2063SBarry Smith } 200*17ab2063SBarry Smith } 201*17ab2063SBarry Smith fflush(fd); 202*17ab2063SBarry Smith } 203*17ab2063SBarry Smith return 0; 204*17ab2063SBarry Smith } 205*17ab2063SBarry Smith 206*17ab2063SBarry Smith static int MatAssemblyEnd_SeqAIJ(Mat aijin,MatAssemblyType mode) 207*17ab2063SBarry Smith { 208*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 209*17ab2063SBarry Smith int fshift = 0,i,j,*ai = aij->i, *aj = aij->j, *imax = aij->imax; 210*17ab2063SBarry Smith int m = aij->m, *ip, N, *ailen = aij->ilen; 211*17ab2063SBarry Smith Scalar *a = aij->a, *ap; 212*17ab2063SBarry Smith int shift = aij->indexshift; 213*17ab2063SBarry Smith 214*17ab2063SBarry Smith if (mode == FLUSH_ASSEMBLY) return 0; 215*17ab2063SBarry Smith 216*17ab2063SBarry Smith for ( i=1; i<m; i++ ) { 217*17ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 218*17ab2063SBarry Smith if (fshift) { 219*17ab2063SBarry Smith ip = aj + ai[i] + shift; ap = a + ai[i] + shift; 220*17ab2063SBarry Smith N = ailen[i]; 221*17ab2063SBarry Smith for ( j=0; j<N; j++ ) { 222*17ab2063SBarry Smith ip[j-fshift] = ip[j]; 223*17ab2063SBarry Smith ap[j-fshift] = ap[j]; 224*17ab2063SBarry Smith } 225*17ab2063SBarry Smith } 226*17ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 227*17ab2063SBarry Smith } 228*17ab2063SBarry Smith if (m) { 229*17ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 230*17ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 231*17ab2063SBarry Smith } 232*17ab2063SBarry Smith /* reset ilen and imax for each row */ 233*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 234*17ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 235*17ab2063SBarry Smith } 236*17ab2063SBarry Smith aij->nz = ai[m] + shift; 237*17ab2063SBarry Smith 238*17ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 239*17ab2063SBarry Smith if (fshift && aij->diag) { 240*17ab2063SBarry Smith PETSCFREE(aij->diag); 241*17ab2063SBarry Smith PLogObjectMemory(aijin,-(m+1)*sizeof(int)); 242*17ab2063SBarry Smith aij->diag = 0; 243*17ab2063SBarry Smith } 244*17ab2063SBarry Smith aij->assembled = 1; 245*17ab2063SBarry Smith return 0; 246*17ab2063SBarry Smith } 247*17ab2063SBarry Smith 248*17ab2063SBarry Smith static int MatZeroEntries_SeqAIJ(Mat mat) 249*17ab2063SBarry Smith { 250*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) mat->data; 251*17ab2063SBarry Smith int shift = aij->indexshift; 252*17ab2063SBarry Smith Scalar *a = aij->a; 253*17ab2063SBarry Smith int i,n = aij->i[aij->m]+shift; 254*17ab2063SBarry Smith 255*17ab2063SBarry Smith for ( i=0; i<n; i++ ) a[i] = 0.0; 256*17ab2063SBarry Smith return 0; 257*17ab2063SBarry Smith 258*17ab2063SBarry Smith } 259*17ab2063SBarry Smith int MatDestroy_SeqAIJ(PetscObject obj) 260*17ab2063SBarry Smith { 261*17ab2063SBarry Smith Mat mat = (Mat) obj; 262*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) mat->data; 263*17ab2063SBarry Smith #if defined(PETSC_LOG) 264*17ab2063SBarry Smith PLogObjectState(obj,"Rows=%d, Cols=%d, NZ=%d",aij->m,aij->n,aij->nz); 265*17ab2063SBarry Smith #endif 266*17ab2063SBarry Smith PETSCFREE(aij->a); 267*17ab2063SBarry Smith if (!aij->singlemalloc) { PETSCFREE(aij->i); PETSCFREE(aij->j);} 268*17ab2063SBarry Smith if (aij->diag) PETSCFREE(aij->diag); 269*17ab2063SBarry Smith if (aij->ilen) PETSCFREE(aij->ilen); 270*17ab2063SBarry Smith if (aij->imax) PETSCFREE(aij->imax); 271*17ab2063SBarry Smith if (aij->solve_work) PETSCFREE(aij->solve_work); 272*17ab2063SBarry Smith PETSCFREE(aij); 273*17ab2063SBarry Smith PLogObjectDestroy(mat); 274*17ab2063SBarry Smith PETSCHEADERDESTROY(mat); 275*17ab2063SBarry Smith return 0; 276*17ab2063SBarry Smith } 277*17ab2063SBarry Smith 278*17ab2063SBarry Smith static int MatCompress_SeqAIJ(Mat aijin) 279*17ab2063SBarry Smith { 280*17ab2063SBarry Smith return 0; 281*17ab2063SBarry Smith } 282*17ab2063SBarry Smith 283*17ab2063SBarry Smith static int MatSetOption_SeqAIJ(Mat aijin,MatOption op) 284*17ab2063SBarry Smith { 285*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 286*17ab2063SBarry Smith if (op == ROW_ORIENTED) aij->roworiented = 1; 287*17ab2063SBarry Smith else if (op == COLUMN_ORIENTED) aij->roworiented = 0; 288*17ab2063SBarry Smith else if (op == COLUMNS_SORTED) aij->sorted = 1; 289*17ab2063SBarry Smith /* doesn't care about sorted rows */ 290*17ab2063SBarry Smith else if (op == NO_NEW_NONZERO_LOCATIONS) aij->nonew = 1; 291*17ab2063SBarry Smith else if (op == YES_NEW_NONZERO_LOCATIONS) aij->nonew = 0; 292*17ab2063SBarry Smith 293*17ab2063SBarry Smith if (op == COLUMN_ORIENTED) 294*17ab2063SBarry Smith SETERRQ(1,"MatSetOption_SeqAIJ:Column oriented input not supported"); 295*17ab2063SBarry Smith return 0; 296*17ab2063SBarry Smith } 297*17ab2063SBarry Smith 298*17ab2063SBarry Smith static int MatGetDiagonal_SeqAIJ(Mat aijin,Vec v) 299*17ab2063SBarry Smith { 300*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 301*17ab2063SBarry Smith int i,j, n; 302*17ab2063SBarry Smith Scalar *x, zero = 0.0; 303*17ab2063SBarry Smith int shift = aij->indexshift; 304*17ab2063SBarry Smith 305*17ab2063SBarry Smith if (!aij->assembled) SETERRQ(1, 306*17ab2063SBarry Smith "MatGetDiagonal_SeqAIJ:Cannot get diagonal of unassembled matrix"); 307*17ab2063SBarry Smith VecSet(&zero,v); 308*17ab2063SBarry Smith VecGetArray(v,&x); VecGetLocalSize(v,&n); 309*17ab2063SBarry Smith if (n != aij->m) 310*17ab2063SBarry Smith SETERRQ(1,"MatGetDiagonal_SeqAIJ:Nonconforming matrix and vector"); 311*17ab2063SBarry Smith for ( i=0; i<aij->m; i++ ) { 312*17ab2063SBarry Smith for ( j=aij->i[i]+shift; j<aij->i[i+1]+shift; j++ ) { 313*17ab2063SBarry Smith if (aij->j[j]+shift == i) { 314*17ab2063SBarry Smith x[i] = aij->a[j]; 315*17ab2063SBarry Smith break; 316*17ab2063SBarry Smith } 317*17ab2063SBarry Smith } 318*17ab2063SBarry Smith } 319*17ab2063SBarry Smith return 0; 320*17ab2063SBarry Smith } 321*17ab2063SBarry Smith 322*17ab2063SBarry Smith /* -------------------------------------------------------*/ 323*17ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 324*17ab2063SBarry Smith /* -------------------------------------------------------*/ 325*17ab2063SBarry Smith static int MatMultTrans_SeqAIJ(Mat aijin,Vec xx,Vec yy) 326*17ab2063SBarry Smith { 327*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 328*17ab2063SBarry Smith Scalar *x, *y, *v, alpha; 329*17ab2063SBarry Smith int m = aij->m, n, i, *idx; 330*17ab2063SBarry Smith int shift = aij->indexshift; 331*17ab2063SBarry Smith 332*17ab2063SBarry Smith if (!aij->assembled) 333*17ab2063SBarry Smith SETERRQ(1,"MatMultTrans_SeqAIJ:Cannot multiply unassembled matrix"); 334*17ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 335*17ab2063SBarry Smith PETSCMEMSET(y,0,aij->n*sizeof(Scalar)); 336*17ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 337*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 338*17ab2063SBarry Smith idx = aij->j + aij->i[i] + shift; 339*17ab2063SBarry Smith v = aij->a + aij->i[i] + shift; 340*17ab2063SBarry Smith n = aij->i[i+1] - aij->i[i]; 341*17ab2063SBarry Smith alpha = x[i]; 342*17ab2063SBarry Smith /* should inline */ 343*17ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 344*17ab2063SBarry Smith } 345*17ab2063SBarry Smith PLogFlops(2*aij->nz - aij->n); 346*17ab2063SBarry Smith return 0; 347*17ab2063SBarry Smith } 348*17ab2063SBarry Smith static int MatMultTransAdd_SeqAIJ(Mat aijin,Vec xx,Vec zz,Vec yy) 349*17ab2063SBarry Smith { 350*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 351*17ab2063SBarry Smith Scalar *x, *y, *v, alpha; 352*17ab2063SBarry Smith int m = aij->m, n, i, *idx; 353*17ab2063SBarry Smith int shift = aij->indexshift; 354*17ab2063SBarry Smith 355*17ab2063SBarry Smith if (!aij->assembled) 356*17ab2063SBarry Smith SETERRQ(1,"MatMultTransAdd_SeqAIJ:Cannot multiply unassembled matrix"); 357*17ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 358*17ab2063SBarry Smith if (zz != yy) VecCopy(zz,yy); 359*17ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 360*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 361*17ab2063SBarry Smith idx = aij->j + aij->i[i] + shift; 362*17ab2063SBarry Smith v = aij->a + aij->i[i] + shift; 363*17ab2063SBarry Smith n = aij->i[i+1] - aij->i[i]; 364*17ab2063SBarry Smith alpha = x[i]; 365*17ab2063SBarry Smith /* should inline */ 366*17ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 367*17ab2063SBarry Smith } 368*17ab2063SBarry Smith return 0; 369*17ab2063SBarry Smith } 370*17ab2063SBarry Smith 371*17ab2063SBarry Smith static int MatMult_SeqAIJ(Mat aijin,Vec xx,Vec yy) 372*17ab2063SBarry Smith { 373*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 374*17ab2063SBarry Smith Scalar *x, *y, *v, sum; 375*17ab2063SBarry Smith int m = aij->m, n, i, *idx; 376*17ab2063SBarry Smith int shift = aij->indexshift,ii; 377*17ab2063SBarry Smith 378*17ab2063SBarry Smith if (!aij->assembled) 379*17ab2063SBarry Smith SETERRQ(1,"MatMult_SeqAIJ:Cannot multiply unassembled matrix"); 380*17ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 381*17ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 382*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 383*17ab2063SBarry Smith idx = aij->j + aij->i[i] + shift; 384*17ab2063SBarry Smith v = aij->a + aij->i[i] + shift; 385*17ab2063SBarry Smith n = aij->i[i+1] - aij->i[i]; 386*17ab2063SBarry Smith sum = 0.0; 387*17ab2063SBarry Smith /* SPARSEDENSEDOT(sum,x,v,idx,n); */ 388*17ab2063SBarry Smith while (n--) sum += *v++ * x[*idx++]; 389*17ab2063SBarry Smith /* for ( j=n-1; j>-1; j--) sum += v[j]*x[idx[j]]; */ 390*17ab2063SBarry Smith y[i] = sum; 391*17ab2063SBarry Smith } 392*17ab2063SBarry Smith PLogFlops(2*aij->nz - m); 393*17ab2063SBarry Smith return 0; 394*17ab2063SBarry Smith } 395*17ab2063SBarry Smith 396*17ab2063SBarry Smith static int MatMultAdd_SeqAIJ(Mat aijin,Vec xx,Vec yy,Vec zz) 397*17ab2063SBarry Smith { 398*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) aijin->data; 399*17ab2063SBarry Smith Scalar *x, *y, *z, *v, sum; 400*17ab2063SBarry Smith int m = aij->m, n, i, *idx; 401*17ab2063SBarry Smith int shift = aij->indexshift; 402*17ab2063SBarry Smith 403*17ab2063SBarry Smith if (!aij->assembled) 404*17ab2063SBarry Smith SETERRQ(1,"MatMultAdd_SeqAIJ:Cannot multiply unassembled matrix"); 405*17ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); VecGetArray(zz,&z); 406*17ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 407*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 408*17ab2063SBarry Smith idx = aij->j + aij->i[i] + shift; 409*17ab2063SBarry Smith v = aij->a + aij->i[i] + shift; 410*17ab2063SBarry Smith n = aij->i[i+1] - aij->i[i]; 411*17ab2063SBarry Smith sum = y[i]; 412*17ab2063SBarry Smith SPARSEDENSEDOT(sum,x,v,idx,n); 413*17ab2063SBarry Smith z[i] = sum; 414*17ab2063SBarry Smith } 415*17ab2063SBarry Smith PLogFlops(2*aij->nz); 416*17ab2063SBarry Smith return 0; 417*17ab2063SBarry Smith } 418*17ab2063SBarry Smith 419*17ab2063SBarry Smith /* 420*17ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 421*17ab2063SBarry Smith */ 422*17ab2063SBarry Smith 423*17ab2063SBarry Smith int MatMarkDiag_SeqAIJ(Mat mat) 424*17ab2063SBarry Smith { 425*17ab2063SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) mat->data; 426*17ab2063SBarry Smith int i,j, *diag, m = aij->m; 427*17ab2063SBarry Smith int shift = aij->indexshift; 428*17ab2063SBarry Smith 429*17ab2063SBarry Smith if (!aij->assembled) SETERRQ(1,"MatMarkDiag_SeqAIJ:unassembled matrix"); 430*17ab2063SBarry Smith diag = (int *) PETSCMALLOC( (m+1)*sizeof(int)); CHKPTRQ(diag); 431*17ab2063SBarry Smith PLogObjectMemory(mat,(m+1)*sizeof(int)); 432*17ab2063SBarry Smith for ( i=0; i<aij->m; i++ ) { 433*17ab2063SBarry Smith for ( j=aij->i[i]+shift; j<aij->i[i+1]+shift; j++ ) { 434*17ab2063SBarry Smith if (aij->j[j]+shift == i) { 435*17ab2063SBarry Smith diag[i] = j - shift; 436*17ab2063SBarry Smith break; 437*17ab2063SBarry Smith } 438*17ab2063SBarry Smith } 439*17ab2063SBarry Smith } 440*17ab2063SBarry Smith aij->diag = diag; 441*17ab2063SBarry Smith return 0; 442*17ab2063SBarry Smith } 443*17ab2063SBarry Smith 444*17ab2063SBarry Smith static int MatRelax_SeqAIJ(Mat matin,Vec bb,double omega,MatSORType flag, 445*17ab2063SBarry Smith double fshift,int its,Vec xx) 446*17ab2063SBarry Smith { 447*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 448*17ab2063SBarry Smith Scalar *x, *b, *bs, d, *xs, sum, *v = mat->a,*t,scale,*ts, *xb; 449*17ab2063SBarry Smith int ierr, *idx, *diag; 450*17ab2063SBarry Smith int n = mat->n, m = mat->m, i; 451*17ab2063SBarry Smith int shift = mat->indexshift; 452*17ab2063SBarry Smith 453*17ab2063SBarry Smith VecGetArray(xx,&x); VecGetArray(bb,&b); 454*17ab2063SBarry Smith if (!mat->diag) {if ((ierr = MatMarkDiag_SeqAIJ(matin))) return ierr;} 455*17ab2063SBarry Smith diag = mat->diag; 456*17ab2063SBarry Smith xs = x + shift; /* shifted by one for index start of a or mat->j*/ 457*17ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 458*17ab2063SBarry Smith /* apply ( U + D/omega) to the vector */ 459*17ab2063SBarry Smith bs = b + shift; 460*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 461*17ab2063SBarry Smith d = fshift + mat->a[diag[i] + shift]; 462*17ab2063SBarry Smith n = mat->i[i+1] - diag[i] - 1; 463*17ab2063SBarry Smith idx = mat->j + diag[i] + (!shift); 464*17ab2063SBarry Smith v = mat->a + diag[i] + (!shift); 465*17ab2063SBarry Smith sum = b[i]*d/omega; 466*17ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 467*17ab2063SBarry Smith x[i] = sum; 468*17ab2063SBarry Smith } 469*17ab2063SBarry Smith return 0; 470*17ab2063SBarry Smith } 471*17ab2063SBarry Smith if (flag == SOR_APPLY_LOWER) { 472*17ab2063SBarry Smith SETERRQ(1,"MatRelax_SeqAIJ:SOR_APPLY_LOWER is not done"); 473*17ab2063SBarry Smith } 474*17ab2063SBarry Smith if (flag & SOR_EISENSTAT) { 475*17ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 476*17ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 477*17ab2063SBarry Smith 478*17ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 479*17ab2063SBarry Smith 480*17ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 481*17ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 482*17ab2063SBarry Smith is the relaxation factor. 483*17ab2063SBarry Smith */ 484*17ab2063SBarry Smith t = (Scalar *) PETSCMALLOC( m*sizeof(Scalar) ); CHKPTRQ(t); 485*17ab2063SBarry Smith scale = (2.0/omega) - 1.0; 486*17ab2063SBarry Smith 487*17ab2063SBarry Smith /* x = (E + U)^{-1} b */ 488*17ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 489*17ab2063SBarry Smith d = fshift + mat->a[diag[i] + shift]; 490*17ab2063SBarry Smith n = mat->i[i+1] - diag[i] - 1; 491*17ab2063SBarry Smith idx = mat->j + diag[i] + (!shift); 492*17ab2063SBarry Smith v = mat->a + diag[i] + (!shift); 493*17ab2063SBarry Smith sum = b[i]; 494*17ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 495*17ab2063SBarry Smith x[i] = omega*(sum/d); 496*17ab2063SBarry Smith } 497*17ab2063SBarry Smith 498*17ab2063SBarry Smith /* t = b - (2*E - D)x */ 499*17ab2063SBarry Smith v = mat->a; 500*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 501*17ab2063SBarry Smith 502*17ab2063SBarry Smith /* t = (E + L)^{-1}t */ 503*17ab2063SBarry Smith ts = t + shift; /* shifted by one for index start of a or mat->j*/ 504*17ab2063SBarry Smith diag = mat->diag; 505*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 506*17ab2063SBarry Smith d = fshift + mat->a[diag[i]+shift]; 507*17ab2063SBarry Smith n = diag[i] - mat->i[i]; 508*17ab2063SBarry Smith idx = mat->j + mat->i[i] + shift; 509*17ab2063SBarry Smith v = mat->a + mat->i[i] + shift; 510*17ab2063SBarry Smith sum = t[i]; 511*17ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 512*17ab2063SBarry Smith t[i] = omega*(sum/d); 513*17ab2063SBarry Smith } 514*17ab2063SBarry Smith 515*17ab2063SBarry Smith /* x = x + t */ 516*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { x[i] += t[i]; } 517*17ab2063SBarry Smith PETSCFREE(t); 518*17ab2063SBarry Smith return 0; 519*17ab2063SBarry Smith } 520*17ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 521*17ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 522*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 523*17ab2063SBarry Smith d = fshift + mat->a[diag[i]+shift]; 524*17ab2063SBarry Smith n = diag[i] - mat->i[i]; 525*17ab2063SBarry Smith idx = mat->j + mat->i[i] + shift; 526*17ab2063SBarry Smith v = mat->a + mat->i[i] + shift; 527*17ab2063SBarry Smith sum = b[i]; 528*17ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 529*17ab2063SBarry Smith x[i] = omega*(sum/d); 530*17ab2063SBarry Smith } 531*17ab2063SBarry Smith xb = x; 532*17ab2063SBarry Smith } 533*17ab2063SBarry Smith else xb = b; 534*17ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 535*17ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 536*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 537*17ab2063SBarry Smith x[i] *= mat->a[diag[i]+shift]; 538*17ab2063SBarry Smith } 539*17ab2063SBarry Smith } 540*17ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 541*17ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 542*17ab2063SBarry Smith d = fshift + mat->a[diag[i] + shift]; 543*17ab2063SBarry Smith n = mat->i[i+1] - diag[i] - 1; 544*17ab2063SBarry Smith idx = mat->j + diag[i] + (!shift); 545*17ab2063SBarry Smith v = mat->a + diag[i] + (!shift); 546*17ab2063SBarry Smith sum = xb[i]; 547*17ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 548*17ab2063SBarry Smith x[i] = omega*(sum/d); 549*17ab2063SBarry Smith } 550*17ab2063SBarry Smith } 551*17ab2063SBarry Smith its--; 552*17ab2063SBarry Smith } 553*17ab2063SBarry Smith while (its--) { 554*17ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 555*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 556*17ab2063SBarry Smith d = fshift + mat->a[diag[i]+shift]; 557*17ab2063SBarry Smith n = mat->i[i+1] - mat->i[i]; 558*17ab2063SBarry Smith idx = mat->j + mat->i[i] + shift; 559*17ab2063SBarry Smith v = mat->a + mat->i[i] + shift; 560*17ab2063SBarry Smith sum = b[i]; 561*17ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 562*17ab2063SBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum/d + x[i]); 563*17ab2063SBarry Smith } 564*17ab2063SBarry Smith } 565*17ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 566*17ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 567*17ab2063SBarry Smith d = fshift + mat->a[diag[i] + shift]; 568*17ab2063SBarry Smith n = mat->i[i+1] - mat->i[i]; 569*17ab2063SBarry Smith idx = mat->j + mat->i[i] + shift; 570*17ab2063SBarry Smith v = mat->a + mat->i[i] + shift; 571*17ab2063SBarry Smith sum = b[i]; 572*17ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 573*17ab2063SBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum/d + x[i]); 574*17ab2063SBarry Smith } 575*17ab2063SBarry Smith } 576*17ab2063SBarry Smith } 577*17ab2063SBarry Smith return 0; 578*17ab2063SBarry Smith } 579*17ab2063SBarry Smith 580*17ab2063SBarry Smith static int MatGetInfo_SeqAIJ(Mat matin,MatInfoType flag,int *nz, 581*17ab2063SBarry Smith int *nzalloc,int *mem) 582*17ab2063SBarry Smith { 583*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 584*17ab2063SBarry Smith *nz = mat->nz; 585*17ab2063SBarry Smith *nzalloc = mat->maxnz; 586*17ab2063SBarry Smith *mem = (int)matin->mem; 587*17ab2063SBarry Smith return 0; 588*17ab2063SBarry Smith } 589*17ab2063SBarry Smith 590*17ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*); 591*17ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 592*17ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double); 593*17ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 594*17ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 595*17ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec); 596*17ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec); 597*17ab2063SBarry Smith 598*17ab2063SBarry Smith static int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 599*17ab2063SBarry Smith { 600*17ab2063SBarry Smith Mat_SeqAIJ *l = (Mat_SeqAIJ *) A->data; 601*17ab2063SBarry Smith int i,ierr,N, *rows,m = l->m - 1; 602*17ab2063SBarry Smith int shift = l->indexshift; 603*17ab2063SBarry Smith 604*17ab2063SBarry Smith ierr = ISGetLocalSize(is,&N); CHKERRQ(ierr); 605*17ab2063SBarry Smith ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 606*17ab2063SBarry Smith if (diag) { 607*17ab2063SBarry Smith for ( i=0; i<N; i++ ) { 608*17ab2063SBarry Smith if (rows[i] < 0 || rows[i] > m) 609*17ab2063SBarry Smith SETERRQ(1,"MatZeroRows_SeqAIJ:row out of range"); 610*17ab2063SBarry Smith if (l->ilen[rows[i]] > 0) { /* in case row was completely empty */ 611*17ab2063SBarry Smith l->ilen[rows[i]] = 1; 612*17ab2063SBarry Smith l->a[l->i[rows[i]]+shift] = *diag; 613*17ab2063SBarry Smith l->j[l->i[rows[i]]+shift] = rows[i]+shift; 614*17ab2063SBarry Smith } 615*17ab2063SBarry Smith else { 616*17ab2063SBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES); 617*17ab2063SBarry Smith CHKERRQ(ierr); 618*17ab2063SBarry Smith } 619*17ab2063SBarry Smith } 620*17ab2063SBarry Smith } 621*17ab2063SBarry Smith else { 622*17ab2063SBarry Smith for ( i=0; i<N; i++ ) { 623*17ab2063SBarry Smith if (rows[i] < 0 || rows[i] > m) 624*17ab2063SBarry Smith SETERRQ(1,"MatZeroRows_SeqAIJ:row out of range"); 625*17ab2063SBarry Smith l->ilen[rows[i]] = 0; 626*17ab2063SBarry Smith } 627*17ab2063SBarry Smith } 628*17ab2063SBarry Smith ISRestoreIndices(is,&rows); 629*17ab2063SBarry Smith ierr = MatAssemblyBegin(A,FINAL_ASSEMBLY); CHKERRQ(ierr); 630*17ab2063SBarry Smith ierr = MatAssemblyEnd(A,FINAL_ASSEMBLY); CHKERRQ(ierr); 631*17ab2063SBarry Smith return 0; 632*17ab2063SBarry Smith } 633*17ab2063SBarry Smith 634*17ab2063SBarry Smith static int MatGetSize_SeqAIJ(Mat matin,int *m,int *n) 635*17ab2063SBarry Smith { 636*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 637*17ab2063SBarry Smith *m = mat->m; *n = mat->n; 638*17ab2063SBarry Smith return 0; 639*17ab2063SBarry Smith } 640*17ab2063SBarry Smith 641*17ab2063SBarry Smith static int MatGetOwnershipRange_SeqAIJ(Mat matin,int *m,int *n) 642*17ab2063SBarry Smith { 643*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 644*17ab2063SBarry Smith *m = 0; *n = mat->m; 645*17ab2063SBarry Smith return 0; 646*17ab2063SBarry Smith } 647*17ab2063SBarry Smith static int MatGetRow_SeqAIJ(Mat matin,int row,int *nz,int **idx,Scalar **v) 648*17ab2063SBarry Smith { 649*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 650*17ab2063SBarry Smith int *itmp,i,ierr; 651*17ab2063SBarry Smith int shift = mat->indexshift; 652*17ab2063SBarry Smith 653*17ab2063SBarry Smith if (row < 0 || row >= mat->m) SETERRQ(1,"MatGetRow_SeqAIJ:Row out of range"); 654*17ab2063SBarry Smith 655*17ab2063SBarry Smith if (!mat->assembled) { 656*17ab2063SBarry Smith ierr = MatAssemblyBegin(matin,FINAL_ASSEMBLY); CHKERRQ(ierr); 657*17ab2063SBarry Smith ierr = MatAssemblyEnd(matin,FINAL_ASSEMBLY); CHKERRQ(ierr); 658*17ab2063SBarry Smith } 659*17ab2063SBarry Smith *nz = mat->i[row+1] - mat->i[row]; 660*17ab2063SBarry Smith if (v) *v = mat->a + mat->i[row] + shift; 661*17ab2063SBarry Smith if (idx) { 662*17ab2063SBarry Smith if (*nz) { 663*17ab2063SBarry Smith itmp = mat->j + mat->i[row] + shift; 664*17ab2063SBarry Smith *idx = (int *) PETSCMALLOC( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 665*17ab2063SBarry Smith for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;} 666*17ab2063SBarry Smith } 667*17ab2063SBarry Smith else *idx = 0; 668*17ab2063SBarry Smith } 669*17ab2063SBarry Smith return 0; 670*17ab2063SBarry Smith } 671*17ab2063SBarry Smith 672*17ab2063SBarry Smith static int MatRestoreRow_SeqAIJ(Mat matin,int row,int *nz,int **idx,Scalar **v) 673*17ab2063SBarry Smith { 674*17ab2063SBarry Smith if (idx) {if (*idx) PETSCFREE(*idx);} 675*17ab2063SBarry Smith return 0; 676*17ab2063SBarry Smith } 677*17ab2063SBarry Smith 678*17ab2063SBarry Smith static int MatNorm_SeqAIJ(Mat matin,MatNormType type,double *norm) 679*17ab2063SBarry Smith { 680*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 681*17ab2063SBarry Smith Scalar *v = mat->a; 682*17ab2063SBarry Smith double sum = 0.0; 683*17ab2063SBarry Smith int i, j; 684*17ab2063SBarry Smith int shift = mat->indexshift; 685*17ab2063SBarry Smith 686*17ab2063SBarry Smith if (!mat->assembled) 687*17ab2063SBarry Smith SETERRQ(1,"MatNorm_SeqAIJ:Cannot compute norm of unassembled matrix"); 688*17ab2063SBarry Smith if (type == NORM_FROBENIUS) { 689*17ab2063SBarry Smith for (i=0; i<mat->nz; i++ ) { 690*17ab2063SBarry Smith #if defined(PETSC_COMPLEX) 691*17ab2063SBarry Smith sum += real(conj(*v)*(*v)); v++; 692*17ab2063SBarry Smith #else 693*17ab2063SBarry Smith sum += (*v)*(*v); v++; 694*17ab2063SBarry Smith #endif 695*17ab2063SBarry Smith } 696*17ab2063SBarry Smith *norm = sqrt(sum); 697*17ab2063SBarry Smith } 698*17ab2063SBarry Smith else if (type == NORM_1) { 699*17ab2063SBarry Smith double *tmp; 700*17ab2063SBarry Smith int *jj = mat->j; 701*17ab2063SBarry Smith tmp = (double *) PETSCMALLOC( mat->n*sizeof(double) ); CHKPTRQ(tmp); 702*17ab2063SBarry Smith PETSCMEMSET(tmp,0,mat->n*sizeof(double)); 703*17ab2063SBarry Smith *norm = 0.0; 704*17ab2063SBarry Smith for ( j=0; j<mat->nz; j++ ) { 705*17ab2063SBarry Smith #if defined(PETSC_COMPLEX) 706*17ab2063SBarry Smith tmp[*jj++ + shift] += abs(*v++); 707*17ab2063SBarry Smith #else 708*17ab2063SBarry Smith tmp[*jj++ + shift] += fabs(*v++); 709*17ab2063SBarry Smith #endif 710*17ab2063SBarry Smith } 711*17ab2063SBarry Smith for ( j=0; j<mat->n; j++ ) { 712*17ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 713*17ab2063SBarry Smith } 714*17ab2063SBarry Smith PETSCFREE(tmp); 715*17ab2063SBarry Smith } 716*17ab2063SBarry Smith else if (type == NORM_INFINITY) { 717*17ab2063SBarry Smith *norm = 0.0; 718*17ab2063SBarry Smith for ( j=0; j<mat->m; j++ ) { 719*17ab2063SBarry Smith v = mat->a + mat->i[j] + shift; 720*17ab2063SBarry Smith sum = 0.0; 721*17ab2063SBarry Smith for ( i=0; i<mat->i[j+1]-mat->i[j]; i++ ) { 722*17ab2063SBarry Smith #if defined(PETSC_COMPLEX) 723*17ab2063SBarry Smith sum += abs(*v); v++; 724*17ab2063SBarry Smith #else 725*17ab2063SBarry Smith sum += fabs(*v); v++; 726*17ab2063SBarry Smith #endif 727*17ab2063SBarry Smith } 728*17ab2063SBarry Smith if (sum > *norm) *norm = sum; 729*17ab2063SBarry Smith } 730*17ab2063SBarry Smith } 731*17ab2063SBarry Smith else { 732*17ab2063SBarry Smith SETERRQ(1,"MatNorm_SeqAIJ:No support for the two norm yet"); 733*17ab2063SBarry Smith } 734*17ab2063SBarry Smith return 0; 735*17ab2063SBarry Smith } 736*17ab2063SBarry Smith 737*17ab2063SBarry Smith static int MatTranspose_SeqAIJ(Mat A,Mat *matout) 738*17ab2063SBarry Smith { 739*17ab2063SBarry Smith Mat_SeqAIJ *amat = (Mat_SeqAIJ *) A->data; 740*17ab2063SBarry Smith Mat tmat; 741*17ab2063SBarry Smith int i, ierr, *aj = amat->j, *ai = amat->i, m = amat->m, len, *col; 742*17ab2063SBarry Smith Scalar *array = amat->a; 743*17ab2063SBarry Smith int shift = amat->indexshift; 744*17ab2063SBarry Smith 745*17ab2063SBarry Smith if (!matout && m != amat->n) SETERRQ(1, 746*17ab2063SBarry Smith "MatTranspose_SeqAIJ: Cannot transpose rectangular matrix in place"); 747*17ab2063SBarry Smith col = (int *) PETSCMALLOC((1+amat->n)*sizeof(int)); CHKPTRQ(col); 748*17ab2063SBarry Smith PETSCMEMSET(col,0,(1+amat->n)*sizeof(int)); 749*17ab2063SBarry Smith if (shift) { 750*17ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1; 751*17ab2063SBarry Smith } 752*17ab2063SBarry Smith for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1; 753*17ab2063SBarry Smith ierr = MatCreateSeqAIJ(A->comm,amat->n,m,0,col,&tmat); CHKERRQ(ierr); 754*17ab2063SBarry Smith PETSCFREE(col); 755*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 756*17ab2063SBarry Smith len = ai[i+1]-ai[i]; 757*17ab2063SBarry Smith ierr = MatSetValues(tmat,len,aj,1,&i,array,INSERT_VALUES); CHKERRQ(ierr); 758*17ab2063SBarry Smith array += len; aj += len; 759*17ab2063SBarry Smith } 760*17ab2063SBarry Smith if (shift) { 761*17ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1; 762*17ab2063SBarry Smith } 763*17ab2063SBarry Smith 764*17ab2063SBarry Smith ierr = MatAssemblyBegin(tmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 765*17ab2063SBarry Smith ierr = MatAssemblyEnd(tmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 766*17ab2063SBarry Smith 767*17ab2063SBarry Smith if (matout) { 768*17ab2063SBarry Smith *matout = tmat; 769*17ab2063SBarry Smith } else { 770*17ab2063SBarry Smith /* This isn't really an in-place transpose ... but free data structures from amat */ 771*17ab2063SBarry Smith PETSCFREE(amat->a); 772*17ab2063SBarry Smith if (!amat->singlemalloc) {PETSCFREE(amat->i); PETSCFREE(amat->j);} 773*17ab2063SBarry Smith if (amat->diag) PETSCFREE(amat->diag); 774*17ab2063SBarry Smith if (amat->ilen) PETSCFREE(amat->ilen); 775*17ab2063SBarry Smith if (amat->imax) PETSCFREE(amat->imax); 776*17ab2063SBarry Smith if (amat->solve_work) PETSCFREE(amat->solve_work); 777*17ab2063SBarry Smith PETSCFREE(amat); 778*17ab2063SBarry Smith PETSCMEMCPY(A,tmat,sizeof(struct _Mat)); 779*17ab2063SBarry Smith PETSCHEADERDESTROY(tmat); 780*17ab2063SBarry Smith } 781*17ab2063SBarry Smith return 0; 782*17ab2063SBarry Smith } 783*17ab2063SBarry Smith 784*17ab2063SBarry Smith static int MatScale_SeqAIJ(Mat matin,Vec ll,Vec rr) 785*17ab2063SBarry Smith { 786*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 787*17ab2063SBarry Smith Scalar *l,*r,x,*v; 788*17ab2063SBarry Smith int i,j,m = mat->m, n = mat->n, M, nz = mat->nz, *jj; 789*17ab2063SBarry Smith int shift = mat->indexshift; 790*17ab2063SBarry Smith 791*17ab2063SBarry Smith if (!mat->assembled) 792*17ab2063SBarry Smith SETERRQ(1,"MatScale_SeqAIJ:Cannot scale unassembled matrix"); 793*17ab2063SBarry Smith if (ll) { 794*17ab2063SBarry Smith VecGetArray(ll,&l); VecGetSize(ll,&m); 795*17ab2063SBarry Smith if (m != mat->m) 796*17ab2063SBarry Smith SETERRQ(1,"MatScale_SeqAIJ:Left scaling vector wrong length"); 797*17ab2063SBarry Smith v = mat->a; 798*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 799*17ab2063SBarry Smith x = l[i]; 800*17ab2063SBarry Smith M = mat->i[i+1] - mat->i[i]; 801*17ab2063SBarry Smith for ( j=0; j<M; j++ ) { (*v++) *= x;} 802*17ab2063SBarry Smith } 803*17ab2063SBarry Smith } 804*17ab2063SBarry Smith if (rr) { 805*17ab2063SBarry Smith VecGetArray(rr,&r); VecGetSize(rr,&n); 806*17ab2063SBarry Smith if (n != mat->n) 807*17ab2063SBarry Smith SETERRQ(1,"MatScale_SeqAIJ:Right scaling vector wrong length"); 808*17ab2063SBarry Smith v = mat->a; jj = mat->j; 809*17ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 810*17ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 811*17ab2063SBarry Smith } 812*17ab2063SBarry Smith } 813*17ab2063SBarry Smith return 0; 814*17ab2063SBarry Smith } 815*17ab2063SBarry Smith 816*17ab2063SBarry Smith static int MatGetSubMatrix_SeqAIJ(Mat matin,IS isrow,IS iscol,Mat *submat) 817*17ab2063SBarry Smith { 818*17ab2063SBarry Smith Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; 819*17ab2063SBarry Smith int nznew, *smap, i, k, kstart, kend, ierr, oldcols = mat->n; 820*17ab2063SBarry Smith int *irow, *icol, nrows, ncols, *cwork; 821*17ab2063SBarry Smith Scalar *vwork; 822*17ab2063SBarry Smith Mat newmat; 823*17ab2063SBarry Smith int shift = mat->indexshift; 824*17ab2063SBarry Smith 825*17ab2063SBarry Smith if (!mat->assembled) SETERRQ(1, 826*17ab2063SBarry Smith "MatGetSubMatrix_SeqAIJ:Cannot extract submatrix from unassembled matrix"); 827*17ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 828*17ab2063SBarry Smith ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 829*17ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 830*17ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 831*17ab2063SBarry Smith 832*17ab2063SBarry Smith smap = (int *) PETSCMALLOC((1+oldcols)*sizeof(int)); CHKPTRQ(smap); 833*17ab2063SBarry Smith cwork = (int *) PETSCMALLOC((1+ncols)*sizeof(int)); CHKPTRQ(cwork); 834*17ab2063SBarry Smith vwork = (Scalar *) PETSCMALLOC((1+ncols)*sizeof(Scalar)); CHKPTRQ(vwork); 835*17ab2063SBarry Smith PETSCMEMSET(smap,0,oldcols*sizeof(int)); 836*17ab2063SBarry Smith for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 837*17ab2063SBarry Smith 838*17ab2063SBarry Smith /* Create and fill new matrix */ 839*17ab2063SBarry Smith ierr = MatCreateSeqAIJ(matin->comm,nrows,ncols,0,0,&newmat); 840*17ab2063SBarry Smith CHKERRQ(ierr); 841*17ab2063SBarry Smith for (i=0; i<nrows; i++) { 842*17ab2063SBarry Smith nznew = 0; 843*17ab2063SBarry Smith kstart = mat->i[irow[i]]+shift; 844*17ab2063SBarry Smith kend = kstart + mat->ilen[irow[i]]; 845*17ab2063SBarry Smith for ( k=kstart; k<kend; k++ ) { 846*17ab2063SBarry Smith if (smap[mat->j[k]+shift]) { 847*17ab2063SBarry Smith cwork[nznew] = smap[mat->j[k]+shift] - 1; 848*17ab2063SBarry Smith vwork[nznew++] = mat->a[k]; 849*17ab2063SBarry Smith } 850*17ab2063SBarry Smith } 851*17ab2063SBarry Smith ierr = MatSetValues(newmat,1,&i,nznew,cwork,vwork,INSERT_VALUES); 852*17ab2063SBarry Smith CHKERRQ(ierr); 853*17ab2063SBarry Smith } 854*17ab2063SBarry Smith ierr = MatAssemblyBegin(newmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 855*17ab2063SBarry Smith ierr = MatAssemblyEnd(newmat,FINAL_ASSEMBLY); CHKERRQ(ierr); 856*17ab2063SBarry Smith 857*17ab2063SBarry Smith /* Free work space */ 858*17ab2063SBarry Smith PETSCFREE(smap); PETSCFREE(cwork); PETSCFREE(vwork); 859*17ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 860*17ab2063SBarry Smith ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 861*17ab2063SBarry Smith *submat = newmat; 862*17ab2063SBarry Smith return 0; 863*17ab2063SBarry Smith } 864*17ab2063SBarry Smith 865*17ab2063SBarry Smith static int MatGetSubMatrixInPlace_SeqAIJ(Mat matin,IS rows,IS cols) 866*17ab2063SBarry Smith { 867*17ab2063SBarry Smith /* Mat_SeqAIJ *mat = (Mat_SeqAIJ *) matin->data; */ 868*17ab2063SBarry Smith 869*17ab2063SBarry Smith SETERRQ(1,"MatGetSubMatrixInPlace_SeqAIJ:not finished"); 870*17ab2063SBarry Smith } 871*17ab2063SBarry Smith 872*17ab2063SBarry Smith /* -------------------------------------------------------------------*/ 873*17ab2063SBarry Smith extern int MatILUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,int,Mat *); 874*17ab2063SBarry Smith extern int MatConvert_SeqAIJ(Mat,MatType,Mat *); 875*17ab2063SBarry Smith static int MatCopyPrivate_SeqAIJ(Mat,Mat *); 876*17ab2063SBarry Smith 877*17ab2063SBarry Smith static struct _MatOps MatOps = {MatSetValues_SeqAIJ, 878*17ab2063SBarry Smith MatGetRow_SeqAIJ,MatRestoreRow_SeqAIJ, 879*17ab2063SBarry Smith MatMult_SeqAIJ,MatMultAdd_SeqAIJ,MatMultTrans_SeqAIJ,MatMultTransAdd_SeqAIJ, 880*17ab2063SBarry Smith MatSolve_SeqAIJ,MatSolveAdd_SeqAIJ, 881*17ab2063SBarry Smith MatSolveTrans_SeqAIJ,MatSolveTransAdd_SeqAIJ, 882*17ab2063SBarry Smith MatLUFactor_SeqAIJ,0, 883*17ab2063SBarry Smith MatRelax_SeqAIJ, 884*17ab2063SBarry Smith MatTranspose_SeqAIJ, 885*17ab2063SBarry Smith MatGetInfo_SeqAIJ,0, 886*17ab2063SBarry Smith MatGetDiagonal_SeqAIJ,MatScale_SeqAIJ,MatNorm_SeqAIJ, 887*17ab2063SBarry Smith 0,MatAssemblyEnd_SeqAIJ, 888*17ab2063SBarry Smith MatCompress_SeqAIJ, 889*17ab2063SBarry Smith MatSetOption_SeqAIJ,MatZeroEntries_SeqAIJ,MatZeroRows_SeqAIJ, 890*17ab2063SBarry Smith MatGetReordering_SeqAIJ, 891*17ab2063SBarry Smith MatLUFactorSymbolic_SeqAIJ,MatLUFactorNumeric_SeqAIJ,0,0, 892*17ab2063SBarry Smith MatGetSize_SeqAIJ,MatGetSize_SeqAIJ,MatGetOwnershipRange_SeqAIJ, 893*17ab2063SBarry Smith MatILUFactorSymbolic_SeqAIJ,0, 894*17ab2063SBarry Smith 0,0,MatConvert_SeqAIJ, 895*17ab2063SBarry Smith MatGetSubMatrix_SeqAIJ,MatGetSubMatrixInPlace_SeqAIJ, 896*17ab2063SBarry Smith MatCopyPrivate_SeqAIJ}; 897*17ab2063SBarry Smith 898*17ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 899*17ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 900*17ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 901*17ab2063SBarry Smith 902*17ab2063SBarry Smith /*@C 903*17ab2063SBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ format 904*17ab2063SBarry Smith (the default uniprocessor PETSc format). 905*17ab2063SBarry Smith 906*17ab2063SBarry Smith Input Parameters: 907*17ab2063SBarry Smith . comm - MPI communicator, set to MPI_COMM_SELF 908*17ab2063SBarry Smith . m - number of rows 909*17ab2063SBarry Smith . n - number of columns 910*17ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 911*17ab2063SBarry Smith . nzz - number of nonzeros per row or null (possibly different for each row) 912*17ab2063SBarry Smith 913*17ab2063SBarry Smith Output Parameter: 914*17ab2063SBarry Smith . newmat - the matrix 915*17ab2063SBarry Smith 916*17ab2063SBarry Smith Notes: 917*17ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 918*17ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 919*17ab2063SBarry Smith storage. That is, the stored row and column indices begin at 920*17ab2063SBarry Smith one, not zero. 921*17ab2063SBarry Smith 922*17ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 923*17ab2063SBarry Smith Set both nz and nnz to zero for PETSc to control dynamic memory 924*17ab2063SBarry Smith allocation. 925*17ab2063SBarry Smith 926*17ab2063SBarry Smith .keywords: matrix, aij, compressed row, sparse 927*17ab2063SBarry Smith 928*17ab2063SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues() 929*17ab2063SBarry Smith @*/ 930*17ab2063SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz, 931*17ab2063SBarry Smith int *nnz, Mat *newmat) 932*17ab2063SBarry Smith { 933*17ab2063SBarry Smith Mat mat; 934*17ab2063SBarry Smith Mat_SeqAIJ *aij; 935*17ab2063SBarry Smith int i,len,ierr; 936*17ab2063SBarry Smith *newmat = 0; 937*17ab2063SBarry Smith PETSCHEADERCREATE(mat,_Mat,MAT_COOKIE,MATSEQAIJ,comm); 938*17ab2063SBarry Smith PLogObjectCreate(mat); 939*17ab2063SBarry Smith mat->data = (void *) (aij = PETSCNEW(Mat_SeqAIJ)); CHKPTRQ(aij); 940*17ab2063SBarry Smith PETSCMEMCPY(&mat->ops,&MatOps,sizeof(struct _MatOps)); 941*17ab2063SBarry Smith mat->destroy = MatDestroy_SeqAIJ; 942*17ab2063SBarry Smith mat->view = MatView_SeqAIJ; 943*17ab2063SBarry Smith mat->factor = 0; 944*17ab2063SBarry Smith mat->lupivotthreshold = 1.0; 945*17ab2063SBarry Smith OptionsGetDouble(0,"-mat_lu_pivotthreshold",&mat->lupivotthreshold); 946*17ab2063SBarry Smith aij->row = 0; 947*17ab2063SBarry Smith aij->col = 0; 948*17ab2063SBarry Smith aij->indexshift = 0; 949*17ab2063SBarry Smith if (OptionsHasName(0,"-mat_aij_oneindex")) aij->indexshift = -1; 950*17ab2063SBarry Smith 951*17ab2063SBarry Smith aij->m = m; 952*17ab2063SBarry Smith aij->n = n; 953*17ab2063SBarry Smith aij->imax = (int *) PETSCMALLOC( (m+1)*sizeof(int) ); CHKPTRQ(aij->imax); 954*17ab2063SBarry Smith if (!nnz) { 955*17ab2063SBarry Smith if (nz <= 0) nz = 1; 956*17ab2063SBarry Smith for ( i=0; i<m; i++ ) aij->imax[i] = nz; 957*17ab2063SBarry Smith nz = nz*m; 958*17ab2063SBarry Smith } 959*17ab2063SBarry Smith else { 960*17ab2063SBarry Smith nz = 0; 961*17ab2063SBarry Smith for ( i=0; i<m; i++ ) {aij->imax[i] = nnz[i]; nz += nnz[i];} 962*17ab2063SBarry Smith } 963*17ab2063SBarry Smith 964*17ab2063SBarry Smith /* allocate the matrix space */ 965*17ab2063SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (aij->m+1)*sizeof(int); 966*17ab2063SBarry Smith aij->a = (Scalar *) PETSCMALLOC( len ); CHKPTRQ(aij->a); 967*17ab2063SBarry Smith aij->j = (int *) (aij->a + nz); 968*17ab2063SBarry Smith PETSCMEMSET(aij->j,0,nz*sizeof(int)); 969*17ab2063SBarry Smith aij->i = aij->j + nz; 970*17ab2063SBarry Smith aij->singlemalloc = 1; 971*17ab2063SBarry Smith 972*17ab2063SBarry Smith aij->i[0] = -aij->indexshift; 973*17ab2063SBarry Smith for (i=1; i<m+1; i++) { 974*17ab2063SBarry Smith aij->i[i] = aij->i[i-1] + aij->imax[i-1]; 975*17ab2063SBarry Smith } 976*17ab2063SBarry Smith 977*17ab2063SBarry Smith /* aij->ilen will count nonzeros in each row so far. */ 978*17ab2063SBarry Smith aij->ilen = (int *) PETSCMALLOC((m+1)*sizeof(int)); 979*17ab2063SBarry Smith PLogObjectMemory(mat,len + 2*(m+1)*sizeof(int) + sizeof(struct _Mat) 980*17ab2063SBarry Smith + sizeof(Mat_SeqAIJ)); 981*17ab2063SBarry Smith for ( i=0; i<aij->m; i++ ) { aij->ilen[i] = 0;} 982*17ab2063SBarry Smith 983*17ab2063SBarry Smith aij->nz = 0; 984*17ab2063SBarry Smith aij->maxnz = nz; 985*17ab2063SBarry Smith aij->sorted = 0; 986*17ab2063SBarry Smith aij->roworiented = 1; 987*17ab2063SBarry Smith aij->nonew = 0; 988*17ab2063SBarry Smith aij->diag = 0; 989*17ab2063SBarry Smith aij->assembled = 0; 990*17ab2063SBarry Smith aij->solve_work = 0; 991*17ab2063SBarry Smith 992*17ab2063SBarry Smith *newmat = mat; 993*17ab2063SBarry Smith if (OptionsHasName(0,"-mat_aij_superlu")) { 994*17ab2063SBarry Smith ierr = MatUseSuperLU_SeqAIJ(mat); CHKERRQ(ierr); 995*17ab2063SBarry Smith } 996*17ab2063SBarry Smith if (OptionsHasName(0,"-mat_aij_essl")) { 997*17ab2063SBarry Smith ierr = MatUseEssl_SeqAIJ(mat); CHKERRQ(ierr); 998*17ab2063SBarry Smith } 999*17ab2063SBarry Smith if (OptionsHasName(0,"-mat_aij_dxml")) { 1000*17ab2063SBarry Smith if (!aij->indexshift) 1001*17ab2063SBarry Smith SETERRQ(1,"MatCreateSeqAIJ: must use -mat_aij_oneindex with -mat_aij_dxml"); 1002*17ab2063SBarry Smith ierr = MatUseDXML_SeqAIJ(mat); CHKERRQ(ierr); 1003*17ab2063SBarry Smith } 1004*17ab2063SBarry Smith 1005*17ab2063SBarry Smith return 0; 1006*17ab2063SBarry Smith } 1007*17ab2063SBarry Smith 1008*17ab2063SBarry Smith static int MatCopyPrivate_SeqAIJ(Mat matin,Mat *newmat) 1009*17ab2063SBarry Smith { 1010*17ab2063SBarry Smith Mat mat; 1011*17ab2063SBarry Smith Mat_SeqAIJ *aij,*oldmat = (Mat_SeqAIJ *) matin->data; 1012*17ab2063SBarry Smith int i,len, m = oldmat->m; 1013*17ab2063SBarry Smith int shift = oldmat->indexshift; 1014*17ab2063SBarry Smith *newmat = 0; 1015*17ab2063SBarry Smith 1016*17ab2063SBarry Smith if (!oldmat->assembled) 1017*17ab2063SBarry Smith SETERRQ(1,"MatCopyPrivate_SeqAIJ:Cannot copy unassembled matrix"); 1018*17ab2063SBarry Smith PETSCHEADERCREATE(mat,_Mat,MAT_COOKIE,MATSEQAIJ,matin->comm); 1019*17ab2063SBarry Smith PLogObjectCreate(mat); 1020*17ab2063SBarry Smith mat->data = (void *) (aij = PETSCNEW(Mat_SeqAIJ)); CHKPTRQ(aij); 1021*17ab2063SBarry Smith PETSCMEMCPY(&mat->ops,&MatOps,sizeof(struct _MatOps)); 1022*17ab2063SBarry Smith mat->destroy = MatDestroy_SeqAIJ; 1023*17ab2063SBarry Smith mat->view = MatView_SeqAIJ; 1024*17ab2063SBarry Smith mat->factor = matin->factor; 1025*17ab2063SBarry Smith aij->row = 0; 1026*17ab2063SBarry Smith aij->col = 0; 1027*17ab2063SBarry Smith aij->indexshift = shift; 1028*17ab2063SBarry Smith 1029*17ab2063SBarry Smith aij->m = oldmat->m; 1030*17ab2063SBarry Smith aij->n = oldmat->n; 1031*17ab2063SBarry Smith 1032*17ab2063SBarry Smith aij->imax = (int *) PETSCMALLOC((m+1)*sizeof(int)); CHKPTRQ(aij->imax); 1033*17ab2063SBarry Smith aij->ilen = (int *) PETSCMALLOC((m+1)*sizeof(int)); CHKPTRQ(aij->ilen); 1034*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1035*17ab2063SBarry Smith aij->imax[i] = oldmat->imax[i]; 1036*17ab2063SBarry Smith aij->ilen[i] = oldmat->ilen[i]; 1037*17ab2063SBarry Smith } 1038*17ab2063SBarry Smith 1039*17ab2063SBarry Smith /* allocate the matrix space */ 1040*17ab2063SBarry Smith aij->singlemalloc = 1; 1041*17ab2063SBarry Smith len = (m+1)*sizeof(int)+(oldmat->i[m])*(sizeof(Scalar)+sizeof(int)); 1042*17ab2063SBarry Smith aij->a = (Scalar *) PETSCMALLOC( len ); CHKPTRQ(aij->a); 1043*17ab2063SBarry Smith aij->j = (int *) (aij->a + oldmat->i[m] + shift); 1044*17ab2063SBarry Smith aij->i = aij->j + oldmat->i[m] + shift; 1045*17ab2063SBarry Smith PETSCMEMCPY(aij->i,oldmat->i,(m+1)*sizeof(int)); 1046*17ab2063SBarry Smith if (m > 0) { 1047*17ab2063SBarry Smith PETSCMEMCPY(aij->j,oldmat->j,(oldmat->i[m]+shift)*sizeof(int)); 1048*17ab2063SBarry Smith PETSCMEMCPY(aij->a,oldmat->a,(oldmat->i[m]+shift)*sizeof(Scalar)); 1049*17ab2063SBarry Smith } 1050*17ab2063SBarry Smith 1051*17ab2063SBarry Smith PLogObjectMemory(mat,len + 2*(m+1)*sizeof(int) + sizeof(struct _Mat) 1052*17ab2063SBarry Smith + sizeof(Mat_SeqAIJ)); 1053*17ab2063SBarry Smith aij->sorted = oldmat->sorted; 1054*17ab2063SBarry Smith aij->roworiented = oldmat->roworiented; 1055*17ab2063SBarry Smith aij->nonew = oldmat->nonew; 1056*17ab2063SBarry Smith 1057*17ab2063SBarry Smith if (oldmat->diag) { 1058*17ab2063SBarry Smith aij->diag = (int *) PETSCMALLOC( (m+1)*sizeof(int) ); CHKPTRQ(aij->diag); 1059*17ab2063SBarry Smith PLogObjectMemory(mat,(m+1)*sizeof(int)); 1060*17ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1061*17ab2063SBarry Smith aij->diag[i] = oldmat->diag[i]; 1062*17ab2063SBarry Smith } 1063*17ab2063SBarry Smith } 1064*17ab2063SBarry Smith else aij->diag = 0; 1065*17ab2063SBarry Smith aij->assembled = 1; 1066*17ab2063SBarry Smith aij->nz = oldmat->nz; 1067*17ab2063SBarry Smith aij->maxnz = oldmat->maxnz; 1068*17ab2063SBarry Smith aij->solve_work = 0; 1069*17ab2063SBarry Smith *newmat = mat; 1070*17ab2063SBarry Smith return 0; 1071*17ab2063SBarry Smith } 1072*17ab2063SBarry Smith 1073*17ab2063SBarry Smith #include "sysio.h" 1074*17ab2063SBarry Smith 1075*17ab2063SBarry Smith int MatLoad_SeqAIJ(Viewer bview,MatType type,Mat *newmat) 1076*17ab2063SBarry Smith { 1077*17ab2063SBarry Smith Mat_SeqAIJ *aij; 1078*17ab2063SBarry Smith Mat mat; 1079*17ab2063SBarry Smith int i, nz, ierr; 1080*17ab2063SBarry Smith int fd; 1081*17ab2063SBarry Smith PetscObject vobj = (PetscObject) bview; 1082*17ab2063SBarry Smith MPI_Comm comm = vobj->comm; 1083*17ab2063SBarry Smith int header[4],numtid,*rowlengths = 0,M,N; 1084*17ab2063SBarry Smith int shift; 1085*17ab2063SBarry Smith 1086*17ab2063SBarry Smith MPI_Comm_size(comm,&numtid); 1087*17ab2063SBarry Smith if (numtid > 1) SETERRQ(1,"MatLoad_SeqAIJ: view must have one processor"); 1088*17ab2063SBarry Smith ierr = ViewerFileGetDescriptor_Private(bview,&fd); CHKERRQ(ierr); 1089*17ab2063SBarry Smith ierr = SYRead(fd,(char *)header,4*sizeof(int),SYINT); CHKERRQ(ierr); 1090*17ab2063SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(1,"MatLoad_SeqAIJ: not matrix object"); 1091*17ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 1092*17ab2063SBarry Smith 1093*17ab2063SBarry Smith /* read in row lengths */ 1094*17ab2063SBarry Smith rowlengths = (int*) PETSCMALLOC( M*sizeof(int) ); CHKPTRQ(rowlengths); 1095*17ab2063SBarry Smith ierr = SYRead(fd,(char *)rowlengths,M*sizeof(int),SYINT); CHKERRQ(ierr); 1096*17ab2063SBarry Smith 1097*17ab2063SBarry Smith /* create our matrix */ 1098*17ab2063SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,newmat); CHKERRQ(ierr); 1099*17ab2063SBarry Smith mat = *newmat; 1100*17ab2063SBarry Smith aij = (Mat_SeqAIJ *) mat->data; 1101*17ab2063SBarry Smith shift = aij->indexshift; 1102*17ab2063SBarry Smith 1103*17ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 1104*17ab2063SBarry Smith ierr = SYRead(fd,(char *)aij->j,nz*sizeof(int),SYINT); CHKERRQ(ierr); 1105*17ab2063SBarry Smith if (shift) { 1106*17ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 1107*17ab2063SBarry Smith aij->j[i] += 1; 1108*17ab2063SBarry Smith } 1109*17ab2063SBarry Smith } 1110*17ab2063SBarry Smith 1111*17ab2063SBarry Smith /* read in nonzero values */ 1112*17ab2063SBarry Smith ierr = SYRead(fd,(char *)aij->a,nz*sizeof(Scalar),SYSCALAR); CHKERRQ(ierr); 1113*17ab2063SBarry Smith 1114*17ab2063SBarry Smith /* set matrix "i" values */ 1115*17ab2063SBarry Smith aij->i[0] = -shift; 1116*17ab2063SBarry Smith for ( i=1; i<= M; i++ ) { 1117*17ab2063SBarry Smith aij->i[i] = aij->i[i-1] + rowlengths[i-1]; 1118*17ab2063SBarry Smith aij->ilen[i-1] = rowlengths[i-1]; 1119*17ab2063SBarry Smith } 1120*17ab2063SBarry Smith PETSCFREE(rowlengths); 1121*17ab2063SBarry Smith 1122*17ab2063SBarry Smith ierr = MatAssemblyBegin(mat,FINAL_ASSEMBLY); CHKERRQ(ierr); 1123*17ab2063SBarry Smith ierr = MatAssemblyEnd(mat,FINAL_ASSEMBLY); CHKERRQ(ierr); 1124*17ab2063SBarry Smith return 0; 1125*17ab2063SBarry Smith } 1126*17ab2063SBarry Smith 1127*17ab2063SBarry Smith 1128*17ab2063SBarry Smith 1129