44 #include <fei_trilinos_macros.hpp> 
   45 #include <fei_iostream.hpp> 
   47 #ifdef HAVE_FEI_AZTECOO 
   57 #define AZTEC_MPI AZTEC_MPI 
   67 #include <fei_ArrayUtils.hpp> 
   69 #include <fei_Aztec_Map.hpp> 
   70 #include <fei_Aztec_LSVector.hpp> 
   71 #include <fei_AztecDMSR_Matrix.hpp> 
   73 #define ADMSR_LOCAL_ROW_ALLOC_LEN(localRow) 1+bindx[localRow+1]-bindx[localRow] 
   75 #define ADMSR_LOCAL_ROW_LEN(localRow) 1+rowLengths_[localRow] 
   77 namespace fei_trilinos {
 
   83     localOffset_(map->localOffset()),
 
   84     localSize_(map->localSize()),
 
   87     arraysAllocated_(false),
 
   92     N_update_(map->localSize()),
 
  100       rowLengths_ = 
new int[N_update_];
 
  101       for(
int i=0; i<N_update_; i++) {
 
  106     Amat_ = AZ_matrix_create(N_update_);
 
  110   AztecDMSR_Matrix::AztecDMSR_Matrix(
const AztecDMSR_Matrix& src)
 
  111     : isFilled_(src.isFilled_),
 
  112     isAllocated_(src.isAllocated_),
 
  113     localOffset_(src.localOffset_),
 
  114     localSize_(src.localSize_),
 
  117     arraysAllocated_(src.arraysAllocated_),
 
  121     nnzeros_(src.nnzeros_),
 
  122     N_update_(src.N_update_),
 
  127     azTransformed_(src.azTransformed_)
 
  129     expand_array(tmp_array_, tmp_array_len_, src.tmp_array_len_);
 
  130     expand_array(dtmp_array_, dtmp_array_len_, src.dtmp_array_len_);
 
  133       rowLengths_ = 
new int[N_update_];
 
  134       for(
int i=0; i<N_update_; i++) {
 
  135         rowLengths_[i] = src.rowLengths_[i];
 
  139     Amat_ = AZ_matrix_create(N_update_);
 
  141     if (isAllocated_ && nnzeros_ > 0) {
 
  142       val = 
new double[nnzeros_+1];
 
  143       bindx = 
new int[nnzeros_+1];
 
  145       for(
int i=0; i<nnzeros_+1; ++i) {
 
  147         bindx[i] = src.bindx[i];
 
  151         AZ_set_MSR(Amat_, bindx, val, amap_->data_org, 0, NULL, AZ_LOCAL);
 
  157   AztecDMSR_Matrix::~AztecDMSR_Matrix()
 
  159     if (arraysAllocated_) {
 
  164       arraysAllocated_ = 
false;
 
  167     if (dtmp_array_) 
delete [] dtmp_array_; dtmp_array_ = NULL;
 
  170       delete [] rowLengths_;
 
  175     if (azTransformed_) {
 
  176       azTransformed_ = 
false;
 
  179     AZ_matrix_destroy(&Amat_);
 
  183     isAllocated_ = 
false;
 
  184     arraysAllocated_ = 
false;
 
  186     if (tmp_array_len_ > 0) {
 
  187       delete [] tmp_array_;
 
  194   void AztecDMSR_Matrix::expand_array(
int*& array, 
int& arraylen, 
int newlen)
 
  196     if (arraylen < newlen) {
 
  198       array = 
new int[newlen];
 
  199       for(
int i=0; i<newlen; ++i) array[i] = -999;
 
  205   void AztecDMSR_Matrix::expand_array(
double*& array, 
int& arraylen, 
int newlen)
 
  207     if (arraylen < newlen) {
 
  209       array = 
new double[newlen];
 
  210       for(
int i=0; i<newlen; ++i) array[i] = -999.9;
 
  216   void AztecDMSR_Matrix::scale(
double scalar)
 
  218     if (scalar == 1.0) 
return;
 
  221       for(
int i=0; i<nnzeros_+1; ++i) {
 
  228   void AztecDMSR_Matrix::matvec(
const Aztec_LSVector& x,
 
  229       Aztec_LSVector& y)
 const 
  237     int *proc_config = amap_->getProcConfig();
 
  239     double *b = (
double*)x.startPointer();
 
  240     double *c = (
double*)y.startPointer();
 
  242     AZ_MSR_matvec_mult(b, c, Amat_, proc_config);
 
  249   void AztecDMSR_Matrix::put(
double s)
 
  252       for(
int i=0; i<bindx[N_update_]; i++) val[i] = s;
 
  255       fei::console_out() << 
"AztecDMSR_Matrix::put - ERROR, can't do put until allocated" 
  262   int AztecDMSR_Matrix::rowLength(
int row)
 const 
  268     if(amap_->inUpdate(thisRow,localRow)){
 
  269       return(ADMSR_LOCAL_ROW_ALLOC_LEN(localRow));
 
  273         << 
" not in local update set." << FEI_ENDL;
 
  280   int AztecDMSR_Matrix::setDiagEntry(
int row, 
double value)
 
  284     if(!amap_->inUpdate(thisRow,localRow)){
 
  286         << 
" not in local update set." << FEI_ENDL;
 
  290     val[localRow] = value;
 
  295   double AztecDMSR_Matrix::getDiagEntry(
int row)
 const 
  299     if(!amap_->inUpdate(thisRow,localRow)){
 
  301         << 
" not in local update set." << FEI_ENDL;
 
  302       abort(); 
return val[0];
 
  305     return(val[localRow]);
 
  309   int AztecDMSR_Matrix::getOffDiagRowPointers(
int row, 
int*& colIndices,
 
  311       int& offDiagRowLength)
 
  315     if(!amap_->inUpdate(thisRow,localRow)){
 
  316       fei::console_out() << 
"AztecDMSR_Matrix::getOffDiagRowPointers: ERROR - row " << row
 
  317         << 
" not in local update set." << FEI_ENDL;
 
  321     offDiagRowLength = rowLengths_[localRow];
 
  322     if (isFilled_) offDiagRowLength = ADMSR_LOCAL_ROW_ALLOC_LEN(localRow)-1;
 
  323     int start = bindx[localRow];
 
  324     colIndices = &(bindx[start]);
 
  325     coefs = &(val[start]);
 
  331   void AztecDMSR_Matrix::getRow(
int row,
 
  341     bool foundDiagonal = 
false;
 
  343     int j, localRow, itmp;
 
  347     if(!amap_->inUpdate(thisRow,localRow)){
 
  349         << 
" not in local update set." << FEI_ENDL;
 
  354     int start = bindx[localRow];
 
  355     int end = bindx[localRow+1]-1;
 
  358     for(
int i=start; i<=end; i++){
 
  360       colInd[j] = amap_->getTransformedEqn(bindx[i]);
 
  362       if (colInd[j]==row) {
 
  366         coefs[j] = val[localRow];
 
  371         foundDiagonal = 
true;
 
  377       coefs[j] = val[localRow];
 
  386   int AztecDMSR_Matrix::putRow(
int row, 
int len, 
const double *coefs,
 
  394     int j, localRow, globalColIndex;
 
  398     if (!amap_->inUpdate(thisRow,localRow)){
 
  400         << 
" not in local update set." << FEI_ENDL;
 
  404     int offDiagRowLen = rowLengths_[localRow];
 
  405     int rowAllocLen = ADMSR_LOCAL_ROW_ALLOC_LEN(localRow);
 
  406     if (isFilled_) offDiagRowLen = rowAllocLen - 1;
 
  407     int offDiagRowAllocLen = rowAllocLen - 1;
 
  409     if (len > rowAllocLen) {
 
  410       fei::console_out() << 
"AztecDMSR_Matrix::putRow. too many coefs, row " << row << FEI_ENDL;
 
  414     int jLimit = bindx[localRow+1] - 1;
 
  415     int jStart = bindx[localRow];
 
  416     int* colInds = &(bindx[jStart]);
 
  417     int colStart = *colInds;
 
  418     double* rowCoefs = &(val[jStart]);
 
  420     for(
int i=0; i<len; i++){
 
  421       if (colInd[i] == row){  
 
  422         val[localRow] = coefs[i];
 
  430         int colIndex = colStart;
 
  432         while (j <= jLimit) {
 
  433           globalColIndex = amap_->getTransformedEqn(colIndex);
 
  435           if (globalColIndex == col) 
break;
 
  437           colIndex = bindx[++j];
 
  447             << 
" find col. index " << colInd[i] << 
" in " 
  448             << 
"row " << row << FEI_ENDL;
 
  456         int insertPoint = -1;
 
  457         int index = fei::binarySearch<int>(col, colInds, offDiagRowLen, insertPoint);
 
  459         if (index >= offDiagRowAllocLen){ 
 
  461             << 
"row " << row << 
", colInd["<<i<<
"] " << colInd[i]
 
  462             << 
", index = " << index << FEI_ENDL;
 
  467           rowCoefs[index] = coefs[i];
 
  470           int tmp = offDiagRowLen;
 
  471           int err = insert(col, insertPoint, colInds,
 
  472               tmp, offDiagRowAllocLen);
 
  473           err += insert(coefs[i], insertPoint, rowCoefs,
 
  474               offDiagRowLen, offDiagRowAllocLen);
 
  477               << 
"value for index " << col << 
" to row " << row << FEI_ENDL;
 
  480           rowLengths_[localRow]++;
 
  489   int AztecDMSR_Matrix::sumIntoRow(
int numRows, 
const int* rows,
 
  490       int numCols, 
const int *colInd,
 
  491       const double* 
const* coefs)
 
  493     if (numRows == 0 || numCols == 0) 
return(0);
 
  497       for(
int i=0; i<numRows; ++i) {
 
  498         err = sumIntoRow(rows[i], numCols, coefs[i], colInd);
 
  499         if (err != 0) 
return(err);
 
  509     for(
int i=0; i<numRows; ++i) {
 
  512       if (!amap_->inUpdate(row, localRow)) {
 
  514           << 
" not in local update set [" << amap_->getUpdate()[0] << 
" ... " 
  515           << amap_->getUpdate()[N_update_-1] << 
"]." << FEI_ENDL;
 
  519       int rowlen = bindx[localRow+1]-bindx[localRow];
 
  520       if (maxRowLen < rowlen) maxRowLen = rowlen;
 
  523     if (maxRowLen+2*numCols > tmp_array_len_) {
 
  524       expand_array(tmp_array_, tmp_array_len_, maxRowLen+2*numCols);
 
  527     int* incols = &tmp_array_[maxRowLen];
 
  528     int* indirect = incols+numCols;
 
  530     for(
int jj=0; jj<numCols; ++jj) {
 
  531       incols[jj] = colInd[jj];
 
  535     fei::insertion_sort_with_companions<int>(numCols, incols, indirect);
 
  539     for(
int i=0; i<numRows; ++i) {
 
  541       if (!amap_->inUpdate(row, localRow)) {
 
  543           << 
" not in local update set [" << amap_->getUpdate()[0] << 
" ... " 
  544           << amap_->getUpdate()[N_update_-1] << 
"]." << FEI_ENDL;
 
  548       int jStart = bindx[localRow];
 
  549       double* rowCoefs = val+jStart;
 
  550       int* rowColInds = bindx+jStart;
 
  551       int rowLen= bindx[localRow+1]-jStart;
 
  553       for(
int jj=0; jj<rowLen; ++jj) {
 
  554         tmp_array_[jj] = amap_->getTransformedEqn(rowColInds[jj]);
 
  557       const double* coefs_i = coefs[i];
 
  560       int incol = incols[inoffset];
 
  561       while (incol == row) {
 
  562         val[localRow] += coefs_i[indirect[inoffset++]];
 
  563         if (inoffset >= numCols) 
break;
 
  564         incol = incols[inoffset];
 
  567       if (inoffset >= numCols) 
continue;
 
  571       int rowOffset = fei::binarySearch<int>(incol, tmp_array_, rowLen);
 
  574           << 
"row " << row << 
", col not found: " 
  575           << incol << FEI_ENDL;
 
  579       rowCoefs[rowOffset++] += coefs_i[indirect[inoffset++]];
 
  582       if (inoffset>0 && incols[inoffset] == incols[inoffset-1]) --rowOffset;
 
  584       while(inoffset < numCols) {
 
  585         incol = incols[inoffset];
 
  588           val[localRow] += coefs_i[indirect[inoffset++]];
 
  592         while(tmp_array_[rowOffset] != incol) {
 
  594           if (rowOffset >= rowLen) {
 
  596               << incol << 
" not found in row " << row << FEI_ENDL;
 
  601         rowCoefs[rowOffset++] += coefs_i[indirect[inoffset++]];
 
  602         if (inoffset>0 && incols[inoffset] == incols[inoffset-1]) --rowOffset;
 
  610   int AztecDMSR_Matrix::sumIntoRow(
int row, 
int len, 
const double *coefs,
 
  618     int localRow, thisRow = row ;
 
  620     if (!amap_->inUpdate(thisRow,localRow)) {
 
  622         << 
" not in local update set." << FEI_ENDL;
 
  626     int jLimit = bindx[localRow+1] - 1;
 
  627     int jStart = bindx[localRow];
 
  628     int jLen = jLimit-jStart+1;
 
  629     int* colInds = &(bindx[jStart]);
 
  630     double* rowCoefs = &(val[jStart]);
 
  633       if (jLen+len > tmp_array_len_) {
 
  634         expand_array(tmp_array_, tmp_array_len_, jLen+len);
 
  635         expand_array(dtmp_array_, dtmp_array_len_, len);
 
  637       for(
int jj=0; jj<jLen; ++jj) {
 
  638         tmp_array_[jj] = amap_->getTransformedEqn(colInds[jj]);
 
  641       int* incols = &tmp_array_[jLen];
 
  643       for(
int jj=0; jj<len; ++jj) {
 
  644         int col = colInd[jj];
 
  646           val[localRow] += coefs[jj];
 
  650           dtmp_array_[doffs++] = coefs[jj];
 
  653       fei::insertion_sort_with_companions<double>(doffs, incols, dtmp_array_);
 
  656       int offset = fei::binarySearch<int>(incols[ioffset], tmp_array_, jLen);
 
  659           << 
"row " << row << 
", col not found: " 
  660           << colInd[ioffset] << FEI_ENDL;
 
  664       rowCoefs[offset++] += dtmp_array_[ioffset++];
 
  665       if (incols[ioffset] == tmp_array_[offset-1]) --offset;
 
  667       while(ioffset < doffs) {
 
  668         int incol = incols[ioffset];
 
  670         while(tmp_array_[offset] != incol) {
 
  672           if (offset >= jLen) {
 
  674               << incols[ioffset] << 
" not found in row " << row << FEI_ENDL;
 
  678         rowCoefs[offset++] += dtmp_array_[ioffset++];
 
  679         if (incols[ioffset] == tmp_array_[offset-1]) --offset;
 
  687     int rowAllocLen = ADMSR_LOCAL_ROW_ALLOC_LEN(localRow);
 
  688     int offDiagRowLen = isFilled_ ? rowAllocLen - 1 : rowLengths_[localRow];
 
  689     int offDiagRowAllocLen = rowAllocLen - 1;
 
  691     for(
int i=0; i<len; i++){
 
  692       if (colInd[i] == row){  
 
  693         val[localRow] += coefs[i];
 
  699       int insertPoint = -1;
 
  700       int index = fei::binarySearch<int>(col, colInds, offDiagRowLen, insertPoint);
 
  703         rowCoefs[index] += coefs[i];
 
  706         int tmp = offDiagRowLen;
 
  707         int err = insert(col, insertPoint, colInds,
 
  708             tmp, offDiagRowAllocLen);
 
  709         err += insert(coefs[i], insertPoint, rowCoefs,
 
  710             offDiagRowLen, offDiagRowAllocLen);
 
  713             << 
"value for index " << col << 
" to row " << row << FEI_ENDL;
 
  716         rowLengths_[localRow]++;
 
  724   int AztecDMSR_Matrix::addScaledMatrix(
double scalar,
 
  725       const AztecDMSR_Matrix& source)
 
  727     if (N_update_ != source.N_update_ ||
 
  728         nnzeros_ != source.nnzeros_ ||
 
  729         isFilled_ != source.isFilled_) {
 
  730       fei::console_out() << 
"AztecDMSR_Matrix::addScaledMatrix ERROR, not compatible" 
  735     const double* src_val = source.val;
 
  737     for(i=0; i<N_update_; ++i) {
 
  738       val[i] += scalar*src_val[i];
 
  744       for(i=N_update_+1; i<nnzeros_+1; ++i) {
 
  745         val[i] += src_val[i];
 
  749       for(i=N_update_+1; i<nnzeros_+1; ++i) {
 
  750         val[i] += scalar*src_val[i];
 
  758   int AztecDMSR_Matrix::insert(
int item, 
int offset, 
int* list,
 
  759       int& len, 
int allocLen)
 
  761     if (len >= allocLen) 
return(-1);
 
  763     for(
int i=len; i>offset; i--) list[i] = list[i-1];
 
  772   int AztecDMSR_Matrix::insert(
double item, 
int offset, 
double* list,
 
  773       int& len, 
int allocLen)
 
  775     if (len >= allocLen) 
return(-1);
 
  777     for(
int i=len; i>offset; i--) list[i] = list[i-1];
 
  786   void AztecDMSR_Matrix::getDiagonal(Aztec_LSVector& diagVector)
 const {
 
  792     double *pdv = (
double*)diagVector.startPointer();
 
  794     for(
int i=0; i<N_update_; i++){
 
  800   void AztecDMSR_Matrix::allocate(
int *rowLengths)
 
  813     for(i=0; i<N_update_; i++){
 
  814       if (rowLengths[i] < 0) {
 
  815         messageAbort(
"allocate: negative row length");
 
  817       nnzeros_ += rowLengths[i] + 1;
 
  823     bindx = 
new int[nnzeros_+1];
 
  828     val = 
new double[nnzeros_+1];
 
  830     arraysAllocated_ = 
true;
 
  832     for(i=0; i<nnzeros_+1; i++){
 
  837     bindx[0] = N_update_+1;
 
  839     for(i=0; i<N_update_; i++){
 
  840       bindx[i+1] = bindx[i] + rowLengths[i];
 
  841       if (bindx[i+1] < 0) {
 
  842         messageAbort(
"allocate: bindx row length negative.");
 
  847     val[N_update_] = 0.0;
 
  849     AZ_set_MSR(Amat_, bindx, val,amap_->data_org, 0, NULL, AZ_LOCAL);
 
  856   void AztecDMSR_Matrix::allocate(
int *rowLengths,
 
  857       const int* 
const* colIndices)
 
  859     allocate(rowLengths);
 
  862     int offset = N_update_+1;
 
  863     for(
int i=0; i<N_update_; ++i) {
 
  864       const int* row_cols = colIndices[i];
 
  865       int row_len = rowLengths[i];
 
  866       rowLengths_[i] = row_len-1;
 
  870       for(
int j=0; j<row_len; ++j) {
 
  871         col = row_cols[coffset++];
 
  873         if (col == localOffset_+i) {
 
  874           col = row_cols[coffset++];
 
  877         if (col <= prev_col) {
 
  878           messageAbort(
"allocate: column-indices not sorted.");
 
  883         bindx[offset++] = col;
 
  889   double AztecDMSR_Matrix::rowMax(
int row)
 const {
 
  893     if(!amap_->inUpdate(row,localRow)){
 
  895         << 
" not in local update set." << FEI_ENDL;
 
  899     max = fabs(val[localRow]);
 
  901     for(
int i=bindx[localRow]; i<bindx[localRow+1]; i++)
 
  902       if(fabs(val[i])>max)max = fabs(val[i]);
 
  908   void AztecDMSR_Matrix::fillComplete() {
 
  914     if (isFilled_ || azTransformed_) {
 
  916       azTransformed_ = 
true;
 
  920     int *proc_config = amap_->getProcConfig();
 
  925     int globalSize = amap_->globalSize();
 
  926     for(
int i=N_update_+1; i<nnzeros_+1; i++) {
 
  927       if (bindx[i] < 0 || bindx[i] >= globalSize) {
 
  928         fei::console_out() << 
"AztecDMSR_Matrix: ERROR, bindx["<<i<<
"]: " << bindx[i]
 
  929           << 
", globalSize: " << globalSize << FEI_ENDL;
 
  931         MPI_Comm thisComm = amap_->getCommunicator();
 
  932         MPI_Abort(thisComm, -1);
 
  937     AZ_transform(proc_config, &amap_->external, bindx, val,
 
  938         amap_->getUpdate(), &amap_->update_index,
 
  939         &amap_->extern_index, &amap_->data_org, N_update_,
 
  940         dummy, dummy, dummy, &dummy, AZ_MSR_MATRIX);
 
  953     AZ_set_MSR(Amat_, bindx, val, amap_->data_org, 0, NULL, AZ_LOCAL);
 
  955     amap_->orderingUpdate.resize(N_update_);
 
  956     for(
int ii=0; ii<N_update_; ii++) {
 
  957       amap_->orderingUpdate[amap_->update_index[ii]] = ii;
 
  960     amap_->az_transformed = 
true;
 
  961     azTransformed_ = 
true;
 
  968   void AztecDMSR_Matrix::copyStructure(AztecDMSR_Matrix& source)
 
  975     nnzeros_ = source.nnzeros_;
 
  977     if (arraysAllocated_) {
 
  980       arraysAllocated_ = 
false;
 
  983     val = 
new double[nnzeros_+1];
 
  984     bindx = 
new int[nnzeros_+1];
 
  987     for(i=0; i<nnzeros_+1; i++) {
 
  989       bindx[i] = source.bindx[i];
 
  992     for(i=0; i<N_update_; ++i) rowLengths_[i] = source.rowLengths_[i];
 
  994     amap_ = source.amap_;
 
  996     AZ_set_MSR(Amat_, bindx, val, amap_->data_org, 0, NULL, AZ_LOCAL);
 
  998     isFilled_ = source.isFilled_;
 
  999     azTransformed_ = source.azTransformed_;
 
 1001     arraysAllocated_ = 
true;
 
 1006   bool AztecDMSR_Matrix::readFromFile(
const char *filename)
 
 1024     FILE *mfp = fopen(filename,
"r");
 
 1027       fei::console_out() << 
"AztecDMSR_Matrix::readFromFile - couldn't open matrix file." 
 1032     if (strstr(filename, 
".mtx") == NULL) {
 
 1033       fei::console_out() << 
"AztecDMSR_Matrix::readFromFile: filename doesn't contain " 
 1034         << 
"'.mtx'. File should be a MatrixMarket file." << FEI_ENDL;
 
 1039       fgets(line,128,mfp);
 
 1040     } 
while(strchr(line,
'%'));
 
 1044         fgets(line,128,mfp);
 
 1045       } 
while(strchr(line,
'%'));
 
 1050       sscanf(line,
"%d %d %le",&i,&j,&value);
 
 1052       if(amap_->inUpdate(i, dummy)) {
 
 1053         if (putRow(i, 1, &value, &j) != 0) 
return(
false);
 
 1062   bool AztecDMSR_Matrix::writeToFile(
const char *fileName)
 const 
 1071     int numProcs = amap_->getProcConfig()[AZ_N_procs];
 
 1072     int thisProc = amap_->getProcConfig()[AZ_node];
 
 1076     int localNNZ = nnzeros_;
 
 1077     int globalNNZ = localNNZ;
 
 1079     MPI_Comm thisComm = amap_->getCommunicator();
 
 1080     MPI_Allreduce(&localNNZ, &globalNNZ, 1, MPI_INT, MPI_SUM, thisComm);
 
 1083     for(
int p=0; p<numProcs; p++){
 
 1087       MPI_Barrier(thisComm);
 
 1090       if (p == thisProc) {
 
 1093         if (masterRank == thisProc) {
 
 1095           file = fopen(fileName,
"w");
 
 1100           int n = amap_->globalSize();
 
 1101           fprintf(file,
"%d %d %d\n",n, n, globalNNZ);
 
 1105           file = fopen(fileName,
"a");
 
 1109         for(
int i=0; i<N_update_; i++){
 
 1110           int row = localOffset_+i;
 
 1113           if (!amap_->inUpdate(row, localRow)) 
return(
false);
 
 1115           int offDiagRowLen = ADMSR_LOCAL_ROW_LEN(localRow) - 1;
 
 1116           if (isFilled_) offDiagRowLen = ADMSR_LOCAL_ROW_ALLOC_LEN(localRow) - 1;
 
 1117           int* colInds = &(bindx[bindx[localRow]]);
 
 1118           double* coefs = &(val[bindx[localRow]]);
 
 1120           bool wroteDiagonal = 
false;
 
 1121           for(
int j=0; j<offDiagRowLen; j++) {
 
 1122             int col = colInds[j];
 
 1123             int globalCol = col;
 
 1125               globalCol = amap_->getTransformedEqn(col);
 
 1128             if (globalCol >= row && !wroteDiagonal) {
 
 1129               fprintf(file,
"%d %d %20.13e\n", row, row,
 
 1131               wroteDiagonal = 
true;
 
 1134             fprintf(file,
"%d %d %20.13e\n", row, globalCol, coefs[j]);
 
 1136           if (!wroteDiagonal) {
 
 1137             fprintf(file,
"%d %d %20.13e\n", row, row,
 
 1139             wroteDiagonal = 
true;
 
 1150   void AztecDMSR_Matrix::messageAbort(
const char* mesg) {
 
 1151     fei::console_out() << 
"AztecDMSR_Matrix: ERROR: " << mesg << 
" Aborting." << FEI_ENDL;
 
std::ostream & console_out()
 
int numProcs(MPI_Comm comm)