1*8a729477SBarry Smith 2*8a729477SBarry Smith #include "aij.h" 3*8a729477SBarry Smith #include "vec/vecimpl.h" 4*8a729477SBarry Smith #include "inline/spops.h" 5*8a729477SBarry Smith 6*8a729477SBarry Smith int SpToSymmetricIJ(Matiaij*,int**,int**); 7*8a729477SBarry Smith int SpOrderND(int,int*,int*,int*); 8*8a729477SBarry Smith int SpOrder1WD(int,int*,int*,int*); 9*8a729477SBarry Smith int SpOrderQMD(int,int*,int*,int*); 10*8a729477SBarry Smith int SpOrderRCM(int,int*,int*,int*); 11*8a729477SBarry Smith 12*8a729477SBarry Smith static int MatAIJreorder(Mat mat,int type,IS *rperm, IS *cperm) 13*8a729477SBarry Smith { 14*8a729477SBarry Smith Matiaij *aij = (Matiaij *) mat->data; 15*8a729477SBarry Smith int i, ierr, *ia, *ja, *perma; 16*8a729477SBarry Smith 17*8a729477SBarry Smith perma = (int *) MALLOC( aij->n*sizeof(int) ); CHKPTR(perma); 18*8a729477SBarry Smith 19*8a729477SBarry Smith if (ierr = SpToSymmetricIJ( aij, &ia, &ja )) SETERR(ierr,0); 20*8a729477SBarry Smith 21*8a729477SBarry Smith if (type == ORDER_NATURAL) { 22*8a729477SBarry Smith for ( i=0; i<aij->n; i++ ) perma[i] = i; 23*8a729477SBarry Smith } 24*8a729477SBarry Smith else if (type == ORDER_ND) { 25*8a729477SBarry Smith ierr = SpOrderND( aij->n, ia, ja, perma ); 26*8a729477SBarry Smith } 27*8a729477SBarry Smith else if (type == ORDER_1WD) { 28*8a729477SBarry Smith ierr = SpOrder1WD( aij->n, ia, ja, perma ); 29*8a729477SBarry Smith } 30*8a729477SBarry Smith else if (type == ORDER_RCM) { 31*8a729477SBarry Smith ierr = SpOrderRCM( aij->n, ia, ja, perma ); 32*8a729477SBarry Smith } 33*8a729477SBarry Smith else if (type == ORDER_QMD) { 34*8a729477SBarry Smith ierr = SpOrderQMD( aij->n, ia, ja, perma ); 35*8a729477SBarry Smith } 36*8a729477SBarry Smith else SETERR(1,"Cannot performing ordering requested"); 37*8a729477SBarry Smith if (ierr) SETERR(ierr,0); 38*8a729477SBarry Smith FREE(ia); FREE(ja); 39*8a729477SBarry Smith 40*8a729477SBarry Smith if (ierr = ISCreateSequential(aij->n,perma,rperm)) SETERR(ierr,0); 41*8a729477SBarry Smith ISSetPermutation(*rperm); 42*8a729477SBarry Smith FREE(perma); 43*8a729477SBarry Smith *cperm = *rperm; /* so far all permutations are symmetric.*/ 44*8a729477SBarry Smith return 0; 45*8a729477SBarry Smith } 46*8a729477SBarry Smith 47*8a729477SBarry Smith 48*8a729477SBarry Smith #define CHUNCKSIZE 5 49*8a729477SBarry Smith 50*8a729477SBarry Smith /* This version has row oriented v */ 51*8a729477SBarry Smith static int MatiAIJAddValues(Mat matin,Scalar *v,int m,int *idxm,int n, 52*8a729477SBarry Smith int *idxn) 53*8a729477SBarry Smith { 54*8a729477SBarry Smith Matiaij *mat = (Matiaij *) matin->data; 55*8a729477SBarry Smith int *rp,k,a,b,t,ii,row,nrow,i,col,l,rmax, N, sorted = mat->sorted; 56*8a729477SBarry Smith int *imax = mat->imax, *ai = mat->i, *ailen = mat->ilen; 57*8a729477SBarry Smith int *aj = mat->j, nonew = mat->nonew; 58*8a729477SBarry Smith Scalar *ap,value, *aa = mat->a; 59*8a729477SBarry Smith 60*8a729477SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 61*8a729477SBarry Smith row = idxm[k]; rp = aj + ai[row] - 1; ap = aa + ai[row] - 1; 62*8a729477SBarry Smith rmax = imax[row]; nrow = ailen[row]; 63*8a729477SBarry Smith a = 0; 64*8a729477SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 65*8a729477SBarry Smith col = idxn[l] + 1; value = *v++; 66*8a729477SBarry Smith if (nrow) { 67*8a729477SBarry Smith if (!sorted) a = 0; b = nrow; 68*8a729477SBarry Smith while (b-a > 5) { 69*8a729477SBarry Smith t = (b+a)/2; 70*8a729477SBarry Smith if (rp[t] > col) b = t; 71*8a729477SBarry Smith else a = t; 72*8a729477SBarry Smith } 73*8a729477SBarry Smith for ( i=a; i<b; i++ ) { 74*8a729477SBarry Smith if (rp[i] > col) break; 75*8a729477SBarry Smith if (rp[i] == col) {ap[i] += value; goto noinsert;} 76*8a729477SBarry Smith } 77*8a729477SBarry Smith if (nonew) goto noinsert; 78*8a729477SBarry Smith if (nrow >= rmax) { 79*8a729477SBarry Smith /* there is no extra room in row, therefore enlarge */ 80*8a729477SBarry Smith int new_nz = ai[mat->m] + CHUNCKSIZE,len,*new_i,*new_j; 81*8a729477SBarry Smith Scalar *new_a; 82*8a729477SBarry Smith fprintf(stderr,"Warning, enlarging matrix storage \n"); 83*8a729477SBarry Smith 84*8a729477SBarry Smith /* malloc new storage space */ 85*8a729477SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(mat->m+1)*sizeof(int); 86*8a729477SBarry Smith new_a = (Scalar *) MALLOC( len ); CHKPTR(new_a); 87*8a729477SBarry Smith new_j = (int *) (new_a + new_nz); 88*8a729477SBarry Smith new_i = new_j + new_nz; 89*8a729477SBarry Smith 90*8a729477SBarry Smith /* copy over old data into new slots */ 91*8a729477SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 92*8a729477SBarry Smith for ( ii=row+1; ii<mat->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNCKSIZE;} 93*8a729477SBarry Smith MEMCPY(new_j,aj,(ai[row]+nrow-1)*sizeof(int)); 94*8a729477SBarry Smith len = (new_nz - CHUNCKSIZE - ai[row] - nrow + 1); 95*8a729477SBarry Smith MEMCPY(new_j+ai[row]-1+nrow+CHUNCKSIZE,aj+ai[row]-1+nrow, 96*8a729477SBarry Smith len*sizeof(int)); 97*8a729477SBarry Smith MEMCPY(new_a,aa,(ai[row]+nrow-1)*sizeof(Scalar)); 98*8a729477SBarry Smith MEMCPY(new_a+ai[row]-1+nrow+CHUNCKSIZE,aa+ai[row]-1+nrow, 99*8a729477SBarry Smith len*sizeof(Scalar)); 100*8a729477SBarry Smith /* free up old matrix storage */ 101*8a729477SBarry Smith FREE(mat->a); if (!mat->singlemalloc) {FREE(mat->i);FREE(mat->j);} 102*8a729477SBarry Smith aa = mat->a = new_a; ai = mat->i = new_i; aj = mat->j = new_j; 103*8a729477SBarry Smith mat->singlemalloc = 1; 104*8a729477SBarry Smith 105*8a729477SBarry Smith rp = aj + ai[row] - 1; ap = aa + ai[row] - 1; 106*8a729477SBarry Smith rmax = imax[row] = imax[row] + CHUNCKSIZE; 107*8a729477SBarry Smith mat->mem += CHUNCKSIZE*(sizeof(int) + sizeof(Scalar)); 108*8a729477SBarry Smith } 109*8a729477SBarry Smith N = nrow++ - 1; mat->nz++; 110*8a729477SBarry Smith /* this has too many shifts here; but alternative was slower*/ 111*8a729477SBarry Smith for ( ii=N; ii>=i; ii-- ) {/* shift values up*/ 112*8a729477SBarry Smith rp[ii+1] = rp[ii]; 113*8a729477SBarry Smith ap[ii+1] = ap[ii]; 114*8a729477SBarry Smith } 115*8a729477SBarry Smith rp[i] = col; 116*8a729477SBarry Smith ap[i] = value; 117*8a729477SBarry Smith noinsert:; 118*8a729477SBarry Smith a = i + 1; 119*8a729477SBarry Smith } 120*8a729477SBarry Smith else { 121*8a729477SBarry Smith ap[0] = value; rp[0] = col; nrow++; a = 1; 122*8a729477SBarry Smith } 123*8a729477SBarry Smith } 124*8a729477SBarry Smith ailen[row] = nrow; 125*8a729477SBarry Smith } 126*8a729477SBarry Smith return 0; 127*8a729477SBarry Smith } 128*8a729477SBarry Smith 129*8a729477SBarry Smith static int MatiAIJview(PetscObject obj,Viewer ptr) 130*8a729477SBarry Smith { 131*8a729477SBarry Smith Mat aijin = (Mat) obj; 132*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 133*8a729477SBarry Smith int i,j; 134*8a729477SBarry Smith for ( i=0; i<aij->m; i++ ) { 135*8a729477SBarry Smith printf("row %d:",i); 136*8a729477SBarry Smith for ( j=aij->i[i]-1; j<aij->i[i+1]-1; j++ ) { 137*8a729477SBarry Smith #if defined(PETSC_COMPLEX) 138*8a729477SBarry Smith printf(" %d %g + %g i",aij->j[j]-1,real(aij->a[j]),imag(aij->a[j])); 139*8a729477SBarry Smith #else 140*8a729477SBarry Smith printf(" %d %g ",aij->j[j]-1,aij->a[j]); 141*8a729477SBarry Smith #endif 142*8a729477SBarry Smith } 143*8a729477SBarry Smith printf("\n"); 144*8a729477SBarry Smith } 145*8a729477SBarry Smith return 0; 146*8a729477SBarry Smith } 147*8a729477SBarry Smith 148*8a729477SBarry Smith static int MatiAIJEndAssemble(Mat aijin) 149*8a729477SBarry Smith { 150*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 151*8a729477SBarry Smith int shift = 0,i,j,*ai = aij->i, *aj = aij->j, *imax = aij->imax; 152*8a729477SBarry Smith int m = aij->m, *ip, N, *ailen = aij->ilen; 153*8a729477SBarry Smith Scalar *a = aij->a, *ap; 154*8a729477SBarry Smith 155*8a729477SBarry Smith for ( i=1; i<m; i++ ) { 156*8a729477SBarry Smith shift += imax[i-1] - ailen[i-1]; 157*8a729477SBarry Smith if (shift) { 158*8a729477SBarry Smith ip = aj + ai[i] - 1; ap = a + ai[i] - 1; 159*8a729477SBarry Smith N = ailen[i]; 160*8a729477SBarry Smith for ( j=0; j<N; j++ ) { 161*8a729477SBarry Smith ip[j-shift] = ip[j]; 162*8a729477SBarry Smith ap[j-shift] = ap[j]; 163*8a729477SBarry Smith } 164*8a729477SBarry Smith } 165*8a729477SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 166*8a729477SBarry Smith } 167*8a729477SBarry Smith shift += imax[m-1] - ailen[m-1]; 168*8a729477SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 169*8a729477SBarry Smith FREE(aij->imax); 170*8a729477SBarry Smith FREE(aij->ilen); 171*8a729477SBarry Smith aij->mem -= 2*(aij->m)*sizeof(int); 172*8a729477SBarry Smith return 0; 173*8a729477SBarry Smith } 174*8a729477SBarry Smith 175*8a729477SBarry Smith static int MatiAIJzeroentries(Mat mat) 176*8a729477SBarry Smith { 177*8a729477SBarry Smith Matiaij *aij = (Matiaij *) mat->data; 178*8a729477SBarry Smith Scalar *a = aij->a; 179*8a729477SBarry Smith int i,n = aij->i[aij->m]-1; 180*8a729477SBarry Smith for ( i=0; i<n; i++ ) a[i] = 0.0; 181*8a729477SBarry Smith return 0; 182*8a729477SBarry Smith 183*8a729477SBarry Smith } 184*8a729477SBarry Smith static int MatiAIJdestroy(PetscObject obj) 185*8a729477SBarry Smith { 186*8a729477SBarry Smith Mat mat = (Mat) obj; 187*8a729477SBarry Smith Matiaij *aij = (Matiaij *) mat->data; 188*8a729477SBarry Smith FREE(aij->a); 189*8a729477SBarry Smith if (!aij->singlemalloc) {FREE(aij->i); FREE(aij->j);} 190*8a729477SBarry Smith FREE(aij); FREE(mat); 191*8a729477SBarry Smith return 0; 192*8a729477SBarry Smith } 193*8a729477SBarry Smith 194*8a729477SBarry Smith static int MatiAIJCompress(Mat aijin) 195*8a729477SBarry Smith { 196*8a729477SBarry Smith return 0; 197*8a729477SBarry Smith } 198*8a729477SBarry Smith 199*8a729477SBarry Smith static int MatiAIJinsopt(Mat aijin,int op) 200*8a729477SBarry Smith { 201*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 202*8a729477SBarry Smith if (op == ROW_ORIENTED) aij->roworiented = 1; 203*8a729477SBarry Smith else if (op == COLUMN_ORIENTED) aij->roworiented = 0; 204*8a729477SBarry Smith else if (op == COLUMNS_SORTED) aij->sorted = 1; 205*8a729477SBarry Smith /* doesn't care about sorted rows */ 206*8a729477SBarry Smith else if (op == NO_NEW_NONZERO_LOCATIONS) aij->nonew = 1; 207*8a729477SBarry Smith else if (op == YES_NEW_NONZERO_LOCATIONS) aij->nonew = 0; 208*8a729477SBarry Smith 209*8a729477SBarry Smith if (op == COLUMN_ORIENTED) SETERR(1,"Column oriented input not supported"); 210*8a729477SBarry Smith return 0; 211*8a729477SBarry Smith } 212*8a729477SBarry Smith 213*8a729477SBarry Smith static int MatiAIJgetdiag(Mat aijin,Vec v) 214*8a729477SBarry Smith { 215*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 216*8a729477SBarry Smith int i,j, n; 217*8a729477SBarry Smith Scalar *x, zero = 0.0; 218*8a729477SBarry Smith CHKTYPE(v,SEQVECTOR); 219*8a729477SBarry Smith VecSet(&zero,v); 220*8a729477SBarry Smith VecGetArray(v,&x); VecGetSize(v,&n); 221*8a729477SBarry Smith if (n != aij->m) SETERR(1,"Nonconforming matrix and vector"); 222*8a729477SBarry Smith for ( i=0; i<aij->m; i++ ) { 223*8a729477SBarry Smith for ( j=aij->i[i]-1; j<aij->i[i+1]-1; j++ ) { 224*8a729477SBarry Smith if (aij->j[j]-1 == i) { 225*8a729477SBarry Smith x[i] = aij->a[j]; 226*8a729477SBarry Smith break; 227*8a729477SBarry Smith } 228*8a729477SBarry Smith } 229*8a729477SBarry Smith } 230*8a729477SBarry Smith return 0; 231*8a729477SBarry Smith } 232*8a729477SBarry Smith 233*8a729477SBarry Smith /* -------------------------------------------------------*/ 234*8a729477SBarry Smith /* Should check that shapes of vectors and matrices match */ 235*8a729477SBarry Smith /* -------------------------------------------------------*/ 236*8a729477SBarry Smith static int MatiAIJmulttrans(Mat aijin,Vec xx,Vec yy) 237*8a729477SBarry Smith { 238*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 239*8a729477SBarry Smith Scalar *x, *y, *v, alpha; 240*8a729477SBarry Smith int m = aij->m, n, i, *idx; 241*8a729477SBarry Smith CHKTYPE(xx,SEQVECTOR);CHKTYPE(yy,SEQVECTOR); 242*8a729477SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 243*8a729477SBarry Smith MEMSET(y,0,aij->n*sizeof(Scalar)); 244*8a729477SBarry Smith y--; /* shift for Fortran start by 1 indexing */ 245*8a729477SBarry Smith for ( i=0; i<m; i++ ) { 246*8a729477SBarry Smith idx = aij->j + aij->i[i] - 1; 247*8a729477SBarry Smith v = aij->a + aij->i[i] - 1; 248*8a729477SBarry Smith n = aij->i[i+1] - aij->i[i]; 249*8a729477SBarry Smith alpha = x[i]; 250*8a729477SBarry Smith /* should inline */ 251*8a729477SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 252*8a729477SBarry Smith } 253*8a729477SBarry Smith return 0; 254*8a729477SBarry Smith } 255*8a729477SBarry Smith static int MatiAIJmulttransadd(Mat aijin,Vec xx,Vec zz,Vec yy) 256*8a729477SBarry Smith { 257*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 258*8a729477SBarry Smith Scalar *x, *y, *z, *v, alpha; 259*8a729477SBarry Smith int m = aij->m, n, i, *idx; 260*8a729477SBarry Smith CHKTYPE(xx,SEQVECTOR);CHKTYPE(yy,SEQVECTOR); 261*8a729477SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 262*8a729477SBarry Smith if (zz != yy) VecCopy(zz,yy); 263*8a729477SBarry Smith y--; /* shift for Fortran start by 1 indexing */ 264*8a729477SBarry Smith for ( i=0; i<m; i++ ) { 265*8a729477SBarry Smith idx = aij->j + aij->i[i] - 1; 266*8a729477SBarry Smith v = aij->a + aij->i[i] - 1; 267*8a729477SBarry Smith n = aij->i[i+1] - aij->i[i]; 268*8a729477SBarry Smith alpha = x[i]; 269*8a729477SBarry Smith /* should inline */ 270*8a729477SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 271*8a729477SBarry Smith } 272*8a729477SBarry Smith return 0; 273*8a729477SBarry Smith } 274*8a729477SBarry Smith 275*8a729477SBarry Smith static int MatiAIJmult(Mat aijin,Vec xx,Vec yy) 276*8a729477SBarry Smith { 277*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 278*8a729477SBarry Smith Scalar *x, *y, *v, sum; 279*8a729477SBarry Smith int m = aij->m, n, i, *idx; 280*8a729477SBarry Smith CHKTYPE(xx,SEQVECTOR);CHKTYPE(yy,SEQVECTOR); 281*8a729477SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); 282*8a729477SBarry Smith x--; /* shift for Fortran start by 1 indexing */ 283*8a729477SBarry Smith for ( i=0; i<m; i++ ) { 284*8a729477SBarry Smith idx = aij->j + aij->i[i] - 1; 285*8a729477SBarry Smith v = aij->a + aij->i[i] - 1; 286*8a729477SBarry Smith n = aij->i[i+1] - aij->i[i]; 287*8a729477SBarry Smith sum = 0.0; 288*8a729477SBarry Smith SPARSEDENSEDOT(sum,x,v,idx,n); 289*8a729477SBarry Smith y[i] = sum; 290*8a729477SBarry Smith } 291*8a729477SBarry Smith return 0; 292*8a729477SBarry Smith } 293*8a729477SBarry Smith 294*8a729477SBarry Smith static int MatiAIJmultadd(Mat aijin,Vec xx,Vec yy,Vec zz) 295*8a729477SBarry Smith { 296*8a729477SBarry Smith Matiaij *aij = (Matiaij *) aijin->data; 297*8a729477SBarry Smith Scalar *x, *y, *z, *v, sum; 298*8a729477SBarry Smith int m = aij->m, n, i, *idx; 299*8a729477SBarry Smith CHKTYPE(xx,SEQVECTOR);CHKTYPE(yy,SEQVECTOR); CHKTYPE(zz,SEQVECTOR); 300*8a729477SBarry Smith VecGetArray(xx,&x); VecGetArray(yy,&y); VecGetArray(zz,&z); 301*8a729477SBarry Smith x--; /* shift for Fortran start by 1 indexing */ 302*8a729477SBarry Smith for ( i=0; i<m; i++ ) { 303*8a729477SBarry Smith idx = aij->j + aij->i[i] - 1; 304*8a729477SBarry Smith v = aij->a + aij->i[i] - 1; 305*8a729477SBarry Smith n = aij->i[i+1] - aij->i[i]; 306*8a729477SBarry Smith sum = y[i]; 307*8a729477SBarry Smith SPARSEDENSEDOT(sum,x,v,idx,n); 308*8a729477SBarry Smith y[i] = sum; 309*8a729477SBarry Smith } 310*8a729477SBarry Smith return 0; 311*8a729477SBarry Smith } 312*8a729477SBarry Smith 313*8a729477SBarry Smith /* 314*8a729477SBarry Smith Adds diagonal pointers to sparse matrix structure. 315*8a729477SBarry Smith */ 316*8a729477SBarry Smith 317*8a729477SBarry Smith static int MatiAIJmarkdiag(Matiaij *aij) 318*8a729477SBarry Smith { 319*8a729477SBarry Smith int i,j, n, *diag;; 320*8a729477SBarry Smith diag = (int *) MALLOC( aij->m*sizeof(int)); CHKPTR(diag); 321*8a729477SBarry Smith for ( i=0; i<aij->m; i++ ) { 322*8a729477SBarry Smith for ( j=aij->i[i]-1; j<aij->i[i+1]-1; j++ ) { 323*8a729477SBarry Smith if (aij->j[j]-1 == i) { 324*8a729477SBarry Smith diag[i] = j + 1; 325*8a729477SBarry Smith break; 326*8a729477SBarry Smith } 327*8a729477SBarry Smith } 328*8a729477SBarry Smith } 329*8a729477SBarry Smith aij->diag = diag; 330*8a729477SBarry Smith return 0; 331*8a729477SBarry Smith } 332*8a729477SBarry Smith 333*8a729477SBarry Smith static int MatiAIJrelax(Mat matin,Vec bb,double omega,int flag,IS is, 334*8a729477SBarry Smith int its,Vec xx) 335*8a729477SBarry Smith { 336*8a729477SBarry Smith Matiaij *mat = (Matiaij *) matin->data; 337*8a729477SBarry Smith Scalar *x, *b, zero = 0.0, d, *xs, sum, *v = mat->a; 338*8a729477SBarry Smith int ierr,one = 1, tmp, *idx, *diag; 339*8a729477SBarry Smith int n = mat->n, m = mat->m, i, j; 340*8a729477SBarry Smith 341*8a729477SBarry Smith if (is) SETERR(1,"No support for ordering in relaxation"); 342*8a729477SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 343*8a729477SBarry Smith if (ierr = VecSet(&zero,xx)) return ierr; 344*8a729477SBarry Smith } 345*8a729477SBarry Smith VecGetArray(xx,&x); VecGetArray(bb,&b); 346*8a729477SBarry Smith if (!mat->diag) {if (ierr = MatiAIJmarkdiag(mat)) return ierr;} 347*8a729477SBarry Smith diag = mat->diag; 348*8a729477SBarry Smith xs = x - 1; /* shifted by one for index start of a or mat->j*/ 349*8a729477SBarry Smith while (its--) { 350*8a729477SBarry Smith if (flag & SOR_FORWARD_SWEEP){ 351*8a729477SBarry Smith for ( i=0; i<m; i++ ) { 352*8a729477SBarry Smith d = mat->a[diag[i]-1]; 353*8a729477SBarry Smith n = mat->i[i+1] - mat->i[i]; 354*8a729477SBarry Smith idx = mat->j + mat->i[i] - 1; 355*8a729477SBarry Smith v = mat->a + mat->i[i] - 1; 356*8a729477SBarry Smith sum = b[i]; 357*8a729477SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 358*8a729477SBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum/d + x[i]); 359*8a729477SBarry Smith } 360*8a729477SBarry Smith } 361*8a729477SBarry Smith if (flag & SOR_BACKWARD_SWEEP){ 362*8a729477SBarry Smith for ( i=m-1; i>=0; i-- ) { 363*8a729477SBarry Smith d = mat->a[diag[i] - 1]; 364*8a729477SBarry Smith n = mat->i[i+1] - mat->i[i]; 365*8a729477SBarry Smith idx = mat->j + mat->i[i] - 1; 366*8a729477SBarry Smith v = mat->a + mat->i[i] - 1; 367*8a729477SBarry Smith sum = b[i]; 368*8a729477SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 369*8a729477SBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum/d + x[i]); 370*8a729477SBarry Smith } 371*8a729477SBarry Smith } 372*8a729477SBarry Smith } 373*8a729477SBarry Smith return 0; 374*8a729477SBarry Smith } 375*8a729477SBarry Smith 376*8a729477SBarry Smith static int MatiAIJnz(Mat matin,int *nz) 377*8a729477SBarry Smith { 378*8a729477SBarry Smith Matiaij *mat = (Matiaij *) matin->data; 379*8a729477SBarry Smith *nz = mat->nz; 380*8a729477SBarry Smith return 0; 381*8a729477SBarry Smith } 382*8a729477SBarry Smith static int MatiAIJmem(Mat matin,int *nz) 383*8a729477SBarry Smith { 384*8a729477SBarry Smith Matiaij *mat = (Matiaij *) matin->data; 385*8a729477SBarry Smith *nz = mat->mem; 386*8a729477SBarry Smith return 0; 387*8a729477SBarry Smith } 388*8a729477SBarry Smith 389*8a729477SBarry Smith int MatiAIJLUFactorSymbolic(Mat,IS,IS,Mat*); 390*8a729477SBarry Smith int MatiAIJLUFactorNumeric(Mat,Mat); 391*8a729477SBarry Smith int MatiAIJSolve(Mat,Vec,Vec); 392*8a729477SBarry Smith 393*8a729477SBarry Smith /* -------------------------------------------------------------------*/ 394*8a729477SBarry Smith static struct _MatOps MatOps = {MatiAIJAddValues,MatiAIJAddValues, 395*8a729477SBarry Smith 0, 0, 396*8a729477SBarry Smith MatiAIJmult,MatiAIJmultadd,MatiAIJmulttrans,MatiAIJmulttransadd, 397*8a729477SBarry Smith MatiAIJSolve,0,0,0, 398*8a729477SBarry Smith 0,0, 399*8a729477SBarry Smith MatiAIJrelax, 400*8a729477SBarry Smith 0, 401*8a729477SBarry Smith MatiAIJnz,MatiAIJmem,0, 402*8a729477SBarry Smith 0, 403*8a729477SBarry Smith MatiAIJgetdiag,0,0, 404*8a729477SBarry Smith 0,MatiAIJEndAssemble, 405*8a729477SBarry Smith MatiAIJCompress, 406*8a729477SBarry Smith MatiAIJinsopt,MatiAIJzeroentries,0,MatAIJreorder, 407*8a729477SBarry Smith MatiAIJLUFactorSymbolic,MatiAIJLUFactorNumeric,0,0 }; 408*8a729477SBarry Smith 409*8a729477SBarry Smith 410*8a729477SBarry Smith 411*8a729477SBarry Smith /*@ 412*8a729477SBarry Smith 413*8a729477SBarry Smith MatCreateSequentialAIJ - Creates a sparse matrix in AIJ format. 414*8a729477SBarry Smith 415*8a729477SBarry Smith Input Parameters: 416*8a729477SBarry Smith . m,n - number of rows and columns 417*8a729477SBarry Smith . nz - total number nonzeros in matrix 418*8a729477SBarry Smith . nzz - number of nonzeros per row or null 419*8a729477SBarry Smith . You must leave room for the diagonal entry even if it is zero. 420*8a729477SBarry Smith 421*8a729477SBarry Smith Output parameters: 422*8a729477SBarry Smith . newmat - the matrix 423*8a729477SBarry Smith 424*8a729477SBarry Smith Keywords: matrix, aij, compressed row, sparse 425*8a729477SBarry Smith @*/ 426*8a729477SBarry Smith int MatCreateSequentialAIJ(int m,int n,int nz,int *nnz, Mat *newmat) 427*8a729477SBarry Smith { 428*8a729477SBarry Smith Mat mat; 429*8a729477SBarry Smith Matiaij *aij; 430*8a729477SBarry Smith int i,rl,len; 431*8a729477SBarry Smith *newmat = 0; 432*8a729477SBarry Smith CREATEHEADER(mat,_Mat); 433*8a729477SBarry Smith mat->data = (void *) (aij = NEW(Matiaij)); CHKPTR(aij); 434*8a729477SBarry Smith mat->cookie = MAT_COOKIE; 435*8a729477SBarry Smith mat->ops = &MatOps; 436*8a729477SBarry Smith mat->destroy = MatiAIJdestroy; 437*8a729477SBarry Smith mat->view = MatiAIJview; 438*8a729477SBarry Smith mat->type = MATAIJSEQ; 439*8a729477SBarry Smith mat->factor = 0; 440*8a729477SBarry Smith mat->row = 0; 441*8a729477SBarry Smith mat->col = 0; 442*8a729477SBarry Smith aij->m = m; 443*8a729477SBarry Smith aij->n = n; 444*8a729477SBarry Smith aij->imax = (int *) MALLOC( m*sizeof(int) ); CHKPTR(aij->imax); 445*8a729477SBarry Smith aij->mem = m*sizeof(int) + sizeof(Matiaij); 446*8a729477SBarry Smith if (!nnz) { 447*8a729477SBarry Smith if (nz <= 0) nz = 1; 448*8a729477SBarry Smith for ( i=0; i<m; i++ ) aij->imax[i] = nz; 449*8a729477SBarry Smith nz = nz*m; 450*8a729477SBarry Smith } 451*8a729477SBarry Smith else { 452*8a729477SBarry Smith nz = 0; 453*8a729477SBarry Smith for ( i=0; i<m; i++ ) {aij->imax[i] = nnz[i]; nz += nnz[i];} 454*8a729477SBarry Smith } 455*8a729477SBarry Smith 456*8a729477SBarry Smith /* allocate the matrix space */ 457*8a729477SBarry Smith aij->nz = nz; 458*8a729477SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (aij->m+1)*sizeof(int); 459*8a729477SBarry Smith aij->a = (Scalar *) MALLOC( len ); CHKPTR(aij->a); 460*8a729477SBarry Smith aij->j = (int *) (aij->a + nz); 461*8a729477SBarry Smith aij->i = aij->j + nz; 462*8a729477SBarry Smith aij->singlemalloc = 1; 463*8a729477SBarry Smith aij->mem += len; 464*8a729477SBarry Smith 465*8a729477SBarry Smith aij->i[0] = 1; 466*8a729477SBarry Smith for (i=1; i<m+1; i++) { 467*8a729477SBarry Smith aij->i[i] = aij->i[i-1] + aij->imax[i-1]; 468*8a729477SBarry Smith } 469*8a729477SBarry Smith 470*8a729477SBarry Smith /* aij->ilen will count nonzeros in each row so far. */ 471*8a729477SBarry Smith aij->ilen = (int *) MALLOC((aij->m)*sizeof(int)); 472*8a729477SBarry Smith 473*8a729477SBarry Smith /* stick in zeros along diagonal */ 474*8a729477SBarry Smith for ( i=0; i<aij->m; i++ ) { 475*8a729477SBarry Smith aij->ilen[i] = 1; 476*8a729477SBarry Smith aij->j[aij->i[i]-1] = i+1; 477*8a729477SBarry Smith aij->a[aij->i[i]-1] = 0.0; 478*8a729477SBarry Smith } 479*8a729477SBarry Smith aij->nz = aij->m; 480*8a729477SBarry Smith aij->mem += (aij->m)*sizeof(int) + len; 481*8a729477SBarry Smith 482*8a729477SBarry Smith aij->sorted = 0; 483*8a729477SBarry Smith aij->roworiented = 1; 484*8a729477SBarry Smith aij->nonew = 0; 485*8a729477SBarry Smith aij->diag = 0; 486*8a729477SBarry Smith 487*8a729477SBarry Smith *newmat = mat; 488*8a729477SBarry Smith return 0; 489*8a729477SBarry Smith } 490