#include "pargrid.h"
/*+ get_mat - Generate a sparse matrix from the given grid
Input Parameters:
grid - the given grid
ncomp - the number of components per grid point
procinfo - the usual procinfo stuff
Returns:
the sparse matrix
+*/
BSspmat *get_mat3d(par_grid *grid, BSprocinfo *procinfo)
{
BSspmat *A;
int i, j, k, l, m;
int count, ncomp, nonsym, positive;
point ***points = grid->points;
int *rp, *cval;
FLOAT *aval, fncomp, off_diag, sign;
ncomp = grid->ncomp;
nonsym = (!grid->symmetric);
positive = grid->positive;
/* allocate space for the sparse matrix */
rp = (int *) MALLOC((ncomp*grid->local_total+1)*sizeof(int));
cval = (int *) MALLOC((7*ncomp*ncomp*grid->local_total)*sizeof(int));
aval = (FLOAT *) MALLOC((7*ncomp*ncomp*grid->local_total)*sizeof(FLOAT));
grid->rp = rp;
grid->cval = cval;
grid->aval = aval;
/* ****************************************************** */
/* now put values in the matrix */
/* ****************************************************** */
fncomp = (FLOAT) ncomp;
off_diag = -(1.0/(6.0*fncomp));
count = 1;
rp[0] = 0;
sign = 1.0;
srand48((long)(11311));
for (i=1;i<grid->l_num_x+1;i++) {
for (j=1;j<grid->l_num_y+1;j++) {
for (k=1;k<grid->l_num_z+1;k++) {
for (l=0;l<ncomp;l++) {
rp[count] = rp[count-1];
/* diagonal, set the column number, the nonzero values */
/* and increment the length of the row */
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i][j][k].num+m;
if(m==l) {
/* various diag possibilities for testing */
aval[rp[count]] = sign*(m+l+1)*fncomp;
aval[rp[count]] = sign*fncomp;
aval[rp[count]] = fncomp + drand48();
aval[rp[count]] = fncomp;
sign *= -1.0;
} else {
if(nonsym) {
if(l<m)
aval[rp[count]] = -1.5;
else
aval[rp[count]] = -0.5;
} else
aval[rp[count]] = -1.0;
}
rp[count]++;
}
/* east */
if (points[i+1][j][k].num >= 0) {
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i+1][j][k].num+m;
if(nonsym)
aval[rp[count]] = (1.0/(12.0*fncomp));
else
aval[rp[count]] = off_diag;
rp[count]++;
}
}
/* west */
if (points[i-1][j][k].num >= 0) {
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i-1][j][k].num+m;
if(nonsym)
aval[rp[count]] = -(1.0/(3.0*fncomp));
else
aval[rp[count]] = off_diag;
rp[count]++;
}
}
/* north */
if (points[i][j+1][k].num >= 0) {
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i][j+1][k].num+m;
aval[rp[count]] = off_diag;
rp[count]++;
}
}
/* south */
if (points[i][j-1][k].num >= 0) {
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i][j-1][k].num+m;
aval[rp[count]] = off_diag;
rp[count]++;
}
}
/* up */
if (points[i][j][k+1].num >= 0) {
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i][j][k+1].num+m;
aval[rp[count]] = off_diag;
rp[count]++;
}
}
/* down */
if (points[i][j][k-1].num >= 0) {
for (m=0;m<ncomp;m++) {
cval[rp[count]] = ncomp*points[i][j][k-1].num+m;
aval[rp[count]] = off_diag;
rp[count]++;
}
}
/* take abs value if positive matrix requested */
if(positive) {
for (m=rp[count-1];m<rp[count];m++) {
aval[m]=fabs(aval[m]);
}
}
/* sort the values in this row */
BSheap_sort1d(rp[count]-rp[count-1],&(cval[rp[count-1]]),
&(aval[rp[count-1]])); CHKERRN(0);
count++;
}
}
}
}
A = BSeasy_A(ncomp*grid->offset,ncomp*grid->local_total,
rp,cval,aval,procinfo);
CHKERRN(0);
return(A);
}
syntax highlighted by Code2HTML, v. 0.9.1