44 #include <fei_trilinos_macros.hpp>
45 #include <fei_sstream.hpp>
47 #ifdef HAVE_FEI_AZTECOO
55 #include "fei_Data.hpp"
56 #include "fei_Lookup.hpp"
57 #include "fei_LinearSystemCore.hpp"
58 #include "snl_fei_Utils.hpp"
59 #include "fei_ArrayUtils.hpp"
62 #define fei_file "fei_Aztec_LinSysCore.cpp"
63 #include "fei_ErrMacros.hpp"
69 #define AZTEC_MPI AZTEC_MPI
79 #include "fei_Aztec_Map.hpp"
80 #include "fei_Aztec_BlockMap.hpp"
81 #include "fei_Aztec_LSVector.hpp"
82 #include "fei_AztecDMSR_Matrix.hpp"
83 #include "fei_AztecDVBR_Matrix.hpp"
85 #include "fei_Aztec_LinSysCore.hpp"
87 namespace fei_trilinos {
89 static int azlsc_solveCounter_ = 0;
90 static int azlsc_debugFileCounter_ = 0;
92 static std::map<std::string, unsigned> fei_aztec_named_solve_counter;
95 Aztec_LinSysCore::Aztec_LinSysCore(MPI_Comm comm)
109 explicitDirichletBCs_(false),
110 BCenforcement_no_column_mod_(false),
112 matrixAllocated_(false),
113 vectorsAllocated_(false),
114 blkMatrixAllocated_(false),
115 matrixLoaded_(false),
117 needNewPreconditioner_(false),
118 tooLateToChooseBlock_(false),
126 precondCreated_(false),
128 scalingCreated_(false),
129 aztec_options_(NULL),
133 tmp_x_touched_(false),
136 tmp_b_allocated_(false),
145 numGlobalEqnBlks_(0),
148 localBlockSizes_(NULL),
154 debugFileCounter_(0),
156 debugFileName_(NULL),
158 named_solve_counter_(fei_aztec_named_solve_counter)
164 MPI_Comm_size(comm_, &numProcs_);
165 MPI_Comm_rank(comm_, &thisProc_);
168 aztec_options_ =
new int[AZ_OPTIONS_SIZE];
169 aztec_params_ =
new double[AZ_PARAMS_SIZE];
171 AZ_defaults(aztec_options_, aztec_params_);
173 aztec_status_ =
new double[AZ_STATUS_SIZE];
174 for(
int i=0; i<AZ_STATUS_SIZE; i++) aztec_status_[i] = 0.0;
177 rhsIDs_ =
new int[numRHSs_];
180 std::map<std::string,unsigned>::iterator
181 iter = named_solve_counter_.find(name_);
182 if (iter == named_solve_counter_.end()) {
183 named_solve_counter_.insert(std::make_pair(name_, 0));
187 struct free_any_remaining_az_memory {
188 free_any_remaining_az_memory(){}
189 ~free_any_remaining_az_memory()
191 AZ_manage_memory(0, AZ_CLEAR_ALL, 0, NULL, NULL);
196 Aztec_LinSysCore::~Aztec_LinSysCore() {
197 static free_any_remaining_az_memory when_program_exits;
199 if (blkMatrixAllocated_) {
201 delete [] blkUpdate_;
202 delete [] localBlockSizes_;
203 blkMatrixAllocated_ =
false;
205 if (matrixAllocated_) {
207 matrixAllocated_ =
false;
210 if (precondCreated_) {
211 AZ_precond_destroy(&azP_);
212 precondCreated_ =
false;
215 if (scalingCreated_) {
216 AZ_scaling_destroy(&azS_);
217 scalingCreated_ =
false;
220 if (vectorsAllocated_)
delete x_;
224 for(
int i=0; i<numRHSs_; i++) {
225 if (vectorsAllocated_)
delete b_[i];
226 if (tmp_b_allocated_)
delete [] tmp_b_[i];
228 if (vectorsAllocated_)
delete [] b_;
229 if (tmp_b_allocated_)
delete [] tmp_b_;
230 tmp_b_allocated_ =
false;
233 delete [] aztec_options_;
234 delete [] aztec_params_;
235 delete [] aztec_status_;
240 for(
int j=0; j<numParams_; j++) {
241 delete [] paramStrings_[j];
243 delete [] paramStrings_;
249 delete [] debugPath_;
250 delete [] debugFileName_;
253 delete [] essBCindices_;
254 essBCindices_ = NULL;
261 return(
new Aztec_LinSysCore(comm_));
265 int Aztec_LinSysCore::parameters(
int numParams,
const char*
const * params) {
270 debugOutput(
"parameters");
272 if (numParams == 0 || params == NULL) {
273 debugOutput(
"--- no parameters");
277 const char* param = NULL;
279 snl_fei::mergeStringLists(paramStrings_, numParams_,
282 param = snl_fei::getParamValue(
"outputLevel",numParams,params);
284 sscanf(param,
"%d", &outputLevel_);
287 param = snl_fei::getParamValue(
"AZ_matrix_type", numParams, params);
289 setMatrixType(param);
292 param = snl_fei::getParam(
"EXPLICIT_BC_ENFORCEMENT", numParams, params);
294 explicitDirichletBCs_ =
true;
297 explicitDirichletBCs_ =
false;
300 param = snl_fei::getParam(
"BC_ENFORCEMENT_NO_COLUMN_MOD",numParams,params);
302 BCenforcement_no_column_mod_ =
true;
305 BCenforcement_no_column_mod_ =
false;
308 param = snl_fei::getParamValue(
"numLevels", numParams, params);
310 sscanf(param,
"%d", &numLevels_);
313 bool dbgOutputParam =
false;
314 char* dbgFileName = NULL;
315 char* dbgPath = NULL;
317 bool output_level_on =
false;
318 param = snl_fei::getParamValue(
"FEI_OUTPUT_LEVEL",numParams,params);
320 std::string str(param);
321 if (str ==
"ALL" || str ==
"MATRIX_FILES" || str ==
"FULL_LOGS") {
322 output_level_on =
true;
326 param = snl_fei::getParamValue(
"debugOutput",numParams,params);
327 if (param != NULL || output_level_on){
328 dbgOutputParam =
true;
329 dbgFileName =
new char[128];
330 dbgPath = param==NULL ?
new char[3] :
new char[strlen(param)+1];
331 if (param == NULL) sprintf(dbgPath,
"./");
332 else strcpy(dbgPath, param);
334 sprintf(dbgFileName,
"AZLSC.%d.%d.%d",
335 numProcs_, thisProc_, azlsc_debugFileCounter_);
338 param = snl_fei::getParamValue(
"name",numParams, params);
342 std::map<std::string,unsigned>::iterator
343 iter = named_solve_counter_.find(name_);
344 if (iter == named_solve_counter_.end()) {
345 named_solve_counter_.insert(std::make_pair(name_, 0));
348 if (dbgOutputParam) {
349 if (dbgFileName != NULL)
delete [] dbgFileName;
350 dbgFileName =
new char[256];
351 sprintf(dbgFileName,
"AZLSC_%s.%d.%d.%d", name_.c_str(),
352 numProcs_, thisProc_, azlsc_debugFileCounter_);
356 if (dbgOutputParam) {
357 if (azlsc_debugFileCounter_ == azlsc_solveCounter_) {
358 setDebugOutput(dbgPath,dbgFileName);
359 ++azlsc_debugFileCounter_;
361 delete [] dbgFileName;
366 fprintf(debugFile_,
"--- numParams %d\n",numParams);
367 for(
int i=0; i<numParams; i++){
368 fprintf(debugFile_,
"------ paramStrings[%d]: %s\n",i,
373 debugOutput(
"leaving parameters function");
378 int Aztec_LinSysCore::setLookup(
Lookup& lookup)
386 int Aztec_LinSysCore::setGlobalOffsets(
int len,
int* nodeOffsets,
387 int* eqnOffsets,
int* blkEqnOffsets)
389 localOffset_ = eqnOffsets[thisProc_];
390 numLocalEqns_ = eqnOffsets[thisProc_+1]-localOffset_;
391 numGlobalEqns_ = eqnOffsets[numProcs_];
393 localBlkOffset_ = blkEqnOffsets[thisProc_];
394 numLocalEqnBlks_ = blkEqnOffsets[thisProc_+1]-localBlkOffset_;
395 numGlobalEqnBlks_ = blkEqnOffsets[numProcs_];
397 int err = createMiscStuff();
398 if (err)
return(err);
401 fprintf(debugFile_,
"setGlobalNodeOffsets, len: %d\n", len);
402 for(
int i=0; i<len; i++) {
403 fprintf(debugFile_,
" nodeOffsets[%d]: %d, eqnOffsets[%d]: %d, blkEqnOffsets[%d], %d\n", i, nodeOffsets[i], i, eqnOffsets[i], i, blkEqnOffsets[i]);
411 int Aztec_LinSysCore::setConnectivities(GlobalID elemBlock,
414 const GlobalID* elemIDs,
415 const int*
const* connNodes)
419 (void) numNodesPerElem;
426 int Aztec_LinSysCore::setMatrixType(
const char* name) {
428 if (!strcmp(name,
"AZ_VBR_MATRIX")) {
429 if (!tooLateToChooseBlock_) {
431 debugOutput(
"setMatrixType: chose block matrix");
434 fei::console_out() <<
"Aztec_LinSysCore::setMatrixType: WARNING: Too late to choose"
435 <<
" the DVBR matrix; make this choice before calling "
436 <<
"setMatrixStructure. DMSR will be used." << FEI_ENDL;
439 else if (!strcmp(name,
"AZ_MSR_MATRIX")) {
443 if (thisProc_ == 0) {
444 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested matrix-type <"<<name <<
"> not recognized." << FEI_ENDL;
445 FEI_COUT <<
"Aztec_LinSysCore: valid matrix-types are: 'AZ_MSR_MATRIX', 'AZ_VBR_MATRIX'" << FEI_ENDL;
452 int Aztec_LinSysCore::setMatrixStructure(
int** ptColIndices,
456 int* ptRowsPerBlkRow)
459 fprintf(debugFile_,
"setMatrixStructure\n");
460 for(
int i=0; i<numLocalEqnBlks_; i++) {
461 int blkEqn = localBlkOffset_+i;
462 fprintf(debugFile_,
" blkRow %d, ptRowsPerBlkRow %d\n",
463 blkEqn, ptRowsPerBlkRow[i]);
468 int err = allocateMatrix(ptColIndices, ptRowLengths, blkColIndices,
469 blkRowLengths, ptRowsPerBlkRow);
474 int Aztec_LinSysCore::createMiscStuff()
482 "createMiscStuff: numRHSs_: %d\n", numRHSs_);
486 if (numLocalEqns_ > numGlobalEqns_)
487 messageAbort(
"createMiscStuff: numLocalEqns > numGlobalEqns");
489 if (0 > localOffset_)
490 messageAbort(
"createMiscStuff: localOffset_ out of range");
492 update_ = numLocalEqns_ > 0 ?
new int[numLocalEqns_] : NULL;
493 if (numLocalEqns_ > 0 && update_ == NULL) {
498 for(j=0; j<numLocalEqns_; j++) update_[j] = localOffset_+j;
500 azS_ = AZ_scaling_create();
501 if (azS_ != NULL) scalingCreated_ =
true;
503 fei::console_out() <<
"Aztec_LinSysCore::createMiscStuff ERROR: failed to create scaling"
509 messageAbort(
"numRHSs_==0. Out of scope or destructor already called?");
511 tmp_x_ = numLocalEqns_ > 0 ?
new double[numLocalEqns_] : NULL;
512 if (numLocalEqns_ > 0 && tmp_x_ == NULL)
return(-1);
514 tmp_bc_ = numLocalEqns_ > 0 ?
new double[numLocalEqns_] : NULL;
515 if (numLocalEqns_ > 0 && tmp_bc_ == NULL)
return(-1);
517 for(i=0; i<numLocalEqns_; i++){
522 if (!tmp_b_allocated_) {
523 tmp_b_ =
new double*[numRHSs_];
525 for(j=0; j<numRHSs_; j++) {
526 tmp_b_[j] =
new double[numLocalEqns_];
527 for(i=0; i<numLocalEqns_; i++) {
532 tmp_b_allocated_ =
true;
535 if (currentRHS_ < 0) currentRHS_ = 0;
540 int Aztec_LinSysCore::allocateMatrix(
int** ptColIndices,
544 int* ptRowsPerBlkRow)
548 err = createBlockMatrix(blkColIndices, blkRowLengths, ptRowsPerBlkRow);
552 tooLateToChooseBlock_ =
true;
554 map_.reset(
new Aztec_Map(numGlobalEqns_, numLocalEqns_, update_, localOffset_, comm_));
556 A_ =
new AztecDMSR_Matrix(map_);
558 if (A_ptr_ == NULL) A_ptr_ = A_;
568 int* row_lengths = numLocalEqns_ > 0 ?
new int[numLocalEqns_] : NULL;
570 for (
int i = 0; i < numLocalEqns_; i++) {
572 ptColIndices[i], ptRowLengths[i]) >= 0) {
573 row_lengths[i] = ptRowLengths[i] - 1;
576 row_lengths[i] = ptRowLengths[i];
582 A_ptr_->allocate(row_lengths, ptColIndices);
584 delete [] row_lengths;
586 matrixAllocated_ =
true;
591 int Aztec_LinSysCore::createBlockMatrix(
int** blkColIndices,
593 int* ptRowsPerBlkRow)
597 blkUpdate_ =
new int[numLocalEqnBlks_];
599 for(i=0; i<numLocalEqnBlks_; i++) {
600 blkUpdate_[i] = localBlkOffset_ + i;
603 blkMap_.reset(
new Aztec_BlockMap(numGlobalEqns_, numLocalEqns_,
604 update_, localOffset_, comm_,
605 numGlobalEqnBlks_, numLocalEqnBlks_,
607 localBlkOffset_, ptRowsPerBlkRow));
609 blkA_ =
new AztecDVBR_Matrix(blkMap_);
611 if (blkA_ptr_ == NULL) blkA_ptr_ = blkA_;
613 localBlockSizes_ =
new int[numLocalEqnBlks_];
616 numNonzeroBlocks_ = 0;
617 for(i=0; i<numLocalEqnBlks_; i++) {
619 numNonzeroBlocks_ += blkRowLengths[i];
621 localBlockSizes_[i] = ptRowsPerBlkRow[i];
626 int* blk_col_inds =
new int[numNonzeroBlocks_];
629 for(i=0; i<numLocalEqnBlks_; i++) {
630 for(
int j=0; j<blkRowLengths[i]; j++) {
631 blk_col_inds[offset++] = blkColIndices[i][j];
636 blkA_->allocate(blkRowLengths, blk_col_inds);
638 delete [] blk_col_inds;
640 blkMatrixAllocated_ =
true;
645 int Aztec_LinSysCore::resetMatrixAndVector(
double s)
647 if (blkMatrixAllocated_) blkA_ptr_->put(s);
648 if (matrixAllocated_) A_ptr_->put(s);
651 for(
int i=0; i<numRHSs_; i++){
655 if (b_ptr_ != NULL) b_ptr_->put(s);
657 if (bc_ != NULL) bc_->put(s);
659 if (!tmp_b_allocated_) {
660 for(
int j=0; j<numRHSs_; j++) {
661 tmp_b_[j] =
new double[numLocalEqns_];
664 matrixLoaded_ =
false;
669 tmp_bc_ =
new double[numLocalEqns_];
671 for(
int ii=0; ii<numLocalEqns_; ii++) tmp_bc_[ii] = s;
673 delete [] essBCindices_;
674 essBCindices_ = NULL;
677 for(
int j=0; j<numRHSs_; j++) {
678 for(
int i=0; i<numLocalEqns_; i++) {
686 int Aztec_LinSysCore::resetMatrix(
double s) {
687 if (blkMatrixAllocated_) blkA_ptr_->put(s);
688 if (matrixAllocated_) A_ptr_->put(s);
690 matrixLoaded_ =
false;
693 if (bc_ != NULL) bc_->put(s);
696 tmp_bc_ =
new double[numLocalEqns_];
698 for(
int ii=0; ii<numLocalEqns_; ii++) tmp_bc_[ii] = s;
700 delete [] essBCindices_;
701 essBCindices_ = NULL;
708 int Aztec_LinSysCore::resetRHSVector(
double s) {
711 for(
int i=0; i<numRHSs_; i++){
716 if (b_ptr_ != NULL) b_ptr_->put(s);
718 if (!tmp_b_allocated_) {
719 for(
int j=0; j<numRHSs_; j++) {
720 tmp_b_[j] =
new double[numLocalEqns_];
726 for(
int j=0; j<numRHSs_; j++) {
727 double* cur_b = tmp_b_[j];
728 for(
int i=0; i<numLocalEqns_; i++) {
736 int Aztec_LinSysCore::sumIntoSystemMatrix(
int numPtRows,
const int* ptRows,
737 int numPtCols,
const int* ptCols,
738 const double*
const* values)
740 matrixLoaded_ =
false;
742 return(sumIntoPointRow(numPtRows, ptRows, numPtCols, ptCols, values,
false));
746 int Aztec_LinSysCore::sumIntoSystemMatrix(
int numPtRows,
const int* ptRows,
747 int numPtCols,
const int* ptCols,
748 int numBlkRows,
const int* blkRows,
749 int numBlkCols,
const int* blkCols,
750 const double*
const* values)
752 matrixLoaded_ =
false;
754 if ((A_ptr_ == NULL) && (blkA_ptr_ == NULL))
755 messageAbort(
"sumIntoSystemMatrix: matrix is NULL.");
758 return(sumIntoBlockRow(numBlkRows, blkRows, numBlkCols, blkCols,
759 values, numPtCols,
false));
762 return( sumIntoPointRow(numPtRows, ptRows, numPtCols, ptCols, values,
768 int Aztec_LinSysCore::putIntoSystemMatrix(
int numPtRows,
const int* ptRows,
769 int numPtCols,
const int* ptCols,
770 const double*
const* values)
772 matrixLoaded_ =
false;
774 return(sumIntoPointRow(numPtRows, ptRows, numPtCols, ptCols, values,
true));
778 int Aztec_LinSysCore::getMatrixRowLength(
int row,
int& length)
781 if (row >= localOffset_ && row < (localOffset_+numLocalEqns_)) {
782 length = A_ptr_->rowLength(row);
787 if (!haveLookup_)
return(-1);
788 int blkRow = lookup_->ptEqnToBlkEqn(row);
789 if (blkRow < 0)
return(-1);
790 return( blkA_ptr_->getNumNonzerosPerRow(blkRow, length) );
797 int Aztec_LinSysCore::getMatrixRow(
int row,
double* coefs,
799 int len,
int& rowLength)
801 int err = getMatrixRowLength(row, rowLength);
802 if (err != 0)
return(-1);
804 int* tmpIndices = indices;
805 double* tmpCoefs = coefs;
807 if (len < rowLength) {
808 tmpIndices =
new int[rowLength];
809 tmpCoefs =
new double[rowLength];
813 A_ptr_->getRow(row, rowLength, tmpCoefs, tmpIndices);
816 fei::console_out() <<
"Aztec_LinSysCore::getMatrixRow: not implemented." << FEI_ENDL;
820 if (len < rowLength) {
821 for(
int i=0; i<len; i++) {
822 indices[i] = tmpIndices[i];
823 coefs[i] = tmpCoefs[i];
825 delete [] tmpIndices;
833 int Aztec_LinSysCore::sumIntoBlockRow(
int numBlkRows,
const int* blkRows,
834 int numBlkCols,
const int* blkCols,
835 const double*
const* values,
837 bool overwriteInsteadOfAccumulate)
844 for(i=0; i<numBlkRows; i++) {
845 int thisSize = lookup_->getBlkEqnSize(blkRows[i]);
847 if (maxBlkSize < thisSize) maxBlkSize = thisSize;
852 double* coefs =
new double[numPtCols*maxBlkSize];
855 for(i=0; i<numBlkRows; i++) {
857 copyBlockRow(i, blkRows, numBlkCols, blkCols, &(values[rowOffset]), coefs);
860 if (overwriteInsteadOfAccumulate) {
861 int err = blkA_ptr_->putBlockRow(blkRows[i], coefs,
862 (
int*)blkCols, numBlkCols);
864 fei::console_out() << thisProc_ <<
" DVBR::putBlockRow failed." << FEI_ENDL;
869 int err = blkA_ptr_->sumIntoBlockRow(blkRows[i], coefs,
870 (
int*)blkCols, numBlkCols);
872 fei::console_out() << thisProc_ <<
" DVBR::sumIntoBlockRow failed." << FEI_ENDL;
877 rowOffset += lookup_->getBlkEqnSize(blkRows[i]);
885 int Aztec_LinSysCore::copyBlockRow(
int i,
const int* blkRows,
886 int numBlkCols,
const int* blkCols,
887 const double*
const* values,
890 int rowSize = 0, colSize = 0;
895 for(
int b=0; b<numBlkCols; b++) {
897 int err = blkA_ptr_->getBlockSize(blkRows[i], blkCols[b],
900 fei::console_out() <<
"Aztec_LSC:copyBlockRow: ERROR in getBlockSize" << FEI_ENDL;
904 for(
int j=colOffset; j<colOffset+colSize; j++) {
905 for(
int r=0; r<rowSize; r++) {
906 coefs[coefOffset++] = values[r][j];
909 colOffset += colSize;
915 int Aztec_LinSysCore::getBlockSize(
int blkInd) {
917 int localBlkRow = blkInd - localBlkOffset_;
918 if (localBlkRow >= 0 && localBlkRow < numLocalEqnBlks_) {
920 return(localBlockSizes_[localBlkRow]);
926 int numRemoteBlocks = blkA_ptr_->getNumRemoteBlocks();
927 int* remoteInds = blkA_ptr_->getRemoteBlockIndices();
928 int* remoteSizes = blkA_ptr_->getRemoteBlockSizes();
933 messageAbort(
"getBlockSize: can't find blkInd.");
935 return(remoteSizes[index]);
940 int Aztec_LinSysCore::sumIntoPointRow(
int numPtRows,
const int* ptRows,
941 int numPtCols,
const int* ptColIndices,
942 const double*
const* values,
943 bool overwriteInsteadOfAccumulate)
947 fprintf(debugFile_,
"sumIntoPointRow, %d rows\n", numPtRows);
948 for(i=0; i<numPtRows; ++i) {
949 for(j=0; j<numPtCols; ++j) {
950 fprintf(debugFile_,
" sipr row %d, col %d, value: %e\n", ptRows[i],
951 ptColIndices[j], values[i][j]);
958 if (overwriteInsteadOfAccumulate) {
959 for(i=0; i<numPtRows; ++i) {
960 CHK_ERR( A_ptr_->putRow(ptRows[i], numPtCols, values[i], ptColIndices) );
964 int err = A_ptr_->sumIntoRow(numPtRows, ptRows, numPtCols, ptColIndices,
967 FEI_OSTRINGSTREAM osstr;
968 osstr <<
"Aztec_LinSysCore::sumIntoPointRow ERROR calling A_ptr->sumIntoRow";
969 throw std::runtime_error(osstr.str());
977 messageAbort(
"sumIntoPointRow: need lookup object, don't have it.");
980 int* blkIntData =
new int[numPtRows*2 + numPtCols*2];
981 int* blkRows = blkIntData;
982 int* blkRowOffsets = blkIntData+numPtRows;
983 int* blkCols = blkIntData+2*numPtRows;
984 int* blkColOffsets = blkIntData+2*numPtRows+numPtCols;;
988 for(i=0; i<numPtRows; i++) {
989 blkRows[i] = lookup_->ptEqnToBlkEqn(ptRows[i]);
990 blkRowOffsets[i] = lookup_->getOffsetIntoBlkEqn(blkRows[i], ptRows[i]);
993 for(i=0; i<numPtCols; i++) {
994 blkCols[i] = lookup_->ptEqnToBlkEqn(ptColIndices[i]);
995 if (blkCols[i] < 0) {
996 fei::console_out() << thisProc_ <<
" lookup ptEqnToBlkEqn("<<ptColIndices[i]<<
"): "
997 << blkCols[i] << FEI_ENDL;
998 messageAbort(
"negative blk-col");
1001 blkColOffsets[i] = lookup_->getOffsetIntoBlkEqn(blkCols[i], ptColIndices[i]);
1004 for(i=0; i<numPtRows; i++) {
1005 for(j=0; j<numPtCols; j++) {
1006 sumPointIntoBlockRow(blkRows[i], blkRowOffsets[i],
1007 blkCols[j], blkColOffsets[j], values[i][j]);
1011 delete [] blkIntData;
1016 int Aztec_LinSysCore::sumPointIntoBlockRow(
int blkRow,
int rowOffset,
1017 int blkCol,
int colOffset,
1020 int rowSize = lookup_->getBlkEqnSize(blkRow);
1021 int colSize = lookup_->getBlkEqnSize(blkCol);
1023 int len = rowSize*colSize;
1025 fei::console_out() << thisProc_ <<
", ALSC::spibr: blkRow: " << blkRow <<
", blkCol: " << blkCol <<
", rowSize: " << rowSize <<
", colSize: " << colSize << FEI_ENDL;
1026 messageAbort(
"sumPointIntoBlockRow: len <= 0");
1029 double* val =
new double[rowSize*colSize];
1031 for(
int i=0; i<len; i++) val[i] = 0.0;
1033 val[colOffset*rowSize + rowOffset] = value;
1035 int err = blkA_ptr_->sumIntoBlockRow(blkRow, val, &blkCol, 1);
1037 fei::console_out() << thisProc_ <<
" DVBR::sumIntoBlockRow failed" << FEI_ENDL;
1046 int Aztec_LinSysCore::sumIntoRHSVector(
int num,
1047 const double* values,
1059 double* cur_b = tmp_b_[currentRHS_];
1062 for(
int i=0; i<num; ++i) {
1063 fprintf(debugFile_,
"sumIntoRHS %d, %e\n", indices[i], values[i]);
1068 for(
int i=0; i<num; i++){
1069 int localRow = indices[i] - localOffset_;
1070 if (localRow < 0 || localRow > numLocalEqns_)
continue;
1072 cur_b[localRow] += values[i];
1078 int Aztec_LinSysCore::putIntoRHSVector(
int num,
const double* values,
1091 for(
int i=0; i<num; i++){
1092 int localRow = indices[i] - localOffset_;
1093 if (localRow < 0 || localRow > numLocalEqns_)
continue;
1096 fprintf(debugFile_,
"putIntoRHS %d, %e\n", indices[i], values[i]);
1100 tmp_b_[currentRHS_][localRow] = values[i];
1106 int Aztec_LinSysCore::getFromRHSVector(
int num,
double* values,
1121 for(
int i=0; i<num; i++){
1122 int localRow = indices[i] - localOffset_;
1123 if (localRow < 0 || localRow > numLocalEqns_)
continue;
1125 values[i] = tmp_b_[currentRHS_][localRow];
1131 int Aztec_LinSysCore::matrixLoadComplete() {
1134 fprintf(debugFile_,
"matrixLoadComplete\n");
1138 if (matrixLoaded_ && rhsLoaded_)
return(0);
1141 int* data_org = NULL;
1150 if (!matrixLoaded_) {
1152 if (!blkA_ptr_->isLoaded()) blkA_ptr_->loadComplete();
1155 if (!A_ptr_->isFilled()) {
1156 A_ptr_->fillComplete();
1160 matrixLoaded_ =
true;
1162 needNewPreconditioner_ =
true;
1165 if (blockMatrix_) data_org = blkA_ptr_->getData_org();
1166 else data_org = A_ptr_->getAZ_MATRIX_PTR()->data_org;
1168 Aztec_LSVector* tmp = NULL;
1174 tmp =
new Aztec_LSVector(*x_);
1179 if (x_ == NULL) x_ =
new Aztec_LSVector(tmpMap, data_org);
1180 if (bc_ == NULL) bc_ =
new Aztec_LSVector(tmpMap, data_org);
1189 if (tmp_bc_ != NULL) {
1190 for(
int j=0; j<numEssBCs_; j++) {
1191 int index = essBCindices_[j];
1192 (*bc_)[index] = tmp_bc_[index-localOffset_];
1196 if (tmp_x_touched_) {
1200 for(
int i=0; i<numLocalEqns_; i++){
1201 (*x_)[i+localOffset_] = tmp_x_[i];
1208 if (blockMatrix_) azA_ = blkA_ptr_->getAZ_MATRIX_Ptr();
1209 else azA_ = A_ptr_->getAZ_MATRIX_PTR();
1211 if (rhsLoaded_)
return(0);
1214 for(
int i=0; i<numRHSs_; i++)
delete b_[i];
1218 b_ =
new Aztec_LSVector*[numRHSs_];
1219 for(
int j=0; j<numRHSs_; j++) {
1220 b_[j] =
new Aztec_LSVector(tmpMap, data_org);
1221 if (b_[j] == NULL)
return(-1);
1224 for(
int i=0; i<numLocalEqns_; i++){
1225 (*(b_[j]))[i+localOffset_] = tmp_b_[j][i];
1229 b_ptr_ = b_[currentRHS_];
1230 vectorsAllocated_ =
true;
1232 if (!bcsLoaded_) modifyRHSforBCs();
1238 fprintf(debugFile_,
"leaving matrixLoadComplete\n");
1245 int Aztec_LinSysCore::getBlkEqnsAndOffsets(
int* ptEqns,
int* blkEqns,
1246 int* blkOffsets,
int numEqns)
1248 if (!haveLookup_) messageAbort(
"getBlkEqnsAndOffsets: don't have Lookup");
1250 for(
int i=0; i<numEqns; i++) {
1251 blkEqns[i] = lookup_->ptEqnToBlkEqn(ptEqns[i]);
1252 if (blkEqns[i] < 0) {
1253 fei::console_out() << thisProc_ <<
"ptEqn: " << ptEqns[i] <<
", blkEqn: " << blkEqns[i]
1255 messageAbort(
"getBlkEqnsAndOffsets: blk-eqn lookup failed.");
1258 blkOffsets[i] = lookup_->getOffsetIntoBlkEqn(blkEqns[i], ptEqns[i]);
1259 if (blkOffsets[i] < 0) {
1260 messageAbort(
"getBlkEqnsAndOffsets: blk-offset lookup failed.");
1267 int Aztec_LinSysCore::enforceEssentialBC(
int* globalEqn,
1269 double* gamma,
int len)
1286 if (len == 0)
return(0);
1288 std::vector<int> bcEqns; bcEqns.reserve(len);
1289 std::vector<int> indirect; indirect.reserve(len);
1290 for(
int i=0; i<len; ++i) {
1291 bcEqns.push_back(globalEqn[i]);
1292 indirect.push_back(i);
1295 fei::insertion_sort_with_companions<int>(len, &bcEqns[0], &indirect[0]);
1298 fprintf(debugFile_,
"numEssBCs: %d\n", len);
1299 for(
int ii=0; ii<len; ++ii) {
1300 fprintf(debugFile_,
" EssBC eqn %d, alpha %e gamma %e\n",
1301 bcEqns[ii], alpha[indirect[ii]], gamma[indirect[ii]]);
1308 int localEnd = localOffset_ + numLocalEqns_ - 1;
1311 fprintf(debugFile_,
"localOffset_: %d, localEnd: %d\n", localOffset_, localEnd);
1316 int* newBCindices =
new int[numEssBCs_+len];
1318 for(ii=0; ii<numEssBCs_; ii++) newBCindices[ii] = essBCindices_[ii];
1320 for(ii=0; ii<len; ii++) {
1321 if ((localOffset_ <= globalEqn[ii]) && (globalEqn[ii] <= localEnd)){
1322 newBCindices[numEssBCs_+offset++] = globalEqn[ii];
1327 delete [] essBCindices_;
1328 essBCindices_ = newBCindices;
1329 numEssBCs_ += offset;
1332 delete [] newBCindices;
1337 int* blkIntData =
new int[len*2];
1338 int* blkEqns = blkIntData;
1339 int* blkOffsets = blkIntData+len;
1341 getBlkEqnsAndOffsets(globalEqn, blkEqns, blkOffsets, len);
1343 enforceBlkEssentialBC(blkEqns, blkOffsets, alpha, gamma, len);
1345 delete [] blkIntData;
1350 for(
int i=0; i<len; i++) {
1352 int globalEqn_i = bcEqns[i];
1357 if ((localOffset_ > globalEqn_i) || (globalEqn_i > localEnd))
continue;
1360 A_ptr_->setDiagEntry(globalEqn_i, 1.0);
1361 int* offDiagIndices = NULL;
1362 double* offDiagCoefs = NULL;
1363 int offDiagLength = 0;
1364 A_ptr_->getOffDiagRowPointers(globalEqn_i, offDiagIndices,
1365 offDiagCoefs, offDiagLength);
1367 for(
int jjj=0; jjj<offDiagLength; jjj++) offDiagCoefs[jjj] = 0.0;
1370 double bc_term = gamma[indirect[i]]/alpha[indirect[i]];
1371 double rhs_term = bc_term;
1372 if (explicitDirichletBCs_) rhs_term = 0.0;
1375 (*b_ptr_)[globalEqn_i] = rhs_term;
1376 (*bc_)[globalEqn_i] = bc_term;
1379 tmp_b_[currentRHS_][globalEqn_i -localOffset_] = rhs_term;
1380 tmp_bc_[globalEqn_i -localOffset_] = bc_term;
1384 if (BCenforcement_no_column_mod_ ==
true) {
1388 for(
int row=localOffset_; row<=localEnd; row++) {
1390 int insertPoint = -1;
1392 if (index >= 0)
continue;
1394 int* offDiagIndices2 = NULL;
1395 double* offDiagCoefs2 = NULL;
1396 int offDiagLength2 = 0;
1397 A_ptr_->getOffDiagRowPointers(row, offDiagIndices2,
1398 offDiagCoefs2, offDiagLength2);
1403 for(
int j=0; j<offDiagLength2; j++) {
1405 int col_index = A_ptr_->getAztec_Map()->getTransformedEqn(offDiagIndices2[j]);
1408 if (idx < 0)
continue;
1410 double bc_term = gamma[indirect[idx]]/alpha[indirect[idx]];
1412 double value = offDiagCoefs2[j]*bc_term;
1415 (*b_ptr_)[row] -= value;
1418 tmp_b_[currentRHS_][row-localOffset_] -= value;
1422 fprintf(debugFile_,
"BC mod, rhs %d -= %e\n", row, value);
1423 fprintf(debugFile_,
"BC, set A(%d,%d)==%e, to 0.0\n",
1424 row, bcEqns[idx], offDiagCoefs2[j]);
1427 offDiagCoefs2[j] = 0.0;
1437 int Aztec_LinSysCore::enforceBlkEssentialBC(
int* blkEqn,
1464 int colInd_length = 0;
1465 int* blkCols = NULL;
1466 int rowNNZs = 0, numCols = 0, err = 0;
1468 double* val2 = NULL;
1469 int val2Len = val_length;
1471 int cols2Len = colInd_length;
1473 int localEnd = localBlkOffset_ + numLocalEqnBlks_ - 1;
1475 for(
int i=0; i<len; i++) {
1480 if ((localBlkOffset_ > blkEqn[i]) || (blkEqn[i] > localEnd)){
1484 err = getBlockRow(blkEqn[i], val, val_length, blkCols, colInd_length,
1493 err = blkRowEssBCMod(blkEqn[i], blkOffset[i], val, blkCols, numCols,
1494 rowNNZs, alpha[i], gamma[i]);
1496 blkA_ptr_->putBlockRow(blkEqn[i], val, blkCols, numCols);
1508 for(
int j=0; j<numCols; j++) {
1510 int col_row = blkCols[j];
1513 if ((localOffset_ > col_row) || (col_row > localEnd))
continue;
1516 if (col_row == blkEqn[i])
continue;
1519 int thisNumBlks = 0;
1520 err = getBlockRow(col_row, val2, val2Len, cols2, cols2Len,
1521 thisNumBlks, thisNNZ);
1523 err = blkColEssBCMod(col_row, blkEqn[i], blkOffset[i], val2, cols2,
1524 thisNumBlks, thisNNZ, alpha[i], gamma[i]);
1526 blkA_ptr_->putBlockRow(col_row, val2, cols2, thisNumBlks);
1539 int Aztec_LinSysCore::blkRowEssBCMod(
int blkEqn,
int blkOffset,
double* val,
1540 int* blkCols,
int numCols,
int numPtNNZ,
1541 double alpha,
double gamma)
1550 int pointRow = blockRowToPointRow(blkEqn);
1554 for(
int j=0; j<numCols; j++) {
1556 int err, ptRows = 0, ptCols = 0;
1557 err = blkA_ptr_->getBlockSize(blkEqn, blkCols[j], ptRows, ptCols);
1560 fei::console_out() <<
"Aztec_LSC::blkRowEssBCMod: error in getBlockSize" << FEI_ENDL;
1564 if (blkCols[j] == blkEqn) {
1568 double bc_term = gamma/alpha;
1569 double rhs_term = bc_term;
1570 if (explicitDirichletBCs_) rhs_term = 0.0;
1572 int thisOffset = offset;
1574 for(
int jj=0; jj<ptCols; jj++) {
1575 if (jj==blkOffset) {
1581 for(
int row=0; row<ptRows; row++) {
1582 if (row==blkOffset) {
1584 (*b_ptr_)[pointRow+row] = rhs_term;
1585 (*bc_)[pointRow+row] = bc_term;
1588 tmp_b_[currentRHS_][pointRow+row-localOffset_] = rhs_term;
1589 tmp_bc_[pointRow+row-localOffset_] = bc_term;
1591 val[thisOffset+row] = 1.0;
1595 (*b_ptr_)[pointRow+row] -= val[thisOffset+row]
1599 tmp_b_[currentRHS_][pointRow+row-localOffset_] -= val[thisOffset+row]*bc_term;
1601 val[thisOffset+row] = 0.0;
1606 val[thisOffset+blkOffset] = 0.0;
1609 thisOffset += ptRows;
1615 int thisOffset = offset + blkOffset;
1616 for(
int ii=0; ii<ptCols; ii++) {
1617 val[thisOffset] = 0.0;
1618 thisOffset += ptRows;
1622 offset += ptRows*ptCols;
1629 int Aztec_LinSysCore::blkColEssBCMod(
int blkRow,
int blkEqn,
int blkOffset,
1630 double* val,
int* blkCols,
int numCols,
1631 int numPtNNZ,
double alpha,
double gamma)
1640 int thisPtRow = blockRowToPointRow(blkRow);
1641 int thisRowSize = 0, thisColSize = 0;
1645 int err, offset = 0;
1646 for(
int j=0; j<numCols; j++) {
1647 err = blkA_ptr_->getBlockSize(blkRow, blkCols[j],
1648 thisRowSize, thisColSize);
1651 fei::console_out() <<
"Aztec_LinSysCore::blkColEssBCMod: ERROR in getBlockSize" << FEI_ENDL;
1655 if (blkCols[j] == blkEqn) {
1656 double bc_term = gamma/alpha;
1658 int thisOffset = offset + blkOffset*thisRowSize;
1660 for(
int row=0; row<thisRowSize; row++) {
1662 (*b_ptr_)[thisPtRow+row] -= val[thisOffset+row] * bc_term;
1665 tmp_b_[currentRHS_][thisPtRow+row-localOffset_] -=
1666 val[thisOffset+row]*bc_term;
1668 val[thisOffset+row] = 0.0;
1674 offset += thisRowSize*thisColSize;
1681 int Aztec_LinSysCore::blockRowToPointRow(
int blkRow) {
1686 int localBlkRow = blkRow - localBlkOffset_;
1688 if (localBlkRow < 0 || localBlkRow > numLocalEqnBlks_)
return(-1);
1691 for(
int i=0; i<localBlkRow; i++) {
1692 localPtRow += localBlockSizes_[i];
1695 int pointRow = localPtRow + localOffset_;
1700 int Aztec_LinSysCore::getBlockRow(
int blkRow,
double*& val,
int& valLen,
1701 int*& blkColInds,
int& blkColIndLen,
1702 int& numNzBlks,
int& numNNZ) {
1711 int err = blkA_ptr_->getNumNonzerosPerRow(blkRow, numNNZ);
1713 fei::console_out() <<
"Aztec_LSC::getBlockRow: ERROR in getNumNonzerosPerRow" << FEI_ENDL;
1718 err = blkA_ptr_->getNumBlocksPerRow(blkRow, numNzBlks);
1720 fei::console_out() <<
"Aztec_LSC::getBlockRow: ERROR in getNumBlocksPerRow" << FEI_ENDL;
1724 if (numNNZ > valLen) {
1725 double* newVals =
new double[numNNZ];
1731 if (numNzBlks > blkColIndLen) {
1732 int* newCols =
new int[numNzBlks];
1733 delete [] blkColInds;
1734 blkColInds = newCols;
1735 blkColIndLen = numNzBlks;
1738 err = blkA_ptr_->getBlockRow(blkRow, val, blkColInds, numNzBlks);
1744 int Aztec_LinSysCore::enforceRemoteEssBCs(
int numEqns,
int* globalEqns,
1745 int** colIndices,
int* colIndLen,
1753 for(
int i=0; i<numEqns; ++i) {
1754 fprintf(debugFile_,
"remBC row %d, (cols,coefs): ", globalEqns[i]);
1755 for(
int j=0; j<colIndLen[i]; ++j) {
1756 fprintf(debugFile_,
"(%d,%e) ",colIndices[i][j], coefs[i][j]);
1758 fprintf(debugFile_,
"\n");
1764 int* blkEqns =
new int[numEqns];
1765 int* blkOffsets =
new int[numEqns];
1767 getBlkEqnsAndOffsets(globalEqns, blkEqns, blkOffsets, numEqns);
1769 int** blkCols =
new int*[numEqns];
1770 int** blkColOffsets =
new int*[numEqns];
1772 for(
int i=0; i<numEqns; i++) {
1773 blkCols[i] =
new int[colIndLen[i]];
1774 blkColOffsets[i] =
new int[colIndLen[i]];
1776 getBlkEqnsAndOffsets(colIndices[i], blkCols[i], blkColOffsets[i],
1780 enforceBlkRemoteEssBCs(numEqns, blkEqns, blkCols, blkColOffsets,
1784 delete [] blkOffsets;
1786 for(
int j=0; j<numEqns; j++) {
1787 delete [] blkCols[j];
1788 delete [] blkColOffsets[j];
1791 delete [] blkColOffsets;
1796 int localEnd = localOffset_ + numLocalEqns_ - 1;
1798 for(
int i=0; i<numEqns; i++) {
1799 int globalEqn_i = globalEqns[i];
1801 if ((localOffset_ > globalEqn_i) || (globalEqn_i > localEnd)){
1806 int* AcolInds = NULL;
1807 double* Acoefs = NULL;
1809 A_ptr_->getOffDiagRowPointers(globalEqn_i, AcolInds, Acoefs, rowLen);
1811 for(
int j=0; j<colIndLen[i]; j++) {
1812 for(
int k=0; k<rowLen; k++) {
1813 if (A_ptr_->getAztec_Map()->getTransformedEqn(AcolInds[k]) == colIndices[i][j]) {
1814 double value = Acoefs[k]*coefs[i][j];
1816 double old_rhs_val = 0.0;
1818 old_rhs_val = (*b_ptr_)[globalEqn_i];
1819 (*b_ptr_)[globalEqn_i] -= value;
1822 old_rhs_val = tmp_b_[currentRHS_][globalEqn_i -localOffset_];
1823 tmp_b_[currentRHS_][globalEqn_i -localOffset_] -= value;
1827 fprintf(debugFile_,
"remBC mod, rhs %d (%e) -= %e\n",
1828 globalEqn_i, old_rhs_val, value);
1829 fprintf(debugFile_,
"remBC, set A(%d,%d)==%e, to 0.0\n",
1830 globalEqn_i, AcolInds[k], Acoefs[k]);
1844 int Aztec_LinSysCore::enforceBlkRemoteEssBCs(
int numEqns,
int* blkEqns,
1845 int** blkColInds,
int** blkColOffsets,
1846 int* blkColLens,
double** remEssBCCoefs) {
1849 int colInd_length = 0;
1850 int* blkCols = NULL;
1851 int rowNNZs = 0, numCols = 0, err = 0;
1853 int localEnd = localBlkOffset_ + numLocalEqnBlks_ - 1;
1855 for(
int i=0; i<numEqns; i++) {
1856 if ((localBlkOffset_ > blkEqns[i]) || (blkEqns[i] > localEnd)){
1860 err = getBlockRow(blkEqns[i], val, val_length, blkCols, colInd_length,
1863 fei::console_out() <<
"Aztec_LSC:enforceBlkRemoteEssBC ERROR in getBlockRow" << FEI_ENDL;
1870 int pointRow = blockRowToPointRow(blkEqns[i]);
1874 for(
int j=0; j<numCols; j++) {
1875 int ptRows = 0, ptCols = 0;
1876 err = blkA_ptr_->getBlockSize(blkEqns[i], blkCols[j],
1879 fei::console_out() <<
"Aztec_LSC::enforceBlkRemoteEssBCs: error in getBlockSize"
1884 for(
int k=0; k<blkColLens[i]; k++) {
1885 if (blkColInds[i][k] == blkCols[j]) {
1886 int thisOffset = offset + blkColOffsets[i][k] * ptRows;
1887 double rhsTerm = remEssBCCoefs[i][k];
1889 double* bvec = &(tmp_b_[currentRHS_][pointRow-localOffset_]);
1890 double* bcvec = &(tmp_bc_[pointRow-localOffset_]);
1891 for(
int row=0; row<ptRows; row++) {
1892 double& coef = val[thisOffset+row];
1893 bvec[row] -= coef*rhsTerm;
1894 bcvec[row] -= coef*rhsTerm;
1898 blkA_ptr_->putBlockRow(blkEqns[i], &val[offset],
1903 offset += ptRows*ptCols;
1913 int Aztec_LinSysCore::getMatrixPtr(
Data& data)
1915 if (!matrixLoaded_) matrixLoadComplete();
1929 int Aztec_LinSysCore::copyInMatrix(
double scalar,
const Data& data) {
1935 if (strcmp(
"AztecDVBR_Matrix", data.
getTypeName()))
1936 messageAbort(
"copyInMatrix: data type string not 'AztecDVBR_Matrix'.");
1938 AztecDVBR_Matrix* source = (AztecDVBR_Matrix*)data.
getDataPtr();
1940 if (blkA_ != NULL)
delete blkA_;
1941 blkA_ =
new AztecDVBR_Matrix(*source);
1944 VBRmatPlusScaledMat(blkA_ptr_, scalar, source);
1946 azA_ = blkA_ptr_->getAZ_MATRIX_Ptr();
1949 if (strcmp(
"AztecDMSR_Matrix", data.
getTypeName()))
1950 messageAbort(
"copyInMatrix: data type string not 'AztecDMSR_Matrix'.");
1952 AztecDMSR_Matrix* source = (AztecDMSR_Matrix*)data.
getDataPtr();
1953 A_ptr_->copyStructure(*source);
1955 MSRmatPlusScaledMat(A_ptr_, scalar, source);
1957 azA_ = A_ptr_->getAZ_MATRIX_PTR();
1960 needNewPreconditioner_ =
true;
1965 int Aztec_LinSysCore::copyOutMatrix(
double scalar,
Data& data) {
1970 if (!matrixLoaded_) matrixLoadComplete();
1973 AztecDVBR_Matrix* outmat =
new AztecDVBR_Matrix(*blkA_ptr_);
1978 VBRmatPlusScaledMat(outmat, scalar, blkA_ptr_);
1984 AztecDMSR_Matrix* outmat =
new AztecDMSR_Matrix(*A_ptr_);
1986 outmat->scale(scalar);
1995 int Aztec_LinSysCore::sumInMatrix(
double scalar,
const Data& data) {
1997 if (!matrixLoaded_) matrixLoadComplete();
2000 if (strcmp(
"AztecDVBR_Matrix", data.
getTypeName())) {
2001 fei::console_out() <<
"Aztec_LinSysCore::sumInMatrix ERROR, incoming type-string: "
2002 << data.
getTypeName() <<
", expected AztecDVBR_Matrix." << FEI_ENDL;
2003 messageAbort(
"Aborting.");
2005 AztecDVBR_Matrix* source = (AztecDVBR_Matrix*)data.
getDataPtr();
2007 VBRmatPlusScaledMat(blkA_ptr_, scalar, source);
2010 if (strcmp(
"AztecDMSR_Matrix", data.
getTypeName()))
2011 messageAbort(
"sumInMatrix: data type string not 'AztecDMSR_Matrix'.");
2013 AztecDMSR_Matrix* source = (AztecDMSR_Matrix*)data.
getDataPtr();
2015 MSRmatPlusScaledMat(A_ptr_, scalar, source);
2018 needNewPreconditioner_ =
true;
2023 int Aztec_LinSysCore::getRHSVectorPtr(
Data& data) {
2025 if (!matrixLoaded_) matrixLoadComplete();
2033 int Aztec_LinSysCore::copyInRHSVector(
double scalar,
const Data& data) {
2035 if (!rhsLoaded_) matrixLoadComplete();
2038 messageAbort(
"copyInRHSVector: data's type string not 'Aztec_LSVector'.");
2040 Aztec_LSVector* sourcevec = (Aztec_LSVector*)data.
getDataPtr();
2042 *b_ptr_ = *sourcevec;
2044 if (scalar != 1.0) b_ptr_->scale(scalar);
2049 int Aztec_LinSysCore::copyOutRHSVector(
double scalar,
Data& data) {
2051 if (!rhsLoaded_) matrixLoadComplete();
2053 Aztec_LSVector* outvec =
new Aztec_LSVector(*b_ptr_);
2057 outvec->addVec(scalar, *b_ptr_);
2065 int Aztec_LinSysCore::sumInRHSVector(
double scalar,
const Data& data) {
2067 if (!rhsLoaded_) matrixLoadComplete();
2070 messageAbort(
"sumInRHSVector: data's type string not 'Aztec_LSVector'.");
2072 Aztec_LSVector* source = (Aztec_LSVector*)data.
getDataPtr();
2074 b_ptr_->addVec(scalar, *source);
2079 int Aztec_LinSysCore::destroyMatrixData(
Data& data) {
2082 if (strcmp(
"AztecDVBR_Matrix", data.
getTypeName()))
2083 messageAbort(
"destroyMatrixData: data doesn't contain a AztecDVBR_Matrix.");
2085 AztecDVBR_Matrix* mat = (AztecDVBR_Matrix*)data.
getDataPtr();
2089 if (strcmp(
"AztecDMSR_Matrix", data.
getTypeName()))
2090 messageAbort(
"destroyMatrixData: data doesn't contain a AztecDMSR_Matrix.");
2092 AztecDMSR_Matrix* mat = (AztecDMSR_Matrix*)data.
getDataPtr();
2099 int Aztec_LinSysCore::destroyVectorData(
Data& data) {
2102 messageAbort(
"destroyVectorData: data doesn't contain a Aztec_LSVector.");
2104 Aztec_LSVector* vec = (Aztec_LSVector*)data.
getDataPtr();
2110 int Aztec_LinSysCore::setNumRHSVectors(
int numRHSs,
const int* rhsIDs) {
2113 messageAbort(
"setNumRHSVectors: numRHSs < 0.");
2115 if (numRHSs == 0)
return(0);
2119 rhsIDs_ =
new int[numRHSs_];
2121 for(
int i=0; i<numRHSs_; i++) rhsIDs_[i] = rhsIDs[i];
2126 int Aztec_LinSysCore::setRHSID(
int rhsID) {
2128 for(
int i=0; i<numRHSs_; i++){
2129 if (rhsIDs_[i] == rhsID){
2131 if (rhsLoaded_) b_ptr_ = b_[currentRHS_];
2136 messageAbort(
"setRHSID: rhsID not found.");
2141 int Aztec_LinSysCore::putInitialGuess(
const int* eqnNumbers,
2142 const double* values,
2152 int localEnd = localOffset_ + numLocalEqns_ -1;
2153 if (matrixLoaded_) {
2154 for(
int i=0; i<len; i++){
2155 if ((localOffset_ > eqnNumbers[i]) || (eqnNumbers[i] > localEnd))
2158 (*x_)[eqnNumbers[i]] = values[i];
2162 tmp_x_touched_ =
true;
2163 for(
int i=0; i<len; i++){
2164 if ((localOffset_ > eqnNumbers[i]) || (eqnNumbers[i] > localEnd))
2166 tmp_x_[eqnNumbers[i]-localOffset_] = values[i];
2173 int Aztec_LinSysCore::getSolution(
double* answers,
int len) {
2179 if (len != numLocalEqns_)
2180 messageAbort(
"getSolution: len != numLocalEqns_.");
2182 for(
int i=0; i<numLocalEqns_; i++) {
2183 answers[i] = (*x_)[localOffset_ + i];
2189 int Aztec_LinSysCore::getSolnEntry(
int eqnNumber,
double& answer) {
2194 int localEnd = localOffset_ + numLocalEqns_ -1;
2195 if ((localOffset_ > eqnNumber) || (eqnNumber > localEnd))
2196 messageAbort(
"getSolnEntry: eqnNumber out of range.");
2198 answer = (*x_)[eqnNumber];
2203 int Aztec_LinSysCore::formResidual(
double* values,
int len)
2205 if (len != numLocalEqns_) {
2206 messageAbort(
"formResidual: len != numLocalEqns_.");
2209 if (!matrixLoaded_ || !rhsLoaded_) {
2210 matrixLoadComplete();
2217 int* update_index = NULL;
2219 update_index = blkA_ptr_->getUpdate_index();
2222 update_index = A_ptr_->getAztec_Map()->update_index;
2225 AZ_reorder_vec((
double*)(x_->startPointer()), azA_->data_org, update_index,
2228 AZ_reorder_vec((
double*)(b_ptr_->startPointer()), azA_->data_org,
2229 update_index, azA_->rpntr);
2231 Aztec_LSVector* r =
new Aztec_LSVector(*x_);
2233 if (blockMatrix_) blkA_ptr_->matvec(*x_, *r);
2234 else A_ptr_->matvec(*x_, *r);
2236 r->addVec(-1.0, *b_ptr_);
2242 Aztec_LSVector* rtmp =
new Aztec_LSVector(*x_);
2244 AZ_invorder_vec((
double*)(r->startPointer()), azA_->data_org, update_index,
2245 azA_->rpntr, (
double*)rtmp->startPointer());
2249 const double* rptr = r->startPointer();
2251 for(
int i=0; i<numLocalEqns_; i++) {
2252 values[i] = rptr[i];
2256 AZ_invorder_vec((
double*)(x_->startPointer()), azA_->data_org, update_index,
2257 azA_->rpntr, (
double*)rtmp->startPointer());
2261 AZ_invorder_vec((
double*)(b_ptr_->startPointer()), azA_->data_org,
2262 update_index, azA_->rpntr, (
double*)rtmp->startPointer());
2272 int Aztec_LinSysCore::selectSolver(
const char* name) {
2279 if (!strcmp(name,
"AZ_gmres")) {
2280 aztec_options_[AZ_solver] = AZ_gmres;
2281 sprintf(msg,
"AZ_gmres solver.");
2283 else if (!strcmp(name,
"AZ_cg")) {
2284 aztec_options_[AZ_solver] = AZ_cg;
2285 sprintf(msg,
"AZ_cg solver.");
2287 else if (!strcmp(name,
"AZ_bicgstab")) {
2288 aztec_options_[AZ_solver] = AZ_bicgstab;
2289 sprintf(msg,
"AZ_bicgstab solver.");
2291 else if (!strcmp(name,
"AZ_cgs")) {
2292 aztec_options_[AZ_solver] = AZ_cgs;
2293 sprintf(msg,
"AZ_cgs solver.");
2295 else if (!strcmp(name,
"AZ_tfqmr")) {
2296 aztec_options_[AZ_solver] = AZ_tfqmr;
2297 sprintf(msg,
"AZ_tfqmr solver.");
2299 else if (!strcmp(name,
"AZ_lu")) {
2300 aztec_options_[AZ_solver] = AZ_lu;
2301 sprintf(msg,
"AZ_lu solver.");
2304 aztec_options_[AZ_solver] = AZ_gmres;
2305 sprintf(msg,
"AZ_gmres default solver.");
2306 if (thisProc_ == 0) {
2307 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested solver <" << name <<
"> not recognized, defaulting to AZ_gmres." << FEI_ENDL;
2317 int Aztec_LinSysCore::selectPreconditioner(
const char* name) {
2320 sprintf(msg,
"selectPreconditioner(%s)", name);
2323 if (!strcmp(name,
"AZ_none")) {
2324 aztec_options_[AZ_precond] = AZ_none;
2325 sprintf(msg,
" -- selected: AZ_none.");
2327 else if (!strcmp(name,
"AZ_Jacobi")) {
2328 aztec_options_[AZ_precond] = AZ_Jacobi;
2329 sprintf(msg,
" -- selected: AZ_Jacobi.");
2331 else if (!strcmp(name,
"AZ_Neumann")) {
2332 aztec_options_[AZ_precond] = AZ_Neumann;
2333 sprintf(msg,
" -- selected: AZ_Neumann.");
2335 else if (!strcmp(name,
"AZ_ls")) {
2336 aztec_options_[AZ_precond] = AZ_ls;
2337 sprintf(msg,
" -- selected: AZ_ls.");
2339 else if (!strcmp(name,
"AZ_sym_GS")) {
2340 aztec_options_[AZ_precond] = AZ_sym_GS;
2341 sprintf(msg,
" -- selected: AZ_sym_GS.");
2343 else if (!strcmp(name,
"AZ_dom_decomp")) {
2344 aztec_options_[AZ_precond] = AZ_dom_decomp;
2345 sprintf(msg,
" -- selected: AZ_dom_decomp.");
2349 else if (!strcmp(name,
"ML_Vanek")) {
2351 aztec_options_[AZ_precond] = AZ_user_precond;
2352 sprintf(msg,
" -- selected: AZ_user_precond.");
2356 aztec_options_[AZ_precond] = AZ_none;
2357 sprintf(msg,
" -- selected: Default, AZ_none.\n");
2358 if (thisProc_ == 0) {
2359 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested preconditioner <" << name <<
"> not recognized, defaulting to AZ_none." << FEI_ENDL;
2369 void Aztec_LinSysCore::setSubdomainSolve(
const char* name) {
2372 sprintf(msg,
"setSubdomainSolve(%s)", name);
2375 if (!strcmp(name,
"AZ_lu")) {
2376 aztec_options_[AZ_subdomain_solve] = AZ_lu;
2377 sprintf(msg,
" -- selected AZ_lu");
2379 else if (!strcmp(name,
"AZ_ilu")) {
2380 aztec_options_[AZ_subdomain_solve] = AZ_ilu;
2381 sprintf(msg,
" -- selected AZ_ilu");
2383 else if (!strcmp(name,
"AZ_ilut")) {
2384 aztec_options_[AZ_subdomain_solve] = AZ_ilut;
2385 sprintf(msg,
" -- selected AZ_ilut");
2387 else if (!strcmp(name,
"AZ_rilu")) {
2388 aztec_options_[AZ_subdomain_solve] = AZ_rilu;
2389 sprintf(msg,
" -- selected AZ_rilu");
2391 else if (!strcmp(name,
"AZ_bilu")) {
2392 aztec_options_[AZ_subdomain_solve] = AZ_bilu;
2393 sprintf(msg,
" -- selected AZ_bilu");
2395 else if (!strcmp(name,
"AZ_icc")) {
2396 aztec_options_[AZ_subdomain_solve] = AZ_icc;
2397 sprintf(msg,
" -- selected AZ_icc");
2400 if (thisProc_ == 0) {
2401 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested subdomain-solve <" << name <<
"> not recognized." << FEI_ENDL;
2409 void Aztec_LinSysCore::setTypeOverlap(
const char* name) {
2412 sprintf(msg,
"setTypeOverlap(%s)", name);
2415 if (!strcmp(name,
"AZ_standard")) {
2416 aztec_options_[AZ_type_overlap] = AZ_standard;
2417 sprintf(msg,
" -- selected AZ_standard");
2419 else if (!strcmp(name,
"AZ_ilu")) {
2420 aztec_options_[AZ_type_overlap] = AZ_symmetric;
2421 sprintf(msg,
" -- selected AZ_symmetric");
2424 if (thisProc_ == 0) {
2425 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested type-overlap <" << name <<
"> not recognized." << FEI_ENDL;
2433 int Aztec_LinSysCore::writeSystem(
const char* name)
2440 void Aztec_LinSysCore::recordUserParams()
2442 checkForParam(
"AZ_tol", numParams_, paramStrings_,
2443 aztec_params_[AZ_tol]);
2445 checkForParam(
"AZ_drop", numParams_, paramStrings_,
2446 aztec_params_[AZ_drop]);
2448 checkForParam(
"AZ_ilut_fill", numParams_, paramStrings_,
2449 aztec_params_[AZ_ilut_fill]);
2451 checkForParam(
"AZ_omega", numParams_, paramStrings_,
2452 aztec_params_[AZ_omega]);
2454 checkForParam(
"AZ_weights", numParams_, paramStrings_,
2455 aztec_params_[AZ_weights]);
2459 void Aztec_LinSysCore::recordUserOptions()
2464 const char* param = NULL;
2466 param = snl_fei::getParamValue(
"AZ_solver", numParams_, paramStrings_);
2468 selectSolver(param);
2471 param = snl_fei::getParamValue(
"AZ_precond", numParams_, paramStrings_);
2473 selectPreconditioner(param);
2476 param = snl_fei::getParamValue(
"AZ_subdomain_solve",
2477 numParams_, paramStrings_);
2479 setSubdomainSolve(param);
2482 param = snl_fei::getParamValue(
"AZ_scaling", numParams_, paramStrings_);
2484 setScalingOption(param);
2487 param = snl_fei::getParamValue(
"AZ_conv", numParams_, paramStrings_);
2492 param = snl_fei::getParamValue(
"AZ_pre_calc",
2493 numParams_, paramStrings_);
2498 param = snl_fei::getParamValue(
"AZ_overlap", numParams_, paramStrings_);
2503 param = snl_fei::getParamValue(
"AZ_type_overlap",
2504 numParams_, paramStrings_);
2506 setTypeOverlap(param);
2509 param = snl_fei::getParamValue(
"AZ_orthog", numParams_, paramStrings_);
2514 param = snl_fei::getParamValue(
"AZ_aux_vec", numParams_, paramStrings_);
2519 param = snl_fei::getParamValue(
"AZ_output", numParams_, paramStrings_);
2521 setAZ_output(param);
2523 else aztec_options_[AZ_output] = outputLevel_;
2525 checkForOption(
"AZ_poly_ord", numParams_, paramStrings_,
2526 aztec_options_[AZ_poly_ord]);
2528 checkForOption(
"AZ_kspace", numParams_, paramStrings_,
2529 aztec_options_[AZ_kspace]);
2531 checkForOption(
"AZ_max_iter", numParams_, paramStrings_,
2532 aztec_options_[AZ_max_iter]);
2534 checkForOption(
"AZ_reorder", numParams_, paramStrings_,
2535 aztec_options_[AZ_reorder]);
2537 checkForOption(
"AZ_graph_fill", numParams_, paramStrings_,
2538 aztec_options_[AZ_graph_fill]);
2540 checkForOption(
"AZ_keep_info", numParams_, paramStrings_,
2541 aztec_options_[AZ_keep_info]);
2545 int Aztec_LinSysCore::writeA(
const char* name)
2551 FEI_OSTRINGSTREAM osstr;
2553 if (debugPath_ != NULL) {
2554 osstr << debugPath_;
2558 osstr <<
"/A_" << name <<
".mtx";
2560 if (blockMatrix_) osstr <<
".vbr";
2562 std::string str = osstr.str();
2563 const char* matname = str.c_str();
2566 blkA_ptr_->writeToFile(matname);
2569 A_ptr_->writeToFile(matname);
2576 int Aztec_LinSysCore::writeVec(Aztec_LSVector* v,
const char* name)
2578 if (name == NULL || v == NULL) {
2582 FEI_OSTRINGSTREAM osstr;
2584 if (debugPath_ != NULL) {
2585 osstr << debugPath_;
2589 osstr <<
"/" << name <<
".vec";
2591 std::string str = osstr.str();
2593 const char* vecname = str.c_str();
2595 v->writeToFile(vecname);
2601 int Aztec_LinSysCore::modifyRHSforBCs()
2603 if (explicitDirichletBCs_) {
2604 for(
int j=0; j<numEssBCs_; j++) {
2605 int index = essBCindices_[j];
2606 (*b_ptr_)[index] = 0.0;
2610 for(
int j=0; j<numEssBCs_; j++) {
2611 int index = essBCindices_[j];
2612 (*b_ptr_)[index] = tmp_bc_[index-localOffset_];
2620 int Aztec_LinSysCore::explicitlySetDirichletBCs()
2622 for(
int j=0; j<numEssBCs_; j++) {
2623 int index = essBCindices_[j];
2625 (*b_ptr_)[index] = (*bc_)[index];
2626 (*x_)[index] = (*bc_)[index];
2629 (*b_ptr_)[index] = tmp_bc_[index-localOffset_];
2630 (*x_)[index] = tmp_bc_[index-localOffset_];
2637 int Aztec_LinSysCore::launchSolver(
int& solveStatus,
int& iterations) {
2646 unsigned counter = 0;
2647 std::map<std::string,unsigned>::iterator
2648 iter = named_solve_counter_.find(name_);
2649 if (iter == named_solve_counter_.end()) {
2650 fei::console_out() <<
"fei: Aztec_LinSysCore::LaunchSolver: internal error."
2654 counter = iter->second++;
2657 if (debugOutput_ && outputLevel_ > 1) {
2658 FEI_OSTRINGSTREAM osstr;
2659 osstr << name_ <<
"_Aztec.np"<<numProcs_<<
".slv"<<counter;
2660 std::string str = osstr.str();
2662 writeA(str.c_str());
2664 FEI_OSTRINGSTREAM x0_osstr;
2665 x0_osstr <<
"x0_" << str;
2666 std::string x0_str = x0_osstr.str();
2668 writeVec(x_, x0_str.c_str());
2670 FEI_OSTRINGSTREAM b_osstr;
2671 b_osstr <<
"b_" << str;
2672 std::string b_str = b_osstr.str();
2674 writeVec(b_ptr_, b_str.c_str());
2677 if (needNewPreconditioner_) {
2678 if (precondCreated_) {
2679 AZ_precond_destroy(&azP_);
2687 int numFineSweeps = 2;
2688 int numCoarseSweeps = 2;
2689 double omega = 0.67;
2691 initialize_ML(azA_, &azP_, numLevels_,
2692 numFineSweeps, numCoarseSweeps, omega,
2693 map_->getProcConfig(), &ml);
2697 azA_->data_org[AZ_name] = 0;
2698 azP_ = AZ_precond_create(azA_, AZ_precondition, NULL);
2701 azA_->data_org[AZ_name] = 0;
2702 azP_ = AZ_precond_create(azA_, AZ_precondition, NULL);
2704 needNewPreconditioner_ =
false;
2705 aztec_options_[AZ_pre_calc] = AZ_calc;
2706 aztec_options_[AZ_conv] = AZ_rhs;
2707 aztec_options_[AZ_orthog] = AZ_modified;
2710 recordUserOptions();
2712 aztec_options_[AZ_keep_info] = 1;
2715 aztec_options_[AZ_pre_calc] = AZ_reuse;
2718 precondCreated_ =
true;
2720 int* proc_config = NULL;
2721 int* update_index = NULL;
2723 proc_config = blkMap_->getProcConfig();
2724 update_index = blkA_ptr_->getUpdate_index();
2727 proc_config = map_->getProcConfig();
2728 update_index = A_ptr_->getAztec_Map()->update_index;
2731 AZ_reorder_vec((
double*)(x_->startPointer()), azA_->data_org, update_index,
2734 AZ_reorder_vec((
double*)(b_ptr_->startPointer()), azA_->data_org,
2735 update_index, azA_->rpntr);
2737 AZ_iterate((
double*)(x_->startPointer()),
2738 (
double*)(b_ptr_->startPointer()),
2739 aztec_options_, aztec_params_, aztec_status_,
2740 proc_config, azA_, azP_, azS_);
2742 iterations = (int)aztec_status_[AZ_its];
2744 solveStatus = (int)aztec_status_[AZ_why];
2746 azlsc_solveCounter_++;
2748 Aztec_LSVector* xtmp =
new Aztec_LSVector(*x_);
2753 AZ_invorder_vec((
double*)(x_->startPointer()), azA_->data_org, update_index,
2754 azA_->rpntr, (
double*)xtmp->startPointer());
2759 AZ_invorder_vec((
double*)(b_ptr_->startPointer()), azA_->data_org,
2760 update_index, azA_->rpntr, (
double*)xtmp->startPointer());
2766 if (explicitDirichletBCs_) explicitlySetDirichletBCs();
2771 FEI_OSTRINGSTREAM osstr;
2772 osstr << name_ <<
"_Aztec.np"<<numProcs_<<
".slv"<<counter;
2773 std::string str = osstr.str();
2775 FEI_OSTRINGSTREAM x_osstr;
2776 x_osstr <<
"x_" << str;
2777 std::string x_str = x_osstr.str();
2779 writeVec(x_, x_str.c_str());
2781 for(
int j=0; j<numEssBCs_; j++) {
2782 int index = essBCindices_[j];
2784 (*bc_)[index] = 0.0;
2787 tmp_bc_[index-localOffset_] = 0.0;
2790 delete [] essBCindices_;
2791 essBCindices_ = NULL;
2798 void Aztec_LinSysCore::setScalingOption(
const char* param) {
2800 char* msg =
new char[128];
2801 for(
int i=0; i<128; i++) msg[i] =
'\0';
2803 if (!strcmp(param,
"AZ_none")) {
2804 aztec_options_[AZ_scaling] = AZ_none;
2805 sprintf(msg,
"No scaling");
2807 else if (!strcmp(param,
"AZ_Jacobi")) {
2808 aztec_options_[AZ_scaling] = AZ_Jacobi;
2809 sprintf(msg,
"AZ_Jacobi scaling");
2811 else if (!strcmp(param,
"AZ_BJacobi")) {
2812 aztec_options_[AZ_scaling] = AZ_BJacobi;
2813 sprintf(msg,
"AZ_BJacobi scaling");
2815 else if (!strcmp(param,
"AZ_row_sum")) {
2816 aztec_options_[AZ_scaling] = AZ_row_sum;
2817 sprintf(msg,
"AZ_row_sum scaling");
2819 else if (!strcmp(param,
"AZ_sym_diag")) {
2820 aztec_options_[AZ_scaling] = AZ_sym_diag;
2821 sprintf(msg,
"AZ_sym_diag scaling");
2823 else if (!strcmp(param,
"AZ_sym_row_sum")) {
2824 aztec_options_[AZ_scaling] = AZ_sym_row_sum;
2825 sprintf(msg,
"AZ_sym_row_sum scaling");
2828 if (thisProc_ == 0) {
2829 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested scaling <" << param <<
"> not recognized." << FEI_ENDL;
2841 void Aztec_LinSysCore::setConvTest(
const char* param) {
2845 if (!strcmp(param,
"AZ_r0")) {
2846 aztec_options_[AZ_conv] = AZ_r0;
2847 sprintf(msg,
"AZ_conv AZ_r0");
2849 else if (!strcmp(param,
"AZ_rhs")) {
2850 aztec_options_[AZ_conv] = AZ_rhs;
2851 sprintf(msg,
"AZ_conv AZ_rhs");
2853 else if (!strcmp(param,
"AZ_Anorm")) {
2854 aztec_options_[AZ_conv] = AZ_Anorm;
2855 sprintf(msg,
"AZ_conv AZ_Anorm");
2857 else if (!strcmp(param,
"AZ_sol")) {
2858 aztec_options_[AZ_conv] = AZ_sol;
2859 sprintf(msg,
"AZ_conv AZ_sol");
2861 else if (!strcmp(param,
"AZ_weighted")) {
2862 aztec_options_[AZ_conv] = AZ_weighted;
2863 sprintf(msg,
"AZ_conv AZ_weighted");
2865 else if (!strcmp(param,
"AZ_noscaled")) {
2866 aztec_options_[AZ_conv] = AZ_noscaled;
2867 sprintf(msg,
"AZ_conv AZ_noscaled");
2870 if (thisProc_ == 0) {
2871 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested convergence test <" << param <<
"> not recognized." << FEI_ENDL;
2881 void Aztec_LinSysCore::setPreCalc(
const char* param)
2885 if (!strcmp(param,
"AZ_calc")) {
2886 aztec_options_[AZ_pre_calc] = AZ_calc;
2887 sprintf(msg,
"AZ_pre_calc AZ_calc");
2889 else if (!strcmp(param,
"AZ_recalc")) {
2890 aztec_options_[AZ_pre_calc] = AZ_recalc;
2891 sprintf(msg,
"AZ_pre_calc AZ_recalc");
2893 else if (!strcmp(param,
"AZ_reuse")) {
2894 aztec_options_[AZ_pre_calc] = AZ_reuse;
2895 sprintf(msg,
"AZ_pre_calc AZ_reuse");
2898 if (thisProc_ == 0) {
2899 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested pre_calc <" << param <<
"> not recognized." << FEI_ENDL;
2909 void Aztec_LinSysCore::setOverlap(
const char* param)
2913 if (!strcmp(param,
"AZ_none")) {
2914 aztec_options_[AZ_overlap] = AZ_none;
2915 sprintf(msg,
"AZ_overlap AZ_none");
2917 else if (!strcmp(param,
"AZ_diag")) {
2918 aztec_options_[AZ_overlap] = AZ_diag;
2919 sprintf(msg,
"AZ_overlap AZ_diag");
2921 else if (!strcmp(param,
"AZ_full")) {
2922 aztec_options_[AZ_overlap] = AZ_full;
2923 sprintf(msg,
"AZ_overlap AZ_full");
2926 checkForOption(
"AZ_overlap", numParams_, paramStrings_,
2927 aztec_options_[AZ_overlap]);
2936 void Aztec_LinSysCore::setOrthog(
const char* param)
2940 if (!strcmp(param,
"AZ_classic")) {
2941 aztec_options_[AZ_orthog] = AZ_classic;
2942 sprintf(msg,
"AZ_orthog AZ_classic");
2944 else if (!strcmp(param,
"AZ_modified")) {
2945 aztec_options_[AZ_orthog] = AZ_modified;
2946 sprintf(msg,
"AZ_orthog AZ_modified");
2949 if (thisProc_ == 0) {
2950 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested orthog. <" << param <<
"> not recognized." << FEI_ENDL;
2960 void Aztec_LinSysCore::setAuxVec(
const char* param)
2964 if (!strcmp(param,
"AZ_resid")) {
2965 aztec_options_[AZ_aux_vec] = AZ_resid;
2966 sprintf(msg,
"AZ_aux_vec AZ_resid");
2968 else if (!strcmp(param,
"AZ_rand")) {
2969 aztec_options_[AZ_aux_vec] = AZ_rand;
2970 sprintf(msg,
"AZ_aux_vec AZ_rand");
2973 if (thisProc_ == 0) {
2974 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested aux_vec <" << param <<
"> not recognized." << FEI_ENDL;
2984 void Aztec_LinSysCore::setAZ_output(
const char* param)
2988 int num = sscanf(param,
"%d", &out);
2989 if (num == 1 && out > -1) {
2990 sprintf(msg,
"AZ_output %d", out);
2991 aztec_options_[AZ_output] = out;
2993 else if (!strcmp(param,
"AZ_all")) {
2994 aztec_options_[AZ_output] = AZ_all;
2995 sprintf(msg,
"AZ_output AZ_all");
2997 else if (!strcmp(param,
"AZ_none")) {
2998 aztec_options_[AZ_output] = AZ_none;
2999 sprintf(msg,
"AZ_output AZ_none");
3001 else if (!strcmp(param,
"AZ_warnings")) {
3002 aztec_options_[AZ_output] = AZ_warnings;
3003 sprintf(msg,
"AZ_output AZ_warnings");
3005 else if (!strcmp(param,
"AZ_last")) {
3006 aztec_options_[AZ_output] = AZ_last;
3007 sprintf(msg,
"AZ_output AZ_last");
3010 if (thisProc_ == 0) {
3011 FEI_COUT <<
"Aztec_LinSysCore: Warning: requested AZ_output <" << param <<
"> not recognized." << FEI_ENDL;
3021 void Aztec_LinSysCore::checkForParam(
const char* paramName,
3022 int numParams,
char** paramStrings,
3024 const char* parameter =
3025 snl_fei::getParamValue(paramName, numParams, paramStrings);
3026 if (parameter != NULL) {
3027 sscanf(parameter,
"%le", ¶m);
3032 void Aztec_LinSysCore::checkForOption(
const char* paramName,
3033 int numParams,
char** paramStrings,
3035 const char* parameter =
3036 snl_fei::getParamValue(paramName, numParams, paramStrings);
3037 if (parameter != NULL) {
3038 sscanf(parameter,
"%d", ¶m);
3043 void Aztec_LinSysCore::setDebugOutput(
const char* path,
const char* name){
3048 fprintf(debugFile_,
"setDebugOutput closing this file.");
3054 int pathLength = strlen(path);
3055 if (path != debugPath_) {
3056 delete [] debugPath_;
3057 debugPath_ =
new char[pathLength + 1];
3058 sprintf(debugPath_,
"%s", path);
3061 int nameLength = strlen(name);
3062 if (name != debugFileName_) {
3063 delete [] debugFileName_;
3064 debugFileName_ =
new char[nameLength + 1];
3065 sprintf(debugFileName_,
"%s",name);
3068 char* dbFileName =
new char[pathLength + nameLength + 3];
3070 sprintf(dbFileName,
"%s/%s", path, name);
3073 debugFile_ = fopen(dbFileName,
"w");
3076 fei::console_out() <<
"couldn't open debug output file: " << dbFileName << FEI_ENDL;
3078 delete [] debugPath_;
3080 delete [] debugFileName_;
3081 debugFileName_ = NULL;
3084 delete [] dbFileName;
3088 int Aztec_LinSysCore::VBRmatPlusScaledMat(AztecDVBR_Matrix* A,
3090 AztecDVBR_Matrix* source)
3092 int* nnz =
new int[numLocalEqnBlks_];
3093 int* nblk =
new int[numLocalEqnBlks_];
3094 int* src_nnz =
new int[numLocalEqnBlks_];
3095 int* src_nblk =
new int[numLocalEqnBlks_];
3097 if (nnz == NULL || nblk == NULL || src_nnz==NULL || src_nblk==NULL) {
3098 messageAbort(
"VBRMatPlusScaledMat: allocation failed");
3101 A->getNumNonzerosPerRow(nnz);
3102 A->getNumBlocksPerRow(nblk);
3103 source->getNumNonzerosPerRow(src_nnz);
3104 source->getNumBlocksPerRow(src_nblk);
3106 int i, max_nnz = 0, max_nblk = 0;
3107 for(i=0; i<numLocalEqnBlks_; i++) {
3108 if (nnz[i] != src_nnz[i] || nblk[i] != src_nblk[i]) {
3109 messageAbort(
"VBRmatPlusScaledMat: matrix sizes don't match.");
3111 if (max_nnz < nnz[i]) max_nnz = nnz[i];
3112 if (max_nblk < nblk[i]) max_nblk = nblk[i];
3120 double* val =
new double[max_nnz];
3121 int* colInds =
new int[max_nblk];
3122 if (val==NULL || colInds==NULL) {
3123 messageAbort(
"VBRmatPlusScaledMat: allocation failed");
3127 for(i=0; i<numLocalEqnBlks_; i++) {
3128 int row = localBlkOffset_+i;
3129 int err = source->getNumBlocksPerRow(row, nnzBlks);
3130 err += source->getNumNonzerosPerRow(row, len);
3131 err += source->getBlockRow(row, val, colInds, nnzBlks);
3133 if (err) messageAbort(
"VBRmatPlusScaledMat: error getting src row");
3135 for(
int j=0; j<len; j++) val[j] *= scalar;
3137 err = A->sumIntoBlockRow(row, val, colInds, nnzBlks);
3138 if (err) messageAbort(
"VBRmatPlusScaledMat: error summing in row");
3147 int Aztec_LinSysCore::MSRmatPlusScaledMat(AztecDMSR_Matrix* A,
3149 AztecDMSR_Matrix* source)
3151 return(A->addScaledMatrix(scalar, *source));
3155 void Aztec_LinSysCore::debugOutput(
const char* msg)
const {
3157 fprintf(debugFile_,
"%s\n", msg);
3163 int Aztec_LinSysCore::messageAbort(
const char* msg)
const {
3164 fei::console_out() <<
"Aztec_LinSysCore: " << msg <<
" Aborting." << FEI_ENDL;
3166 MPI_Abort(comm_, -1);
void setTypeName(const char *name)
int binarySearch(const T &item, const T *list, int len)
void * getDataPtr() const
std::ostream & console_out()
void setDataPtr(void *ptr)
const char * getTypeName() const
int searchList(const T &item, const T *list, int len)