47 #ifdef HAVE_FEI_AZTECOO
58 #define AZTEC_MPI AZTEC_MPI
72 namespace fei_trilinos {
78 N_update_(map->getNumLocalBlocks()),
83 orderingUpdate_(NULL),
90 remoteBlockSizes_(NULL)
98 Amat_ = AZ_matrix_create(N_update_);
99 Amat_->matrix_type = AZ_VBR_MATRIX;
101 (void(*)(
double*,
double*,AZ_MATRIX_STRUCT*,
int*))AZ_VBR_matvec_mult;
112 N_update_(src.N_update_),
117 orderingUpdate_(NULL),
118 isLoaded_(src.isLoaded_),
119 isAllocated_(src.isAllocated_),
120 localNNZ_(src.localNNZ_),
124 remoteBlockSizes_(NULL)
141 nnzPerRow_[i] = src.nnzPerRow_[i];
144 Amat_ = AZ_matrix_create(N_update_);
145 Amat_->matrix_type = AZ_VBR_MATRIX;
147 (void(*)(
double*,
double*,AZ_MATRIX_STRUCT*,
int*))AZ_VBR_matvec_mult;
153 Amat_->bpntr =
new int[N_update_+1];
154 for(i=0; i<N_update_+1; i++) Amat_->bpntr[i] = src.Amat_->bpntr[i];
156 int totalNNZBlks = Amat_->bpntr[N_update_];
157 Amat_->bindx =
new int[totalNNZBlks];
158 for(i=0; i<totalNNZBlks; i++) Amat_->bindx[i] = src.Amat_->bindx[i];
160 Amat_->indx =
new int[totalNNZBlks+1];
161 for(i=0; i<totalNNZBlks+1; i++) Amat_->indx[i] = src.Amat_->indx[i];
163 Amat_->val =
new double[localNNZ_];
164 for(i=0; i<localNNZ_; i++) Amat_->val[i] = 0.0;
168 int dataOrgLength = src.data_org_[AZ_total_send] + AZ_send_list;
169 data_org_ = (
int*) AZ_allocate(dataOrgLength *
sizeof(
int));
170 for(i=0; i<dataOrgLength; i++) data_org_[i] = src.data_org_[i];
172 Amat_->data_org = data_org_;
174 int extLength = src.data_org_[AZ_N_ext_blk];
175 external_ = (
int*) AZ_allocate(extLength *
sizeof(
int));
176 extern_index_ = (
int*) AZ_allocate(extLength *
sizeof(
int));
177 for(i=0; i<extLength; i++) {
178 external_[i] = src.external_[i];
179 extern_index_[i] = src.extern_index_[i];
182 update_index_ = (
int*) AZ_allocate(N_update_ *
sizeof(
int));
185 update_index_[i] = src.update_index_[i];
186 orderingUpdate_[i] = src.orderingUpdate_[i];
189 int cpntrLength = N_update_ + src.data_org_[AZ_N_ext_blk] + 1;
190 Amat_->cpntr = (
int*) AZ_allocate(cpntrLength *
sizeof(
int));
191 for(i=0; i<cpntrLength; i++) Amat_->cpntr[i] = src.Amat_->cpntr[i];
199 delete []
Amat_->val;
200 delete []
Amat_->bindx;
201 delete []
Amat_->rpntr;
202 delete []
Amat_->bpntr;
203 delete []
Amat_->indx;
225 AZ_matrix_destroy(&
Amat_);
239 fei::console_out() <<
"AztecDVBR_Matrix::getNumBlocksPerRow: ERROR: blkRow "
240 << blkRow <<
" not in local update list." <<
FEI_ENDL;
244 nnzBlksPerRow =
Amat_->bpntr[index+1] -
Amat_->bpntr[index];
259 for(
int i=0; i<
amap_->getNumLocalBlocks(); i++) {
260 nnzBlksPerRow[i] =
Amat_->bpntr[i+1] -
Amat_->bpntr[i];
277 fei::console_out() <<
"AztecDVBR_Matrix::getNumNonzerosPerRow: ERROR: blkRow "
278 << blkRow <<
" not in local update list." <<
FEI_ENDL;
298 for(
int i=0; i<
amap_->getNumLocalBlocks(); i++) {
307 int& ptRows,
int& ptCols) {
315 << blkRow <<
" not in local update list." <<
FEI_ENDL;
319 ptRows =
Amat_->rpntr[index+1] -
Amat_->rpntr[index];
321 int local =
inUpdate(blkCol, index);
324 ptCols =
Amat_->rpntr[index+1] -
Amat_->rpntr[index];
329 if (index < 0)
return(1);
343 int *proc_config =
amap_->getProcConfig();
344 double *b = (
double*)x.startPointer();
345 double *c = (
double*)y.startPointer();
347 AZ_VBR_matvec_mult(b, c,
Amat_, proc_config);
368 int numNzBlks)
const {
376 << blkRow <<
" not in local update list." <<
FEI_ENDL;
386 int nnzBlks = 0, nnzPts = 0;
388 if (err)
return(err);
390 if (err)
return(err);
392 if (numNzBlks != nnzBlks)
return(1);
396 const int* blkUpdate =
amap_->getBlockUpdate();
397 for(
int indb =
Amat_->bpntr[index]; indb<Amat_->bpntr[index+1]; indb++) {
399 int numEntries =
Amat_->indx[indb+1] -
Amat_->indx[indb];
400 int valOffset =
Amat_->indx[indb];
403 int ind =
Amat_->bindx[indb];
404 if (ind < N_update_) {
412 blkColInds[blkCounter++] =
Amat_->bindx[indb];
416 for(
int i=0; i<numEntries; i++) {
417 val[offset + i] =
Amat_->val[valOffset + i];
420 offset += numEntries;
430 int numNzBlks)
const {
438 << blkRow <<
" not in local update list." <<
FEI_ENDL;
449 for(
int blk = 0; blk<numNzBlks; blk++) {
451 Amat_->bpntr[index],
Amat_->bpntr[index+1]-1);
453 if (indb < 0)
messageAbort(
"putBlockRow: blk col not found in row.");
455 int numEntries =
Amat_->indx[indb+1] -
Amat_->indx[indb];
456 int valOffset =
Amat_->indx[indb];
459 for(
int i=0; i<numEntries; i++) {
460 Amat_->val[valOffset + i] = val[offset + i];
463 offset += numEntries;
486 << blkRow <<
" not in local update list." <<
FEI_ENDL;
498 for(
int blk = 0; blk<numNzBlks; blk++) {
500 Amat_->bpntr[index],
Amat_->bpntr[index+1]-1);
504 << blkColInds[blk] <<
" not found in row " << blkRow <<
FEI_ENDL;
508 int numEntries =
Amat_->indx[indb+1] -
Amat_->indx[indb];
509 int valOffset =
Amat_->indx[indb];
512 for(
int i=0; i<numEntries; i++) {
513 Amat_->val[valOffset + i] += val[offset + i];
516 offset += numEntries;
538 setBindx(totalNumNzBlks, blkColInds);
570 MPI_Comm_rank(thisComm, &thisProc);
576 &(
Amat_->cpntr), AZ_VBR_MATRIX);
619 infile = fopen(filename,
"r");
620 if (!infile)
messageAbort(
"readFromFile: couldn't open file.");
622 int* num_nz_blocks = NULL;
623 int* blk_col_inds = NULL;
627 allocate(num_nz_blocks, blk_col_inds);
629 delete [] num_nz_blocks;
630 delete [] blk_col_inds;
633 infile = fopen(filename,
"r");
647 int*& blk_col_inds) {
658 if (num_nz_blocks)
delete [] num_nz_blocks;
659 if (blk_col_inds)
delete [] blk_col_inds;
666 int totalNumBlks = 0;
670 num_nz_blocks[i] = 0;
671 blkColInds[i] = NULL;
674 int blkRows, blkCols, rows, cols;
678 fgets(line,256,infile);
679 }
while(strchr(line,
'%'));
680 sscanf(line,
"%d %d %d %d",&blkRows, &blkCols, &rows, &cols);
682 if ((blkRows != blkCols) || (rows != cols))
683 messageAbort(
"readAllocateInfo: non-square matrix not allowed.");
685 int br, bc, pr, pc, index;
687 while (!feof(infile)) {
689 fgets(line,256,infile);
690 }
while(strchr(line,
'%'));
692 if(feof(infile))
break;
694 sscanf(line,
"%d %d %d %d", &br, &bc, &pr, &pc);
697 if ((bc < 0) || bc >= blkCols) {
699 sprintf(mesg,
"readAllocateInfo: blkCols %d, 0-based col ind %d",
704 insertList(bc, blkColInds[index], num_nz_blocks[index]);
711 blk_col_inds =
new int[totalNumBlks];
715 for(
int j=0; j<num_nz_blocks[i]; j++) {
716 blk_col_inds[offset++] = blkColInds[i][j];
719 delete [] blkColInds[i];
722 delete [] blkColInds;
728 int blkRows, blkCols, rows, cols;
729 int br, bc, pr, pc, nnz, index;
730 double* blockValues = NULL;
734 fgets(line,256,infile);
735 }
while(strchr(line,
'%'));
736 sscanf(line,
"%d %d %d %d",&blkRows, &blkCols, &rows, &cols);
738 while (!feof(infile)) {
740 fgets(line,256,infile);
741 }
while(strchr(line,
'%'));
743 if(feof(infile))
break;
745 sscanf(line,
"%d %d %d %d %d", &br, &bc, &pr, &pc, &nnz);
751 blockValues =
new double[nnz];
756 delete [] blockValues;
771 char *offset = &line[0];
773 offset = strchr(offset,
' ');
778 for(i=0; i<lenValues; i++){
779 sscanf(offset,
"%le",&(values[i]));
780 offset = strchr(offset,
' ');
790 int thisProc =
amap_->getProcConfig()[AZ_node];
794 int numGlobalBlocks =
amap_->getNumGlobalBlocks();
795 int numGlobalPtEqns =
amap_->globalSize();
809 file = fopen(fileName,
"w");
810 fprintf(file,
"%d %d %d %d\n", numGlobalBlocks, numGlobalBlocks,
811 numGlobalPtEqns, numGlobalPtEqns);
815 file = fopen(fileName,
"a");
827 for(
int brow=0; brow<numLocalBlocks; brow++) {
828 int bcolind1 =
Amat_->bpntr[brow];
829 int bcolind2 =
Amat_->bpntr[brow+1];
831 for(
int ind=bcolind1; ind<bcolind2; ind++) {
832 int nnzPts =
Amat_->indx[ind+1] -
Amat_->indx[ind];
834 if (nnzPts <= 0)
continue;
836 int blkRowSize =
Amat_->rpntr[brow+1]-
Amat_->rpntr[brow];
839 int lookup =
Amat_->bindx[ind];
841 if (lookup < N_update_) {
852 int globalRow =
amap_->getBlockUpdate()[brow];
855 fprintf(file,
"%d %d %d %d ", globalRow, globCol,
858 int offset =
Amat_->indx[ind];
859 for(
int i=0; i<nnzPts; i++) {
860 fprintf(file,
"%20.13e ",
Amat_->val[offset+i]);
882 localIndex = AZ_find_index(globalIndex,
amap_->getBlockUpdate(),
N_update_);
884 if(localIndex==-1)
return(0);
903 const int* blkSizes =
amap_->getBlockSizes();
905 Amat_->rpntr =
new int[N_update_+1];
910 Amat_->rpntr[i+1] =
Amat_->rpntr[i] + blkSizes[i];
925 Amat_->bpntr =
new int[N_update_+1];
930 Amat_->bpntr[i+1] =
Amat_->bpntr[i] + numNzBlks[i];
939 Amat_->bindx =
new int[nnzBlks];
941 for(
int i=0; i<nnzBlks; i++) {
942 Amat_->bindx[i] = blkColInds[i];
943 if (blkColInds[i] < 0)
965 Amat_->indx =
new int[nnzBlks+1];
972 int numProcs =
amap_->getProcConfig()[AZ_N_procs];
988 for(
int i=0; i<
amap_->getNumLocalBlocks(); i++) {
989 int rowBlkSize =
Amat_->rpntr[i+1] -
Amat_->rpntr[i];
991 int colStart =
Amat_->bpntr[i];
992 int colEnd =
Amat_->bpntr[i+1] - 1;
994 for(
int j=colStart; j<=colEnd; j++) {
996 int colBlkSize =
Amat_->rpntr[index+1] -
Amat_->rpntr[index];
998 Amat_->indx[j+1] =
Amat_->indx[j] + rowBlkSize*colBlkSize;
1001 if (numProcs == 1) {
1003 sprintf(mesg,
"calcIndx: blk col index %d not in update set.",
1015 messageAbort(
"calcIndx: block column index not found.");
1028 int bpntrStart,
int bpntrEnd)
const {
1035 for(
int i=bpntrStart; i<=bpntrEnd; i++) {
1036 int ind =
Amat_->bindx[i];
1039 if (ind < N_update_) {
1046 else globalCol = ind;
1048 if (globalCol == blkInd)
return(i);
1060 int nnzBlks =
Amat_->bpntr[
amap_->getNumLocalBlocks()];
1063 for(
int i=0; i<nnzBlks; i++) {
1084 int numProcs =
amap_->getProcConfig()[AZ_N_procs];
1085 int thisProc =
amap_->getProcConfig()[AZ_node];
1092 MPI_Allgather(&len, 1, MPI_INT, lengths, 1, MPI_INT, comm);
1099 int totalLength = lengths[0];
1101 offsets[i] = offsets[i-1] + lengths[i-1];
1102 totalLength += lengths[i];
1106 int* recvBuf =
new int[totalLength];
1109 MPI_Allgatherv(remoteInds, len, MPI_INT, recvBuf, lengths, offsets,
1114 int* blkSizes =
new int[totalLength];
1117 for(
int j=0; j<totalLength; j++) {
1119 blkSizes[j] =
Amat_->rpntr[index+1]-
Amat_->rpntr[index];
1121 else blkSizes[j] = 0;
1128 int* recvSizes =
new int[totalLength];
1130 MPI_Allreduce(blkSizes, recvSizes, totalLength, MPI_INT, MPI_SUM, comm);
1134 int offset = offsets[thisProc];
1135 for(
int k=0; k<len; k++) {
1136 remoteBlkSizes[k] = recvSizes[offset + k];
1137 if (recvSizes[offset+k] <= 0)
1145 delete [] recvSizes;
1167 int index = AZ_find_index(item, list, len);
1169 if (index >= 0)
return;
1171 int* newList =
new int[len+1];
1176 for(
int i=0; i<len; i++) {
1178 if (list[i] < item) newList[i] = list[i];
1184 else newList[i] = list[i-1];
1188 if (inserted) newList[len] = list[len-1];
1189 else newList[len] = item;
1192 if (len > 0)
delete [] list;
void setBindx(int nnzBlks, int *blkColInds)
int getNumBlocksPerRow(int blkRow, int &nnzBlksPerRow) const
void readMatrixData(FILE *infile)
void matvec(const Aztec_LSVector &x, Aztec_LSVector &y) const
int getNumNonzerosPerRow(int blkRow, int &nnzPerRow) const
void calcIndx(int nnzBlks)
void insertList(int item, int *&list, int &len)
void getRemoteBlkSizes(int *remoteBlkSizes, int *remoteInds, int len)
void setLoaded(bool flag)
AztecDVBR_Matrix(fei::SharedPtr< Aztec_BlockMap > map)
void calcBpntr(int *nzBlksPerRow)
bool writeToFile(const char *fileName) const
void readAllocateInfo(FILE *infile, int *&num_nz_blocks, int *&blk_col_inds)
fei::SharedPtr< Aztec_BlockMap > amap_
int getBlockRow(int blk_row, double *vals, int *blk_col_inds, int num_nz_blocks) const
void calcRemoteInds(int *&remoteInds, int &len)
std::ostream & console_out()
int inUpdate(int globalIndex, int &localIndex) const
int sumIntoBlockRow(int blk_row, double *vals, int *blk_col_inds, int num_nz_blocks) const
int getBindxOffset(int blkInd, int bpntrStart, int bpntrEnd) const
void setAllocated(bool flag)
void messageAbort(const char *mesg) const
void getValuesFromString(char *line, int len, double *values, int lenValues)
void allocate(int *num_nz_blocks, int *blk_col_inds)
virtual ~AztecDVBR_Matrix()
int getBlockSize(int blkRow, int blkCol, int &ptRows, int &ptCols)
int numProcs(MPI_Comm comm)
int putBlockRow(int blk_row, double *vals, int *blk_col_inds, int num_nz_blocks) const
bool readFromFile(const char *filename)