int DirichletBCManager::getEqnNumber(int IDType, int ID, int fieldID, int offsetIntoField) { int eqn = -1; try { if (vecSpace_.get() != NULL) { vecSpace_->getGlobalIndex(IDType, ID, fieldID, eqn); } else { if (structure_ == NULL) { throw std::runtime_error("fei::DirichletBCManager has NULL SNL_FEI_Structure."); } NodeDatabase& nodeDB = structure_->getNodeDatabase(); const NodeDescriptor* node = NULL; nodeDB.getNodeWithID(ID, node); if (node == NULL) { throw std::runtime_error("fei::DirichletBCManager::getEqnNumber failed to get node."); } node->getFieldEqnNumber(fieldID, eqn); } } catch(std::runtime_error& exc) { FEI_OSTRINGSTREAM osstr; osstr << "fei::DirichletBCManager::finalizeBCEqns caught exception: " << exc.what() << " BC IDType="<<IDType<<", ID="<<ID << ", fieldID="<<fieldID; fei::console_out() << osstr.str() << FEI_ENDL; ERReturn(-1); } return eqn + offsetIntoField; }
int snl_fei::RecordMsgHandler::packMaskIDs(int destProc, std::vector<int>& msg) { fei::comm_map::row_type* ids = sendPattern_->getRow(destProc); int len = ids->size(); msg.resize(len); fei::comm_map::row_type::const_iterator id_iter = ids->begin(), id_end = ids->end(); int offset = 0; int* msgPtr = &msg[0]; for(; id_iter != id_end; ++id_iter) { fei::Record<int>* rec = recordCollection_->getRecordWithID(*id_iter); if (rec == NULL) { FEI_OSTRINGSTREAM osstr; osstr << "RecordMsgHandler::packMaskIDs: proc " << localProc_ << " failed to find ID " << *id_iter; throw std::runtime_error(osstr.str()); } msgPtr[offset++] = rec->getFieldMask()->getMaskID(); } return(0); }
int MatrixReducer::getRowLength(int row, int& length) const { if (reducer_->isSlaveEqn(row)) { FEI_OSTRINGSTREAM osstr; osstr << "fei::MatrixReducer::getRowLength ERROR, row="<<row<<" is a slave eqn. You can't get a slave row from the reduced matrix."; throw std::runtime_error(osstr.str()); } int reducedrow = reducer_->translateToReducedEqn(row); return(target_->getRowLength(reducedrow, length)); }
std::string add_macro_values(const char* name) { FEI_OSTRINGSTREAM osstr; osstr << name; #if defined(FEI_PLATFORM) && defined(FEI_OPT_LEVEL) osstr << "_" << FEI_PLATFORM << "_" << FEI_OPT_LEVEL; #else osstr << "_unknown_unknown"; #endif return(osstr.str()); }
//---------------------------------------------------------------------------- int SolnCheck::checkSolution(int localProc, int numProcs, const char* solnFileName, const char* checkFileName, const char* extension, int solveCounter) { if (localProc == 0) { fei::FillableMat soln, correctSoln; FEI_OSTRINGSTREAM fullSolnFileName; FEI_OSTRINGSTREAM fullCheckFileName; fullSolnFileName << solnFileName<<"."<<extension<<"."<<solveCounter; fullCheckFileName<< checkFileName<<"."<<extension<<".correct."<<solveCounter; std::string fullCheck_str = fullCheckFileName.str(); const char* check_c_str = fullCheck_str.c_str(); int err = SolnCheck::readSoln(check_c_str, 1, correctSoln); if (err != 0) { //If we failed to read the data for the "correct" solution, assume that //this is simply a portion of the solution (e.g., lagrange multipliers) //that this test isn't supposed to compare. //FEI_COUT << "FEI_tester: checkSolution: no check-file for '"<<extension // << "' portion of solution, skipping..." << FEI_ENDL; return(0); } std::string fullSoln_str = fullSolnFileName.str(); const char* soln_c_str = fullSoln_str.c_str(); err = SolnCheck::readSoln(soln_c_str, numProcs, soln); if (err != 0) return(err); FEI_COUT << "FEI_tester:checkSolution: checking '"<<extension<<"' solution..."; int solnCheckCode = SolnCheck::compareSoln(soln, correctSoln); if (solnCheckCode != 0) { FEI_COUT << "soln file-name: " << soln_c_str << FEI_ENDL; FEI_COUT << "soln-check failed, checkFileName="<<checkFileName<<FEI_ENDL; FEI_COUT << "soln: " << FEI_ENDL; fei::print(FEI_COUT, soln); FEI_COUT << "correctSoln file-name: " << check_c_str << FEI_ENDL; FEI_COUT << "correctSoln: " << FEI_ENDL; fei::print(FEI_COUT, correctSoln); return(-1); } FEI_COUT << " ok"<<FEI_ENDL; } return(0); }
int MatrixReducer::copyOutRow(int row, int len, double* coefs, int* indices) const { if (reducer_->isSlaveEqn(row)) { FEI_OSTRINGSTREAM osstr; osstr << "fei::MatrixReducer::copyOutRow ERROR, requested row ("<<row <<") is a slave eqn. You can't get a slave row from the reduced matrix."; throw std::runtime_error(osstr.str()); } int reducedrow = reducer_->translateToReducedEqn(row); int err = target_->copyOutRow(reducedrow, len, coefs, indices); for(int i=0; i<len; ++i) { indices[i] = reducer_->translateFromReducedEqn(indices[i]); } return(err); }
//--------------------------------------------------------------------------- int Solver_Amesos::solve(fei::LinearSystem* linearSystem, fei::Matrix* preconditioningMatrix, const fei::ParameterSet& parameterSet, int& iterationsTaken, int& status) { Trilinos_Helpers::copy_parameterset(parameterSet, *paramlist_); int numParams = 0; const char** paramStrings = NULL; std::vector<std::string> stdstrings; fei::utils::convert_ParameterSet_to_strings(¶meterSet, stdstrings); fei::utils::strings_to_char_ptrs(stdstrings, numParams, paramStrings); int err = solve(linearSystem, preconditioningMatrix, numParams, paramStrings, iterationsTaken, status); int olevel = 0; parameterSet.getIntParamValue("outputLevel", olevel); std::string param2; parameterSet.getStringParamValue("FEI_OUTPUT_LEVEL", param2); if (olevel >= 3 || param2 == "MATRIX_FILES" || param2 == "ALL") { std::string param1; parameterSet.getStringParamValue("debugOutput", param1); FEI_OSTRINGSTREAM osstr; if (!param1.empty()) { osstr << param1 << "/"; } else osstr << "./"; static int counter = 1; osstr << "x_Amesos.vec.slv"<<counter++; fei::SharedPtr<fei::Vector> feix = linearSystem->getSolutionVector(); feix->writeToFile(osstr.str().c_str()); } delete [] paramStrings; return(err); }
int DirichletBCManager::finalizeBCEqns(fei::Matrix& matrix, bool throw_if_bc_slave_conflict) { fei::SharedPtr<fei::Reducer> reducer = matrix.getMatrixGraph()->getReducer(); bool haveSlaves = reducer.get()!=NULL; //copy the boundary-condition prescribed values into the matrix, in //an equation-number obtained by using the matrix' VectorSpace to map //from the BC's idtype,id,fieldID,component to an equation-number. The //bc values will go on the diagonal of the matrix, i.e., column-index //will be the same equation-number. bc_map::iterator iter = bcs_.begin(), iter_end = bcs_.end(); for(; iter!=iter_end; ++iter) { int eqn = iter->first; if (haveSlaves) { if (reducer->isSlaveEqn(eqn)) { if (throw_if_bc_slave_conflict) { FEI_OSTRINGSTREAM osstr; osstr << "fei BCManager::finalizeBCeqns ERROR, eqn="<<eqn << " is both a BC eqn and slave-constraint eqn."; throw std::runtime_error(osstr.str()); } continue; } } double* ptr = &iter->second; CHK_ERR( matrix.copyIn(1, &eqn, 1, &eqn, &ptr) ); } bcs_.clear(); return(0); }
void test_MatrixGraph_test7(MPI_Comm comm, int numProcs, int localProc) { fei::SharedPtr<fei::VectorSpace> rowspace(new fei::VectorSpace(comm)); fei::SharedPtr<fei::VectorSpace> colspace(new fei::VectorSpace(comm)); int rowfield = 0, rowfieldsize = 1; int colfield = 1, colfieldsize = 3; rowspace->defineFields(1, &rowfield, &rowfieldsize); colspace->defineFields(1, &colfield, &colfieldsize); fei::MatrixGraph_Impl2 mgraph(rowspace, colspace); int pID = mgraph.definePattern(4, 0, colfield); fei::Pattern* pattern = mgraph.getPattern(pID); if (pattern->getNumIndices() != 4*colfieldsize) { FEI_COUT << "getNumIndices: " << pattern->getNumIndices()<<", colfieldsize: " << colfieldsize<<FEI_ENDL; FEI_OSTRINGSTREAM osstr; osstr << "test_MatrixGraph_test7, line "<<__LINE__<<FEI_ENDL; throw std::runtime_error(osstr.str()); } }
void test_MatrixGraph_test8(MPI_Comm comm, int numProcs, int localProc) { FEI_COUT << "testing matrix-graph with 'diagonal' connectivity block..."; try { fei::SharedPtr<fei::VectorSpace> rowspace(new fei::VectorSpace(comm)); fei::SharedPtr<fei::VectorSpace> colspace; int rowfield = 0, rowfieldsize = 1; rowspace->defineFields(1, &rowfield, &rowfieldsize); int idType = 0; rowspace->defineIDTypes(1, &idType); fei::MatrixGraph_Impl2 mgraph(rowspace, colspace); int numIDs = 4; int patternID = mgraph.definePattern(numIDs, idType, rowfield); fei::Pattern* pattern = mgraph.getPattern(patternID); if (pattern->getNumIndices() != 4*rowfieldsize) { FEI_OSTRINGSTREAM osstr; osstr << "test_MatrixGraph_test8, line "<<__LINE__<<FEI_ENDL; throw std::runtime_error(osstr.str()); } int blockID = 0; int numConnLists = 1; bool diagonal = true; mgraph.initConnectivityBlock(blockID, numConnLists, patternID, diagonal); std::vector<int> ids(numIDs); for(int i=0; i<numIDs; ++i) { ids[i] = i; } mgraph.initConnectivity(blockID, 0, &ids[0]); mgraph.initComplete(); fei::SharedPtr<fei::SparseRowGraph> localSRGraph = mgraph.createGraph(false); if ((int)localSRGraph->packedColumnIndices.size() != numIDs) { FEI_OSTRINGSTREAM osstr; osstr << "test_MatrixGraph_test8, line "<<__LINE__<<FEI_ENDL; throw std::runtime_error(osstr.str()); } } catch(std::runtime_error& exc) { FEI_OSTRINGSTREAM osstr; osstr << "test_MatrixGraph_test8, caught exception: " << exc.what(); throw std::runtime_error(osstr.str()); } FEI_COUT << "ok" << FEI_ENDL; }
//============================================================================== int SolnCheck::readSoln(const char* baseName, int np, fei::FillableMat& solution) { for(int i=0; i<np; i++) { FEI_OSTRINGSTREAM osstr; osstr << baseName << "." << np << "." << i; FEI_IFSTREAM infile(osstr.str().c_str()); if (!infile || infile.bad()) return(-1); int node, numDOF; double tmpValue; infile >> node; while(!infile.eof()) { infile >> numDOF; for(int j=0; j<numDOF; j++) { infile >> tmpValue; solution.putCoef(node,j,tmpValue); } infile >> node; } } return(0); }
//---------------------------------------------------------------------------- int snl_fei::RecordCollection::getGlobalIndexLocalID(int localID, int fieldID, int fieldSize, int fieldOffset, int whichComponentOfField, const int* eqnNumbers) { fei::Record<int>* record = getRecordWithLocalID(localID); if (record == NULL) { FEI_OSTRINGSTREAM osstr; osstr << "snl_fei::RecordCollection::getGlobalIndexLocalID ERROR, no record with " << "localID=" << localID; throw std::runtime_error(osstr.str()); } fei::FieldMask* mask = record->getFieldMask(); int offset = 0; try { mask->getFieldEqnOffset(fieldID, offset); } catch (...) { FEI_OSTRINGSTREAM osstr; osstr << "failed to get eqn-offset for fieldID " << fieldID << " on record with localID " << localID << "."; throw std::runtime_error(osstr.str()); } const int* eqnNums = eqnNumbers + record->getOffsetIntoEqnNumbers(); if (eqnNums == NULL) { FEI_OSTRINGSTREAM osstr; osstr << "snl_fei::RecordCollection::getGlobalIndex ERROR: null pointer," << " possibly because initComplete() hasn't been called yet?"; throw std::runtime_error(osstr.str()); } int globalIndex = -1; if (fieldOffset > 0) { globalIndex = eqnNums[offset + fieldOffset*fieldSize + whichComponentOfField]; } else { globalIndex = eqnNums[offset + whichComponentOfField]; } return(globalIndex); }
//---------------------------------------------------------------------------- void snl_fei::Factory::parameters(const fei::ParameterSet& parameterset) { fei::Factory::parameters(parameterset); int err = 0; if (lsc_.get() != NULL || feData_.get() != NULL) { int numParams = 0; const char** paramStrings = NULL; std::vector<std::string> stdstrings; fei::utils::convert_ParameterSet_to_strings(¶meterset, stdstrings); fei::utils::strings_to_char_ptrs(stdstrings, numParams, paramStrings); char** nc_paramStrings = const_cast<char**>(paramStrings); if (lsc_.get() != NULL) { err += lsc_->parameters(numParams, nc_paramStrings); } if (feData_.get() != NULL) { err += feData_->parameters(numParams, nc_paramStrings); } delete [] paramStrings; if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr << "snl_fei::Factory::parameters received err="<<err << " from either feiData_->parameters or lsc_->parameters."; throw std::runtime_error(osstr.str()); } } parameterset.getIntParamValue("outputLevel", outputLevel_); const fei::Param* param = 0; fei::Param::ParamType ptype = fei::Param::BAD_TYPE; param = parameterset.get("BLOCK_GRAPH"); ptype = param != NULL ? param->getType() : fei::Param::BAD_TYPE; if (ptype != fei::Param::BAD_TYPE) { blockMatrix_ = true; } param = parameterset.get("BLOCK_MATRIX"); ptype = param != NULL ? param->getType() : fei::Param::BAD_TYPE; if (ptype != fei::Param::BAD_TYPE) { if (ptype == fei::Param::BOOL) { blockMatrix_ = param->getBoolValue(); } else { blockMatrix_ = true; } } param = parameterset.get("AZ_matrix_type"); ptype = param != NULL ? param->getType() : fei::Param::BAD_TYPE; if (ptype != fei::Param::BAD_TYPE) { if (ptype == fei::Param::STRING) { if (param->getStringValue() == "AZ_VBR_MATRIX") { blockMatrix_ = true; } } } }
//---------------------------------------------------------------------------- void snl_fei::LinearSystem_General::enforceEssentialBC_step_2(fei::CSVec& essBCs) { //to enforce essential boundary conditions, we do the following: // // 1. for each eqn (== essBCs.indices()[n]), { // put zeros in row A[eqn], but leave 1.0 on the diagonal // set b[eqn] = essBCs.coefs()[n] // } // // 2. for i in 1..numRows (i.e., all rows) { // if (i in bcEqns) continue; // b[i] -= A[i,eqn] * essBCs.coefs()[n] // A[i,eqn] = 0.0; // } // //It is important to note that for step 1, essBCs need only contain //local eqns, but for step 2 it should contain *ALL* bc eqns. // //This function performs step 2. int numBCeqns = essBCs.size(); if (numBCeqns < 1) { return; } int* bcEqns = &(essBCs.indices())[0]; double* bcCoefs = &(essBCs.coefs())[0]; fei::SharedPtr<fei::Reducer> reducer = matrixGraph_->getReducer(); bool haveSlaves = reducer.get()!=NULL; if (haveSlaves) { for(int i=0; i<numBCeqns; ++i) { bcEqns[i] = reducer->translateFromReducedEqn(bcEqns[i]); } } int firstBCeqn = bcEqns[0]; int lastBCeqn = bcEqns[numBCeqns-1]; std::vector<double> coefs; std::vector<int> indices; int insertPoint; int nextBCeqnOffset = 0; int nextBCeqn = bcEqns[nextBCeqnOffset]; for(int i=firstLocalOffset_; i<=lastLocalOffset_; ++i) { if (haveSlaves) { if (reducer->isSlaveEqn(i)) continue; } bool should_continue = false; if (i >= nextBCeqn) { if (i == nextBCeqn) { ++nextBCeqnOffset; if (nextBCeqnOffset < numBCeqns) { nextBCeqn = bcEqns[nextBCeqnOffset]; } else { nextBCeqn = lastLocalOffset_+1; } should_continue = true; } else { while(nextBCeqn <= i) { if (nextBCeqn == i) should_continue = true; ++nextBCeqnOffset; if (nextBCeqnOffset < numBCeqns) { nextBCeqn = bcEqns[nextBCeqnOffset]; } else { nextBCeqn = lastLocalOffset_+1; } } } } if (should_continue) continue; int err = getMatrixRow(matrix_.get(), i, coefs, indices); if (err != 0 || indices.size() < 1) { continue; } int numIndices = indices.size(); int* indicesPtr = &indices[0]; double* coefsPtr = &coefs[0]; bool modifiedCoef = false; fei::insertion_sort_with_companions(numIndices, indicesPtr, coefsPtr); if (indicesPtr[0] > lastBCeqn || indicesPtr[numIndices-1] < firstBCeqn) { continue; } double value = 0.0; int offset = 0; for(int j=0; j<numIndices; ++j) { int idx = indicesPtr[j]; offset = fei::binarySearch(idx, bcEqns, numBCeqns, insertPoint); if (offset > -1) { value -= bcCoefs[offset]*coefsPtr[j]; coefsPtr[j] = 0.0; modifiedCoef = true; } } if (modifiedCoef) { err = matrix_->copyIn(1, &i, numIndices, indicesPtr, &coefsPtr); if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_2 ERROR: " << "err="<<err<<" returned from matrix_->copyIn, row="<<i; throw std::runtime_error(osstr.str()); } } const double fei_eps = 1.e-49; if (std::abs(value) > fei_eps) { rhs_->sumIn(1, &i, &value); if (output_level_ >= fei::FULL_LOGS && output_stream_ != 0) { FEI_OSTREAM& os = *output_stream_; os << "enfEssBC_step2: rhs["<<i<<"] += "<<value<<FEI_ENDL; } } } }
//--------------------------------------------------------------------------- int Solver_AztecOO::solve(fei::LinearSystem* linearSystem, fei::Matrix* preconditioningMatrix, const fei::ParameterSet& parameterSet, int& iterationsTaken, int& status) { std::string pcstring; parameterSet.getStringParamValue("AZ_precond", pcstring); if (pcstring == "ML_Op") { useML_ = true; } Teuchos::ParameterList& paramlist = get_ParameterList(); #ifdef HAVE_FEI_ML if (ml_aztec_options_ == NULL) ml_aztec_options_ = new int[AZ_OPTIONS_SIZE]; if (ml_aztec_params_ == NULL) ml_aztec_params_ = new double[AZ_PARAMS_SIZE]; if (!ml_defaults_set_ && useML_) { Teuchos::ParameterList mlparams; ML_Epetra::SetDefaults("SA", mlparams, ml_aztec_options_,ml_aztec_params_); mlparams.setParameters(paramlist); paramlist = mlparams; ml_defaults_set_ = true; } #endif Trilinos_Helpers::copy_parameterset(parameterSet, paramlist); fei::SharedPtr<fei::Matrix> feiA = linearSystem->getMatrix(); fei::SharedPtr<fei::Vector> feix = linearSystem->getSolutionVector(); fei::SharedPtr<fei::Vector> feib = linearSystem->getRHS(); Epetra_MultiVector* x = NULL; Epetra_MultiVector* b = NULL; Epetra_Operator* epetra_op = 0; Epetra_CrsMatrix* crsA = NULL; Trilinos_Helpers::get_Epetra_pointers(feiA, feix, feib, crsA, epetra_op, x, b); if (epetra_op == 0 || x == 0 || b == 0) { fei::console_out() << "Solver_AztecOO::solve Error, couldn't obtain Epetra objects" << " from fei container-objects."<<FEI_ENDL; return(-1); } //when we call azoo_->SetProblem, it will set some options. So we will //first take a copy of all options and params, then reset them after the //call to SetProblem. That way we preserve any options that have already //been set. std::vector<int> azoptions(AZ_OPTIONS_SIZE); std::vector<double> azparams(AZ_PARAMS_SIZE); const int* azoptionsptr = azoo_->GetAllAztecOptions(); const double* azparamsptr = azoo_->GetAllAztecParams(); int i; for(i=0; i<AZ_OPTIONS_SIZE; ++i) { azoptions[i] = azoptionsptr[i]; } for(i=0; i<AZ_PARAMS_SIZE; ++i) { azparams[i] = azparamsptr[i]; } Epetra_RowMatrix* precond = NULL; if (preconditioningMatrix != NULL) { fei::Matrix_Impl<Epetra_CrsMatrix>* snl_epetra_crs = dynamic_cast<fei::Matrix_Impl<Epetra_CrsMatrix>*>(preconditioningMatrix); fei::Matrix_Impl<Epetra_VbrMatrix>* snl_epetra_vbr = dynamic_cast<fei::Matrix_Impl<Epetra_VbrMatrix>*>(preconditioningMatrix); if (snl_epetra_crs != NULL) { precond = snl_epetra_crs->getMatrix().get(); } else if (snl_epetra_vbr != NULL) { precond = snl_epetra_vbr->getMatrix().get(); } else { fei::console_out() << "Solver_AztecOO::solve: ERROR getting epetra row matrix" << " from preconditioningMatrix."<<FEI_ENDL; return(-1); } } if (precond != NULL) { Epetra_LinearProblem * newlinProb = new Epetra_LinearProblem(epetra_op,x,b); azoo_->SetProblem(*newlinProb); delete linProb; linProb = newlinProb; azoo_->SetAllAztecOptions(&(azoptions[0])); azoo_->SetAllAztecParams(&(azparams[0])); azoo_->SetUseAdaptiveDefaultsTrue(); azoo_->SetPrecMatrix(precond); } bool needNewPreconditioner = false; if (feiA->changedSinceMark()) { feiA->markState(); needNewPreconditioner = true; } if (needNewPreconditioner) { Epetra_LinearProblem * newlinProb = new Epetra_LinearProblem(epetra_op,x,b); azoo_->SetProblem(*newlinProb); delete linProb; linProb = newlinProb; azoo_->SetAllAztecOptions(&(azoptions[0])); azoo_->SetAllAztecParams(&(azparams[0])); azoo_->SetUseAdaptiveDefaultsTrue(); if (useML_) { #ifdef HAVE_FEI_ML setup_ml_operator(*azoo_, crsA); #else fei::console_out() <<"Solver_AztecOO::solve ERROR, ML requested but HAVE_FEI_ML not defined." << FEI_ENDL; return(-1); #endif } else { azoo_->SetAztecOption(AZ_pre_calc, AZ_calc); azoo_->SetAztecOption(AZ_keep_info, 1); } } else { if (!useML_) { azoo_->SetAztecOption(AZ_pre_calc, AZ_reuse); } } epetra_op->SetUseTranspose(useTranspose_); azoo_->SetParameters(paramlist); maxIters_ = azoptionsptr[AZ_max_iter]; tolerance_= azparamsptr[AZ_tol]; status = azoo_->Iterate(maxIters_, //2,//maxSolveAttempts tolerance_); iterationsTaken = azoo_->NumIters(); int olevel = 0; parameterSet.getIntParamValue("outputLevel", olevel); std::string param2; parameterSet.getStringParamValue("FEI_OUTPUT_LEVEL", param2); if (olevel >= 3 || param2 == "MATRIX_FILES" || param2 == "ALL") { std::string param1; parameterSet.getStringParamValue("debugOutput", param1); FEI_OSTRINGSTREAM osstr; if (!param1.empty()) { osstr << param1 << "/"; } else osstr << "./"; osstr << "x_AztecOO.vec"; feix->writeToFile(osstr.str().c_str()); } return(0); }
//--------------------------------------------------------------------------- int Solver_Belos::solve(fei::LinearSystem* linearSystem, fei::Matrix* preconditioningMatrix, const fei::ParameterSet& parameterSet, int& iterationsTaken, int& status) { std::string krylov_solver_name; parameterSet.getStringParamValue("krylov_solver", krylov_solver_name); Teuchos::RCP<Teuchos::ParameterList>& paramlist = paramlist_; #ifdef HAVE_FEI_ML if (ml_aztec_options_ == NULL) ml_aztec_options_ = new int[AZ_OPTIONS_SIZE]; if (ml_aztec_params_ == NULL) ml_aztec_params_ = new double[AZ_PARAMS_SIZE]; if (!ml_defaults_set_ && useML_) { Teuchos::ParameterList mlparams; ML_Epetra::SetDefaults("SA", mlparams, ml_aztec_options_,ml_aztec_params_); mlparams.setParameters(*paramlist); *paramlist = mlparams; ml_defaults_set_ = true; } #endif Trilinos_Helpers::copy_parameterset(parameterSet, *paramlist); fei::SharedPtr<fei::Matrix> feiA = linearSystem->getMatrix(); fei::SharedPtr<fei::Vector> feix = linearSystem->getSolutionVector(); fei::SharedPtr<fei::Vector> feib = linearSystem->getRHS(); Epetra_MultiVector* x = NULL; Epetra_MultiVector* b = NULL; Epetra_Operator* epetra_op = 0; Epetra_CrsMatrix* crsA = NULL; Trilinos_Helpers::get_Epetra_pointers(feiA, feix, feib, crsA, epetra_op, x, b); Teuchos::RCP<Epetra_CrsMatrix> rcp_A(crsA); Teuchos::RCP<Epetra_MultiVector> rcp_x(x); Teuchos::RCP<Epetra_MultiVector> rcp_b(b); if (epetra_op == 0 || x == 0 || b == 0) { fei::console_out() << "Solver_Belos::solve Error, couldn't obtain Epetra objects" << " from fei container-objects."<<FEI_ENDL; return(-1); } Epetra_RowMatrix* precond = NULL; if (preconditioningMatrix != NULL) { fei::Matrix_Impl<Epetra_CrsMatrix>* snl_epetra_crs = dynamic_cast<fei::Matrix_Impl<Epetra_CrsMatrix>*>(preconditioningMatrix); fei::Matrix_Impl<Epetra_VbrMatrix>* snl_epetra_vbr = dynamic_cast<fei::Matrix_Impl<Epetra_VbrMatrix>*>(preconditioningMatrix); if (snl_epetra_crs != NULL) { precond = snl_epetra_crs->getMatrix().get(); } else if (snl_epetra_vbr != NULL) { precond = snl_epetra_vbr->getMatrix().get(); } else { fei::console_out() << "Solver_Belos::solve: ERROR getting epetra row matrix" << " from preconditioningMatrix."<<FEI_ENDL; return(-1); } } if (precond != NULL) { //TODO: set up preconditioner for Belos here } bool needNewPreconditioner = false; if (feiA->changedSinceMark()) { feiA->markState(); needNewPreconditioner = true; } if (needNewPreconditioner) { // // if (useML_) { #ifdef HAVE_FEI_ML // setup_ml_operator(*azoo_, crsA); #else // fei::console_out() <<"Solver_Belos::solve ERROR, ML requested but HAVE_FEI_ML not defined." // << FEI_ENDL; // return(-1); #endif // } // else { // azoo_->SetAztecOption(AZ_pre_calc, AZ_calc); // azoo_->SetAztecOption(AZ_keep_info, 1); // } } else { // if (!useML_) { // azoo_->SetAztecOption(AZ_pre_calc, AZ_reuse); // } } epetra_op->SetUseTranspose(useTranspose_); Belos::SolverFactory<double,Epetra_MultiVector,Epetra_Operator> belos_factory; belos_solver_manager_ = belos_factory.create(krylov_solver_name, paramlist); Teuchos::RCP<Belos::LinearProblem<double,Epetra_MultiVector,Epetra_Operator> > belos_lin_prob = Teuchos::rcp(new Belos::LinearProblem<double,Epetra_MultiVector,Epetra_Operator>(rcp_A, rcp_x, rcp_b)); belos_lin_prob->setProblem(); belos_solver_manager_->setProblem(belos_lin_prob); belos_solver_manager_->solve(); status = 0; iterationsTaken = belos_solver_manager_->getNumIters(); rcp_A.release(); rcp_x.release(); rcp_b.release(); int olevel = 0; parameterSet.getIntParamValue("outputLevel", olevel); std::string param2; parameterSet.getStringParamValue("FEI_OUTPUT_LEVEL", param2); if (olevel >= 3 || param2 == "MATRIX_FILES" || param2 == "ALL") { std::string param1; parameterSet.getStringParamValue("debugOutput", param1); FEI_OSTRINGSTREAM osstr; if (!param1.empty()) { osstr << param1 << "/"; } else osstr << "./"; osstr << "x_Belos.vec"; feix->writeToFile(osstr.str().c_str()); } return(0); }
int test_FEI_Impl::test1() { if (numProcs_ > 1) { return(0); } #ifdef HAVE_FEI_AZTECOO testData* testdata = new testData(localProc_, numProcs_); fei::SharedPtr<LinearSystemCore> linSys(new fei_trilinos::Aztec_LinSysCore(comm_)); fei::SharedPtr<LibraryWrapper> wrapper(new LibraryWrapper(linSys)); fei::SharedPtr<fei::FEI_Impl> fei(new fei::FEI_Impl(wrapper, comm_, 0)); std::string param0("name test1"); FEI_OSTRINGSTREAM osstr; osstr << "debugOutput "; if (path_.empty()) osstr << "."; else osstr << path_; std::string param1 = osstr.str(); int numParams = 2; char** params = new char*[numParams]; params[0] = const_cast<char*>(param0.c_str()); params[1] = const_cast<char*>(param1.c_str()); //call the parameters function a couple of times to test the fei's internal //method for merging string lists when parameters is called more than once. CHK_ERR( fei->parameters(1, ¶ms[0]) ); CHK_ERR( fei->parameters(1, ¶ms[1]) ); CHK_ERR( fei->parameters(2, params) ); delete [] params; CHK_ERR( fei->setIDLists(1, &(testdata->ids[0]), 1, &(testdata->ids[0])) ); CHK_ERR( fei->initFields(testdata->fieldIDs.size(), &(testdata->fieldSizes[0]), &(testdata->fieldIDs[0])) ); int numNodesPerElem = testdata->ids.size(); std::vector<int> numFieldsPerNode(numNodesPerElem, 1); std::vector<int*>nodalFieldIDs(numNodesPerElem, &(testdata->fieldIDs[0])); CHK_ERR( fei->initElemBlock(0, //blockID 1, //numElements numNodesPerElem, &numFieldsPerNode[0], &nodalFieldIDs[0], 0, //numElemDofFieldsPerElement NULL, //elemDofFieldIDs 0)); //interleaveStrategy CHK_ERR( fei->initElem(0, //blockID 0, //elemID &(testdata->ids[0])) ); std::vector<int*> sharingProcs2D(testdata->sharedIDs.size()); int offset = 0; for(int i=0; i<(int)testdata->numSharingProcsPerID.size(); ++i) { sharingProcs2D[i] = &(testdata->sharingProcs[offset]); offset += testdata->numSharingProcsPerID[i]; } if (testdata->sharedIDs.size() > 0) { CHK_ERR( fei->initSharedNodes(testdata->sharedIDs.size(), &(testdata->sharedIDs[0]), &(testdata->numSharingProcsPerID[0]), &sharingProcs2D[0]) ); } CHK_ERR( fei->initComplete() ); std::vector<double> rhsData(testdata->ids.size(), 1.0); double one = 1.0; CHK_ERR( fei->setMatScalars(1, &(testdata->ids[0]), &one) ); CHK_ERR( fei->setRHSScalars(1, &(testdata->ids[0]), &one) ); CHK_ERR( fei->setCurrentMatrix(testdata->ids[0]) ); CHK_ERR( fei->setCurrentRHS(testdata->ids[0]) ); CHK_ERR( fei->putIntoRHS(FEI_NODE, testdata->fieldIDs[0], testdata->ids.size(), &(testdata->ids[0]), &rhsData[0]) ); int numBCNodes = 2; GlobalID* BCNodeIDs = &(testdata->ids[0]); int BCFieldID = testdata->fieldIDs[0]; double* values = new double[numBCNodes]; int* offsetsIntoField = new int[numBCNodes]; for(int ii=0; ii<numBCNodes; ++ii) { values[ii] = 1.0; offsetsIntoField[ii] = 0; } CHK_ERR( fei->loadNodeBCs(numBCNodes, BCNodeIDs, BCFieldID, offsetsIntoField, values) ); delete [] offsetsIntoField; delete [] values; CHK_ERR( fei->loadComplete() ); int numActiveNodes = 0; CHK_ERR( fei->getNumLocalNodes(numActiveNodes) ); if (numActiveNodes != (int)testdata->ids.size()) { ERReturn(-1); } GlobalID* localNodes = new GlobalID[numActiveNodes]; CHK_ERR( fei->getLocalNodeIDList(numActiveNodes, localNodes, numActiveNodes) ); int totalFieldSize = 0; for(int ii=0; ii<(int)testdata->fieldSizes.size(); ++ii) { totalFieldSize += testdata->fieldSizes[ii]; } double* soln = new double[numActiveNodes*totalFieldSize]; int* offsets = new int[numActiveNodes+1]; CHK_ERR( fei->getNodalSolution(numActiveNodes, localNodes, offsets, soln) ); delete [] offsets; delete [] soln; delete [] localNodes; CHK_ERR( fei->resetInitialGuess() ); int fieldSize = 0; CHK_ERR( fei->getFieldSize(testdata->fieldIDs[0], fieldSize) ); double initTime, loadTime, solveTime, solnReturnTime; CHK_ERR( fei->cumulative_cpu_times(initTime, loadTime, solveTime, solnReturnTime) ); delete testdata; #endif return(0); }
void test_Matrix_unit4(MPI_Comm comm, int numProcs, int localProc) { if (numProcs > 1) { return; } FEI_COUT << "testing fei::Matrix_Impl with FEI_BLOCK_DIAGONAL_ROW..."; fei::SharedPtr<fei::VectorSpace> rowspace(new fei::VectorSpace(comm)); fei::SharedPtr<fei::VectorSpace> colspace; int rowfield = 0, rowfieldsize = 2; int idType = 0; rowspace->defineFields(1, &rowfield, &rowfieldsize); rowspace->defineIDTypes(1, &idType); fei::SharedPtr<fei::MatrixGraph> mgraph(new fei::MatrixGraph_Impl2(rowspace, colspace)); int patternID1 = mgraph->definePattern(2, idType, rowfield); fei::Pattern* rowpattern = mgraph->getPattern(patternID1); bool diagonal = true; mgraph->initConnectivityBlock(0, 1, patternID1, diagonal); std::vector<int> ids(2); ids[0] = 0; ids[1] = 1; int err = mgraph->initConnectivity(0, 0, &ids[0]); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit4, initConnectivity returned err="<<err; throw std::runtime_error(osstr.str()); } err = mgraph->initComplete(); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit4, initComplete returned err="<<err; throw std::runtime_error(osstr.str()); } fei::SharedPtr<fei::Factory> factory; try { factory = fei::create_fei_Factory(comm, "Trilinos"); } catch(...) { FEI_COUT << "Trilinos not available."<<FEI_ENDL; return; } fei::Param blktrue("BLOCK_MATRIX", true); fei::Param blkfalse("BLOCK_MATRIX", false); fei::ParameterSet paramset; paramset.add(blktrue); factory->parameters(paramset); fei::SharedPtr<fei::Matrix> feiblkmat = factory->createMatrix(mgraph); paramset.add(blkfalse); factory->parameters(paramset); fei::SharedPtr<fei::Matrix> feimat = factory->createMatrix(mgraph); int numrowindices = rowpattern->getNumIndices(); std::vector<double> coefs(numrowindices*rowfieldsize*rowfieldsize, 1.0); std::vector<double*> coefs_2D(numrowindices*rowfieldsize); int offset = 0; for(int i=0; i<numrowindices*rowfieldsize; ++i) { coefs_2D[i] = &(coefs[offset]); offset += rowfieldsize; } err = feimat->sumIn(0, 0, &coefs_2D[0], FEI_BLOCK_DIAGONAL_ROW); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit4, feimat->sumIn returned err="<<err; throw std::runtime_error(osstr.str()); } err = feiblkmat->sumIn(0, 0, &coefs_2D[0], FEI_BLOCK_DIAGONAL_ROW); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit4, feiblkmat->sumIn returned err="<<err; throw std::runtime_error(osstr.str()); } err = feimat->globalAssemble(); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit4, feimat->globalAssemble returned err="<<err; throw std::runtime_error(osstr.str()); } err = feiblkmat->globalAssemble(); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit4, feimat->globalAssemble returned err="<<err; throw std::runtime_error(osstr.str()); } feimat->writeToFile("feimat_blkdiag.mtx"); feiblkmat->writeToFile("feiblkmat_blkdiag.mtx"); FEI_COUT << "ok"<<FEI_ENDL; }
//---------------------------------------------------------------------------- void snl_fei::LinearSystem_General::enforceEssentialBC_step_1(fei::CSVec& essBCs) { //to enforce essential boundary conditions, we do the following: // // 1. for each eqn (== essBCs.indices()[n]), { // put zeros in row A[eqn], but leave 1.0 on the diagonal // set b[eqn] = essBCs.coefs()[n] // } // // 2. for i in 1..numRows (i.e., all rows) { // if (i in bcEqns) continue; // b[i] -= A[i,eqn] * essBCs.coefs()[n] // A[i,eqn] = 0.0; // } // //It is important to note that for step 1, essBCs need only contain //local eqns, but for step 2 it should contain *ALL* bc eqns. // //This function performs step 1. int numEqns = essBCs.size(); int* eqns = &(essBCs.indices())[0]; double* bcCoefs = &(essBCs.coefs())[0]; std::vector<double> coefs; std::vector<int> indices; fei::SharedPtr<fei::Reducer> reducer = matrixGraph_->getReducer(); bool haveSlaves = reducer.get()!=NULL; try { for(int i=0; i<numEqns; i++) { int eqn = eqns[i]; //if slave-constraints are present, the incoming bc-eqns are in //the reduced equation space. so we actually have to translate them back //to the unreduced space before passing them into the fei::Matrix object, //because the fei::Matrix object has machinery to translate unreduced eqns //to the reduced space. //Also, our firstLocalOffset_ and lastLocalOffset_ attributes are in the //unreduced space. if (haveSlaves) { eqn = reducer->translateFromReducedEqn(eqn); } if (eqn < firstLocalOffset_ || eqn > lastLocalOffset_) continue; //put gamma/alpha on the rhs for this ess-BC equation. double bcValue = bcCoefs[i]; int err = rhs_->copyIn(1, &eqn, &bcValue); if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: " << "err="<<err<<" returned from rhs_->copyIn row="<<eqn; throw std::runtime_error(osstr.str()); } err = getMatrixRow(matrix_.get(), eqn, coefs, indices); if (err != 0 || indices.size() < 1) { continue; } int rowLen = indices.size(); int* indPtr = &indices[0]; //first, put zeros in the row and 1.0 on the diagonal... for(int j=0; j<rowLen; j++) { if (indPtr[j] == eqn) coefs[j] = 1.0; else coefs[j] = 0.0; } double* coefPtr = &coefs[0]; err = matrix_->copyIn(1, &eqn, rowLen, indPtr, &coefPtr); if (err != 0) { FEI_OSTRINGSTREAM osstr; osstr <<"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: " << "err="<<err<<" returned from matrix_->copyIn row="<<eqn; throw std::runtime_error(osstr.str()); } }//for i } catch(std::runtime_error& exc) { FEI_OSTRINGSTREAM osstr; osstr << "fei::LinearSystem::enforceEssentialBC: ERROR, caught exception: " << exc.what(); throw std::runtime_error(osstr.str()); } }
void test_Matrix_unit2(MPI_Comm comm, int numProcs, int localProc) { if (numProcs > 1) { return; } FEI_COUT << "testing fei::Matrix_Impl..."; fei::SharedPtr<fei::VectorSpace> rowspace(new fei::VectorSpace(comm)); fei::SharedPtr<fei::VectorSpace> colspace; int rowfield = 0, rowfieldsize = 1; int idType = 0; rowspace->defineFields(1, &rowfield, &rowfieldsize); rowspace->defineIDTypes(1, &idType); fei::SharedPtr<fei::MatrixGraph> mgraph(new fei::MatrixGraph_Impl2(rowspace, colspace)); int patternID1 = mgraph->definePattern(2, idType, rowfield); fei::Pattern* rowpattern = mgraph->getPattern(patternID1); mgraph->initConnectivityBlock(0, 1, patternID1); std::vector<int> ids(2); ids[0] = 0; ids[1] = 1; int err = mgraph->initConnectivity(0, 0, &ids[0]); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit2, initConnectivity returned err="<<err; throw std::runtime_error(osstr.str()); } err = mgraph->initComplete(); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit2, initComplete returned err="<<err; throw std::runtime_error(osstr.str()); } bool factory_created = false; fei::SharedPtr<fei::Factory> factory; try { factory = fei::create_fei_Factory(comm, "Trilinos"); factory_created = true; } catch(...) {} if (!factory_created) { FEI_COUT << "failed to create Trilinos factory."<<FEI_ENDL; return; } fei::SharedPtr<fei::Matrix> feimat = factory->createMatrix(mgraph); int numrowindices = rowpattern->getNumIndices(); std::vector<double> coefs(numrowindices*numrowindices, 1.0); std::vector<double*> coefs_2D(numrowindices); for(int i=0; i<numrowindices; ++i) { coefs_2D[i] = &(coefs[i*numrowindices]); } err = feimat->sumIn(0, 0, &coefs_2D[0]); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit2, feimat->sumIn returned err="<<err; throw std::runtime_error(osstr.str()); } err = feimat->globalAssemble(); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit2, feimat->globalAssemble returned err="<<err; throw std::runtime_error(osstr.str()); } err = feimat->writeToFile("feimat2.mtx", false); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit2, feimat->writeToFile returned err="<<err; throw std::runtime_error(osstr.str()); } fei::FillableMat feimat_ss; err = fei_test_utils::copy_feiMatrix_to_FillableMat(*feimat, feimat_ss); if (err) { FEI_OSTRINGSTREAM osstr; osstr << "test_Matrix_unit2, copy_feiMatrix_to_FillableMat returned err="<<err; throw std::runtime_error(osstr.str()); } fei_test_utils::writeMatrix("feimat_ss2.mtx", feimat_ss); FEI_COUT << "ok"<<FEI_ENDL; }
//---------------------------------------------------------------------------- int snl_fei::LinearSystem_General::loadComplete(bool applyBCs, bool globalAssemble) { if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != 0) { FEI_OSTREAM& os = *output_stream_; os << dbgprefix_<<"loadComplete"<<FEI_ENDL; } if (dbcManager_ == NULL) { dbcManager_ = new fei::DirichletBCManager(matrixGraph_->getRowSpace()); } if (globalAssemble) { if (matrix_.get() != NULL) { CHK_ERR( matrix_->gatherFromOverlap() ); } if (rhs_.get() != NULL) { CHK_ERR( rhs_->gatherFromOverlap() ); } } unsigned counter = 0; std::map<std::string,unsigned>::iterator iter = named_loadcomplete_counter_.find(name_); if (iter == named_loadcomplete_counter_.end()) { FEI_COUT << "fei::LinearSystem::loadComplete internal error, name " << name_ << " not found." << FEI_ENDL; } else { counter = iter->second++; } if (output_level_ >= fei::FULL_LOGS) { std::string opath = fei::LogManager::getLogManager().getOutputPath(); if (opath == "") opath = "."; FEI_OSTRINGSTREAM Aname; FEI_OSTRINGSTREAM bname; FEI_OSTRINGSTREAM xname; Aname << opath << "/"; bname << opath << "/"; xname << opath << "/"; Aname << "A_"<<name_<<".preBC.np"<<numProcs_<<".slv"<<counter<< ".mtx"; bname << "b_"<<name_<<".preBC.np"<<numProcs_<<".slv"<<counter<< ".vec"; std::string Aname_str = Aname.str(); const char* Aname_c_str = Aname_str.c_str(); CHK_ERR( matrix_->writeToFile(Aname_c_str) ); std::string bname_str = bname.str(); const char* bname_c_str = bname_str.c_str(); CHK_ERR( rhs_->writeToFile(bname_c_str) ); } CHK_ERR( implementBCs(applyBCs) ); if (globalAssemble) { CHK_ERR( matrix_->globalAssemble() ); } if (output_level_ == fei::STATS || output_level_ == fei::ALL) { int globalNumSlaveCRs = matrixGraph_->getGlobalNumSlaveConstraints(); if (localProc_ == 0) { FEI_COUT << "Global Neqns: " << matrix_->getGlobalNumRows(); if (globalNumSlaveCRs > 0) { FEI_COUT << ", Global NslaveCRs: " << globalNumSlaveCRs; } FEI_COUT << FEI_ENDL; } } if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) { FEI_OSTREAM& os = *output_stream_; os << dbgprefix_<<"Neqns=" << matrix_->getGlobalNumRows(); int globalNumSlaveCRs = matrixGraph_->getGlobalNumSlaveConstraints(); if (globalNumSlaveCRs > 0) { os << ", Global NslaveCRs=" << globalNumSlaveCRs; } os << FEI_ENDL; } if (output_level_ >= fei::MATRIX_FILES) { std::string opath = fei::LogManager::getLogManager().getOutputPath(); if (opath == "") opath = "."; FEI_OSTRINGSTREAM Aname; FEI_OSTRINGSTREAM bname; FEI_OSTRINGSTREAM xname; Aname << opath << "/"; bname << opath << "/"; xname << opath << "/"; Aname << "A_" <<name_<<".np"<<numProcs_<< ".slv" << counter << ".mtx"; bname << "b_" <<name_<<".np"<<numProcs_<< ".slv" << counter << ".vec"; xname << "x0_" <<name_<<".np"<<numProcs_<< ".slv" << counter << ".vec"; std::string Aname_str = Aname.str(); const char* Aname_c_str = Aname_str.c_str(); CHK_ERR( matrix_->writeToFile(Aname_c_str) ); std::string bname_str = bname.str(); const char* bname_c_str = bname_str.c_str(); CHK_ERR( rhs_->writeToFile(bname_c_str) ); std::string xname_str = xname.str(); const char* xname_c_str = xname_str.c_str(); CHK_ERR( soln_->writeToFile(xname_c_str) ); } return(0); }