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());
}
Beispiel #5
0
//----------------------------------------------------------------------------
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(&parameterSet, 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;
}
Beispiel #11
0
//==============================================================================
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);
}
Beispiel #13
0
//----------------------------------------------------------------------------
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(&parameterset, 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);
}
Beispiel #17
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, &params[0]) );
  CHK_ERR( fei->parameters(1, &params[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);
}
Beispiel #18
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());
  }
}
Beispiel #20
0
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);
}