void
Albany::FieldManagerScalarResponseFunction::
setup(Teuchos::ParameterList& responseParams)
{
  Teuchos::RCP<const Epetra_Comm> comm = application->getComm();

  // Create field manager
  rfm = Teuchos::rcp(new PHX::FieldManager<PHAL::AlbanyTraits>);

  // FIXME: The adding of the Phalanx Graph Viz parameter
  // below causes problems if this function is called with
  // the same responseParams more than once. This happens
  // when the meshSpecs is but one entry in an array
  // of meshSpecs, which happens in meshes with multiple
  // blocks. In addition, if the building of evaluators
  // below does not recognize the Phalanx Graph Viz parameter,
  // then an exception will be thrown. Quick and dirty fix:
  // Remove the option if it already exists before building
  // the evaluators, it will be added again below anyhow.
  responseParams.remove("Phalanx Graph Visualization Detail", false);
    
  // Create evaluators for field manager
  Teuchos::Array< Teuchos::RCP<const PHX::FieldTag> > tags = 
    problem->buildEvaluators(*rfm, *meshSpecs, *stateMgr, 
			     BUILD_RESPONSE_FM,
			     Teuchos::rcp(&responseParams,false));
  int rank = tags[0]->dataLayout().rank();
  num_responses = tags[0]->dataLayout().dimension(rank-1);
  if (num_responses == 0)
    num_responses = 1;
  
  // Do post-registration setup
  rfm->postRegistrationSetup("");

  // Visualize rfm graph -- get file name from name of response function
  // (with spaces replaced by _ and lower case)
  vis_response_graph = 
    responseParams.get("Phalanx Graph Visualization Detail", 0);
  vis_response_name = responseParams.get<std::string>("Name");
  std::replace(vis_response_name.begin(), vis_response_name.end(), ' ', '_');
  std::transform(vis_response_name.begin(), vis_response_name.end(), 
		 vis_response_name.begin(), ::tolower);
}
  std::string ML2MueLuParameterTranslator::GetSmootherFactory(const Teuchos::ParameterList& paramList, Teuchos::ParameterList& adaptingParamList, const std::string& pname, const std::string& value) {

    TEUCHOS_TEST_FOR_EXCEPTION(pname != "coarse: type" && pname != "coarse: list" && pname != "smoother: type" && pname.find("smoother: list",0) != 0,
      Exceptions::RuntimeError,
      "MueLu::MLParameterListInterpreter::Setup(): Only \"coarse: type\", \"smoother: type\" or \"smoother: list\" (\"coarse: list\") are "
      "supported as ML parameters for transformation of smoother/solver parameters to MueLu");

    // string stream containing the smoother/solver xml parameters
    std::stringstream mueluss;

    // Check whether we are dealing with coarse level (solver) parameters or level smoother parameters
    std::string mode = "smoother:";
    if (pname.find("coarse:", 0) == 0)
      mode = "coarse:";

    // check whether pre and/or post smoothing
    std::string PreOrPost = "both";
    if (paramList.isParameter(mode + " pre or post"))
      PreOrPost = paramList.get<std::string>(mode + " pre or post");

    TEUCHOS_TEST_FOR_EXCEPTION(mode == "coarse:" && PreOrPost != "both", Exceptions::RuntimeError,
      "MueLu::MLParameterListInterpreter::Setup(): The parameter \"coarse: pre or post\" is not supported by MueLu. "
      "It does not make sense for direct solvers. For iterative solvers you obtain the same effect by increasing, "
      "e.g., the number of sweeps for the coarse grid smoother. Please remove it from your parameters.");

    // select smoother type
    std::string valuestr = value; // temporary variable
    std::transform(valuestr.begin(), valuestr.end(), valuestr.begin(), ::tolower);
    if ( valuestr == "jacobi" || valuestr == "gauss-seidel" || valuestr == "symmetric gauss-seidel" ) {
      std::string my_name;
      if ( PreOrPost == "both" ) my_name = "\"" + pname + "\"";
      else                       my_name = "\"smoother: " + PreOrPost + " type\"";
      mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"RELAXATION\"/>" << std::endl;

    } else if ( valuestr == "ifpack" ) {
      std::string my_name = "\"" + pname + "\"";
      if ( paramList.isParameter("smoother: ifpack type") ) {
        if ( paramList.get<std::string>("smoother: ifpack type") == "ILU" ) {
          mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"ILU\"/>" << std::endl;
          adaptingParamList.remove("smoother: ifpack type",false);
        }
        if ( paramList.get<std::string>("smoother: ifpack type") == "ILUT" ) {
          mueluss << "<Parameter name=" << my_name << " type\" type=\"string\" value=\"ILUT\"/>" << std::endl;
          adaptingParamList.remove("smoother: ifpack type",false);
        }
      }

    } else if ( valuestr == "chebyshev" ) {
       std::string my_name = "\"" + pname + "\"";
       mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"CHEBYSHEV\"/>" << std::endl;

    } else if (valuestr.length() > strlen("amesos") && valuestr.substr(0, strlen("amesos")) == "amesos") {  /* catch Amesos-* */
      std::string solverType = valuestr.substr(strlen("amesos")+1);  /* ("amesos-klu" -> "klu") */

      bool valid = false;
      const int  validatorSize = 5;
      std::string validator[validatorSize] = {"superlu", "superludist", "klu", "umfpack"};
      for (int i=0; i < validatorSize; i++)
        if (validator[i] == solverType)
          valid = true;
      TEUCHOS_TEST_FOR_EXCEPTION(!valid, Exceptions::RuntimeError,
        "MueLu::MLParameterListInterpreter: unknown smoother type. '" << solverType << "' not supported.");

      mueluss << "<Parameter name=\"" << pname << "\" type=\"string\" value=\"" << solverType << "\"/>" << std::endl;

    } else {
      // TODO error message
      std::cout << "error in " << __FILE__ << ":" << __LINE__ << " could not find valid smoother/solver" << std::endl;
    }

    // set smoother: pre or post parameter
    // Note that there is no "coarse: pre or post" in MueLu!
    if ( paramList.isParameter("smoother: pre or post") && mode == "smoother:") {
      //std::cout << "paramList" << paramList << std::endl;
      //std::string smootherPreOrPost = paramList.get<std::string>("smoother: pre or post");
      //std::cout << "Create pre or post parameter with " << smootherPreOrPost << std::endl;
      mueluss << "<Parameter name=\"smoother: pre or post\" type=\"string\" value=\"" << PreOrPost << "\"/>" << std::endl;
      adaptingParamList.remove("smoother: pre or post",false);
    }

    // create smoother parameter list
    if (PreOrPost != "both") {
      mueluss << "<ParameterList name=\"smoother: " << PreOrPost << " params\">" << std::endl;
    } else {
      mueluss << "<ParameterList name=\"" << mode << " params\">" << std::endl;
    }

    // relaxation based smoothers:

    if ( valuestr == "jacobi" || valuestr == "gauss-seidel" || valuestr == "symmetric gauss-seidel" ) {
      if ( valuestr == "jacobi" ) { mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"Jacobi\"/>" << std::endl; adaptingParamList.remove("relaxation: type",false); }
      if ( valuestr == "gauss-seidel" ) { mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"Gauss-Seidel\"/>" << std::endl; adaptingParamList.remove("relaxation: type",false); }
      if ( valuestr == "symmetric gauss-seidel" ) { mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"Symmetric Gauss-Seidel\"/>" << std::endl; adaptingParamList.remove("relaxation: type",false); }

      if ( paramList.isParameter("smoother: sweeps") ) { mueluss << "<Parameter name=\"relaxation: sweeps\" type=\"int\" value=\"" << paramList.get<int>("smoother: sweeps") << "\"/>" << std::endl; adaptingParamList.remove("smoother: sweeps",false); }
      if ( paramList.isParameter("smoother: damping factor") ) { mueluss << "<Parameter name=\"relaxation: damping factor\" type=\"double\" value=\"" << paramList.get<double>("smoother: damping factor") << "\"/>" << std::endl; adaptingParamList.remove("smoother: damping factor",false); }
    }

    // Chebyshev
    if ( valuestr == "chebyshev") {
      if ( paramList.isParameter("smoother: polynomial order") ) { mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"" << paramList.get<int>("smoother: polynomial order") << "\"/>" << std::endl; adaptingParamList.remove("smoother: polynomial order",false); }
      else { mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"2\"/>" << std::endl; }
      if ( paramList.isParameter("smoother: Chebyshev alpha") ) { mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"" << paramList.get<double>("smoother: Chebyshev alpha") << "\"/>" << std::endl; adaptingParamList.remove("smoother: Chebyshev alpha",false); }
      else { mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"20\"/>" << std::endl; adaptingParamList.remove("smoother: Chebyshev alpha",false); }
    }

    // parameters for ILU based preconditioners
    if ( valuestr == "ifpack") {

      // add Ifpack parameters
      if ( paramList.isParameter("smoother: ifpack overlap") ) { mueluss << "<Parameter name=\"partitioner: overlap\" type=\"int\" value=\"" << paramList.get<int>("smoother: ifpack overlap") << "\"/>" << std::endl; adaptingParamList.remove("smoother: ifpack overlap",false); }
      if ( paramList.isParameter("smoother: ifpack level-of-fill") ) { mueluss << "<Parameter name=\"fact: level-of-fill\" type=\"int\" value=\"" << paramList.get<int>("smoother: ifpack level-of-fill") << "\"/>" << std::endl; adaptingParamList.remove("smoother: ifpack level-of-fill",false); }
      if ( paramList.isParameter("smoother: ifpack absolute threshold") ) { mueluss << "<Parameter name=\"fact: absolute threshold\" type=\"int\" value=\"" << paramList.get<double>("smoother: ifpack absolute threshold") << "\"/>" << std::endl; adaptingParamList.remove("smoother: ifpack absolute threshold",false); }
      if ( paramList.isParameter("smoother: ifpack relative threshold") ) { mueluss << "<Parameter name=\"fact: relative threshold\" type=\"int\" value=\"" << paramList.get<double>("smoother: ifpack relative threshold") << "\"/>" << std::endl; adaptingParamList.remove("smoother: ifpack relative threshold",false); }
    }

    mueluss << "</ParameterList>" << std::endl;

    // max coarse level size parameter (outside of smoother parameter lists)
    if ( paramList.isParameter("smoother: max size") ) {
      mueluss << "<Parameter name=\"coarse: max size\" type=\"int\" value=\"" << paramList.get<int>("smoother: max size") << "\"/>" << std::endl; adaptingParamList.remove("smoother: max size",false);
    }

    return mueluss.str();
  }
  std::string ML2MueLuParameterTranslator::SetParameterList(const Teuchos::ParameterList & paramList_in, const std::string& defaultVals) {
    Teuchos::ParameterList paramList = paramList_in;

    RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout)); // TODO: use internal out (GetOStream())

#if defined(HAVE_MUELU_ML) && defined(HAVE_MUELU_EPETRA)

    // TODO alternative with standard parameterlist from ML user guide?

    if (defaultVals != "") {
      TEUCHOS_TEST_FOR_EXCEPTION(defaultVals!="SA" && defaultVals!="NSSA", Exceptions::RuntimeError,
                                   "MueLu::MLParameterListInterpreter: only \"SA\" and \"NSSA\" allowed as options for ML default parameters.");
      Teuchos::ParameterList ML_defaultlist;
      ML_Epetra::SetDefaults(defaultVals,ML_defaultlist);

      // merge user parameters with default parameters
      MueLu::MergeParameterList(paramList_in, ML_defaultlist, true);
      paramList = ML_defaultlist;
    }
#else
    if (defaultVals != "") {
        // If no validator available: issue a warning and set parameter value to false in the output list
        *out << "Warning: MueLu_ENABLE_ML=OFF. No ML default values available." << std::endl;
    }
#endif // HAVE_MUELU_ML

    //
    // Move smoothers/aggregation/coarse parameters to sublists
    //

    // ML allows to have level-specific smoothers/aggregation/coarse parameters at the top level of the list or/and defined in sublists:
    // See also: ML Guide section 6.4.1, MueLu::CreateSublists, ML_CreateSublists
    ParameterList paramListWithSubList;
    MueLu::CreateSublists(paramList, paramListWithSubList);
    paramList = paramListWithSubList; // swap
    Teuchos::ParameterList adaptingParamList = paramList;    // copy of paramList which is used to removed already interpreted parameters

    //
    // Validate parameter list
    //
    {
      bool validate = paramList.get("ML validate parameter list", true); /* true = default in ML */
      if (validate) {

#if defined(HAVE_MUELU_ML) && defined(HAVE_MUELU_EPETRA)
        // Validate parameter list using ML validator
        int depth = paramList.get("ML validate depth", 5); /* 5 = default in ML */
        TEUCHOS_TEST_FOR_EXCEPTION(! ML_Epetra::ValidateMLPParameters(paramList, depth), Exceptions::RuntimeError,
                                   "ERROR: ML's Teuchos::ParameterList contains incorrect parameter!");
#else
        // If no validator available: issue a warning and set parameter value to false in the output list
        *out << "Warning: MueLu_ENABLE_ML=OFF. The parameter list cannot be validated." << std::endl;
        paramList.set("ML validate parameter list", false);

#endif // HAVE_MUELU_ML
      } // if(validate)
    } // scope

    // stringstream for concatenating xml parameter strings.
    std::stringstream mueluss;

    // create surrounding MueLu parameter list
    mueluss << "<ParameterList name=\"MueLu\">" << std::endl;

    // loop over all ML parameters in provided parameter list
    for (ParameterList::ConstIterator param = paramListWithSubList.begin(); param != paramListWithSubList.end(); ++param) {

      // extract ML parameter name
      const std::string & pname=paramListWithSubList.name(param);

      // extract corresponding (ML) value
      // remove ParameterList specific information from result string
      std::stringstream valuess;
      valuess << paramList.entry(param);
      std::string valuestr = valuess.str();
      replaceAll(valuestr, "[unused]", "");
      replaceAll(valuestr, "[default]", "");
      valuestr = trim(valuestr);

      // transform ML parameter to corresponding MueLu parameter and generate XML string
      std::string valueInterpreterStr = "\"" + valuestr + "\"";
      std::string ret = MasterList::interpretParameterName(MasterList::ML2MueLu(pname),valueInterpreterStr);

      // add XML string
      if (ret != "") {
        mueluss << ret << std::endl;

        // remove parameter from ML parameter list
        adaptingParamList.remove(pname,false);
      }

      // special handling for energy minimization
      // TAW: this is not optimal for symmetric problems but at least works.
      //      for symmetric problems the "energy minimization" parameter should not exist anyway...
      if (pname == "energy minimization: enable") {
        mueluss << "<Parameter name=\"problem: symmetric\"      type=\"bool\"     value=\"false\"/>" << std::endl;
        mueluss << "<Parameter name=\"transpose: use implicit\" type=\"bool\"     value=\"false\"/>" << std::endl;
      }

      // special handling for smoothers
      if (pname == "smoother: type") {

        mueluss << GetSmootherFactory(paramList, adaptingParamList, pname, valuestr);

      }

      // special handling for level-specific smoothers
      if (pname.find("smoother: list (level",0) == 0) {
        // Scan pname (ex: pname="smoother: type (level 2)")
        std::string type, option;
        int levelID=-1;
        {
          typedef Teuchos::ArrayRCP<char>::size_type size_type;
          Teuchos::Array<char> ctype  (size_type(pname.size()+1));
          Teuchos::Array<char> coption(size_type(pname.size()+1));

          int matched = sscanf(pname.c_str(),"%s %[^(](level %d)", ctype.getRawPtr(), coption.getRawPtr(), &levelID); // use [^(] instead of %s to allow for strings with white-spaces (ex: "ifpack list")
          type = std::string(ctype.getRawPtr());
          option = std::string(coption.getRawPtr()); option.resize(option.size () - 1); // remove final white-space

          if (matched != 3 || (type != "smoother:")) {
            TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::CreateSublist(), Line " << __LINE__ << ". "
                                        << "Error in creating level-specific sublists" << std::endl
                                        << "Offending parameter: " << pname << std::endl);
          }

          mueluss << "<ParameterList name=\"level " << levelID << "\">" << std::endl;
          mueluss << GetSmootherFactory(paramList.sublist(pname),adaptingParamList.sublist(pname), "smoother: type", paramList.sublist(pname).get<std::string>("smoother: type"));
          mueluss << "</ParameterList>" << std::endl;
        }
      }

      // special handling for coarse level
      TEUCHOS_TEST_FOR_EXCEPTION(paramList.isParameter("coarse: type"), Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter::Setup(): The parameter \"coarse: type\" should not exist but being stored in \"coarse: list\" instead.");
      if ( pname == "coarse: list" ) {

        // interpret smoother/coarse solver data.
        // Note, that we inspect the "coarse: list" sublist to define the "coarse" smoother/solver
        // Be aware, that MueLu::CreateSublists renames the prefix of the parameters in the "coarse: list" from "coarse" to "smoother".
        // Therefore, we have to check the values of the "smoother" parameters
        TEUCHOS_TEST_FOR_EXCEPTION(!paramList.sublist("coarse: list").isParameter("smoother: type"), Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter::Setup(): no coarse grid solver defined.");
        mueluss << GetSmootherFactory(paramList.sublist("coarse: list"), adaptingParamList.sublist("coarse: list"), "coarse: type", paramList.sublist("coarse: list").get<std::string>("smoother: type"));


      }
    } // for

    mueluss << "</ParameterList>" << std::endl;

    return mueluss.str();
  }
void
Albany::FieldManagerScalarResponseFunction::
setup(Teuchos::ParameterList& responseParams)
{
  Teuchos::RCP<const Teuchos_Comm> commT = application->getComm();

  // FIXME: The adding of the Phalanx Graph Viz parameter
  // below causes problems if this function is called with
  // the same responseParams more than once. This happens
  // when the meshSpecs is but one entry in an array
  // of meshSpecs, which happens in meshes with multiple
  // blocks. In addition, if the building of evaluators
  // below does not recognize the Phalanx Graph Viz parameter,
  // then an exception will be thrown. Quick and dirty fix:
  // Remove the option if it already exists before building
  // the evaluators, it will be added again below anyhow.
  responseParams.remove("Phalanx Graph Visualization Detail", false);

  // Restrict to the element block?
  const char* reb_parm = "Restrict to Element Block";
  const bool
    reb_parm_present = responseParams.isType<bool>(reb_parm),
    reb = reb_parm_present && responseParams.get<bool>(reb_parm, false);
  element_block_index = reb ? meshSpecs->ebNameToIndex[meshSpecs->ebName] : -1;
  if (reb_parm_present) responseParams.remove(reb_parm, false);

  // Create field manager
  rfm = Teuchos::rcp(new PHX::FieldManager<PHAL::AlbanyTraits>);
    
  // Create evaluators for field manager
  Teuchos::Array< Teuchos::RCP<const PHX::FieldTag> > tags = 
    problem->buildEvaluators(*rfm, *meshSpecs, *stateMgr, 
                             BUILD_RESPONSE_FM,
                             Teuchos::rcp(&responseParams,false));
  int rank = tags[0]->dataLayout().rank();
  num_responses = tags[0]->dataLayout().dimension(rank-1);
  if (num_responses == 0)
    num_responses = 1;
  
  // Do post-registration setup
  
  //amb This is not right because rfm doesn't account for multiple element
  // blocks. Make do for now. Also, rewrite this code to get rid of all this
  // redundancy.
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::Jacobian>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::Jacobian>(
      derivative_dimensions); }
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::Tangent>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::Tangent>(
      derivative_dimensions); }
  // SG and MP implementations get deriv info from the regular evaluation types
#ifdef ALBANY_SG
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::Jacobian>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::SGJacobian>(
      derivative_dimensions); }
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::Tangent>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::SGTangent>(
      derivative_dimensions); }
#endif
#ifdef ALBANY_ENSEMBLE
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::Jacobian>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::MPJacobian>(
      derivative_dimensions); }
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::Tangent>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::MPTangent>(
      derivative_dimensions); }
#endif
  { std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(
      PHAL::getDerivativeDimensions<PHAL::AlbanyTraits::DistParamDeriv>(
        application.get(), meshSpecs.get()));
    rfm->setKokkosExtendedDataTypeDimensions<PHAL::AlbanyTraits::DistParamDeriv>(
      derivative_dimensions); }
  rfm->postRegistrationSetup("");

  // Visualize rfm graph -- get file name from name of response function
  // (with spaces replaced by _ and lower case)
  vis_response_graph = 
    responseParams.get("Phalanx Graph Visualization Detail", 0);
  vis_response_name = responseParams.get<std::string>("Name");
  std::replace(vis_response_name.begin(), vis_response_name.end(), ' ', '_');
  std::transform(vis_response_name.begin(), vis_response_name.end(), 
		 vis_response_name.begin(), ::tolower);

  if (reb_parm_present) responseParams.set<bool>(reb_parm, reb);
}
Esempio n. 5
0
int main(int argc, char *argv[])
{
  Teuchos::GlobalMPISession session(&argc, &argv);
  Teuchos::RCP<const Comm<int> > comm =
    Teuchos::DefaultComm<int>::getComm();

  int rank = comm->getRank();
  int nprocs = comm->getSize();
  int fail = 0;

  ////////////////////////////////////////////////////////////
  // Create a default Environment and test it

  Environment *defEnv = NULL;

  try{
    defEnv = new Environment;
  }
  catch(std::exception &e){
    std::cerr << e.what() << std::endl;
    fail=1000;
  }

  if (checkErrorCode(comm, fail))
    return 1;

  if (!fail && defEnv->myRank_ != rank)
    fail = 1001;

  if (!fail && defEnv->numProcs_ != nprocs)
    fail = 1002;

  if (!fail && defEnv->comm_->getSize() != nprocs)
    fail = 1003;

  if (!fail && defEnv->doStatus() != true)
    fail = 1005;
  
  if (!fail && defEnv->doTiming() != false)
    fail = 1006;

  if (!fail && defEnv->doMemoryProfiling() != false)
    fail = 1007;

  if (!fail && defEnv->errorCheckLevel_ != Zoltan2::BASIC_ASSERTION)
    fail = 1008;

  if (checkErrorCode(comm, fail))
    return 1;

  delete defEnv;

  ////////////////////////////////////////////////////////////
  // Set a few parameters and create an Environment

  Teuchos::ParameterList myParams("testParameterList");

  myParams.set("debug_level", "detailed_status");        
  myParams.set("debug_procs", "all");   
  myParams.set("debug_output_stream", "std::cout");

  if (nprocs > 3)
    myParams.set("memory_procs", "0-1,3"); 
  else
    myParams.set("memory_procs", "0"); 

  myParams.set("memory_output_file", "memInfo.txt");

  myParams.set("speed_versus_quality", "speed");
  myParams.set("memory_versus_speed", "memory");

  myParams.set("topology", "2,6,6");
  myParams.set("randomize_input", "true");
  myParams.set("partitioning_objective", "minimize_cut_edge_weight");
  myParams.set("imbalance_tolerance", 1.2);

  Environment *env = NULL;

  try{
    env = new Environment(myParams, comm);
  }
  catch(std::exception &e){
    std::cerr << e.what() << std::endl;
    fail=2000;
  }

  if (!fail){
     try{
       env->debug(Zoltan2::BASIC_STATUS, "A basic debugging message.");
     }
     catch(std::exception &e){
       std::cerr << e.what() << std::endl;
       fail=3000;
     }
  }

  if (!fail){
     try{
       env->memory("Memory info");
       env->memory("Memory info next");
       env->memory("Memory info after");
     }
     catch(std::exception &e){
       std::cerr << e.what() << std::endl;
       fail=3002;
     }
  }

  if (checkErrorCode(comm, fail))
    return 1;

  if (!fail && env->myRank_ != rank)
    fail = 2001;

  if (!fail && env->numProcs_ != nprocs)
    fail = 2002;

  if (!fail && env->comm_->getSize() != nprocs)
    fail = 2003;

  if (!fail){
    const Teuchos::ParameterList &pl1 = env->getParameters();
    const ParameterEntry *dl = pl1.getEntryPtr("debug_level");
  
    if (!dl){
      fail = 2004;
    }
    else if (!(dl->isType<int>())){
      fail = 2013;
    }
    else{
      int value;
      int &val = dl->getValue<int>(&value);
      if (val != Zoltan2::DETAILED_STATUS) 
        fail = 2005;
    }
  }

  if (!fail && env->errorCheckLevel_ != Zoltan2::BASIC_ASSERTION)
    fail = 2008;

  if (checkErrorCode(comm, fail))
    return 1;

  if (rank==0){
    std::cout << "\nA test parameter list" << std::endl;
    const Teuchos::ParameterList &envParams = env->getParameters();
    try{
      envParams.print();
    }
    catch(std::exception &e){
      std::cerr << e.what() << std::endl;
      fail=2013;
    }
  }

  if (checkErrorCode(comm, fail))
    return 1;

  ////////////////////////////////////////////////////////////
  // Given an existing Environment, get its parameters and
  // add some new parameters and create a new Environment.

  RCP<const Comm<int> > oldComm = env->comm_;
  const Teuchos::ParameterList &oldParams = env->getUnvalidatedParameters();
  
  Teuchos::ParameterList newParams = oldParams;
  newParams.set("error_check_level", "debug_mode_assertions");
  newParams.set("memory_versus_speed", "speed");
  newParams.remove("memory_output_file");
  newParams.set("imbalance_tolerance", "1.05");
  newParams.set("algorithm", "phg");
  newParams.set("partitioning_objective", "minimize_cut_edge_weight");
  
  RCP<Environment> newEnv;

  try{
    newEnv = Teuchos::rcp(new Environment(newParams, oldComm));
  }
  catch(std::exception &e){
    std::cerr << e.what() << std::endl;
    fail=3000;
  }

  if (checkErrorCode(comm, fail))
    return 1;

  if (!fail && newEnv->errorCheckLevel_ != Zoltan2::DEBUG_MODE_ASSERTION)
    fail = 3001;

  if (!fail && rank==0){
    std::cout << "\nA few changes/additions to the list" << std::endl;
    const Teuchos::ParameterList &envParams = newEnv->getParameters();
    try{
      envParams.print();
    }
    catch(std::exception &e){
      std::cerr << e.what() << std::endl;
      fail=3003;
    }
  }

  if (checkErrorCode(comm, fail))
    return 1;

  delete env;

  if (rank==0)
    std::cout << "PASS" << std::endl;

  return 0;
}
void Operator<Node>::paramsToUpper(Teuchos::ParameterList &plist, int &changed, bool rmUnderscore)
{
  changed = 0;

  // get a list of all parameter names in the list

  std::vector<std::string> paramNames ;
  Teuchos::ParameterList::ConstIterator pIter;

  pIter = plist.begin();

  while (1){
    //////////////////////////////////////////////////////////////////////
    // Compiler considered this while statement an error
    // for ( pIter = plist.begin() ; pIter != plist.end() ; pIter++ ){
    // }
    //////////////////////////////////////////////////////////////////////
    if (pIter == plist.end()) break;
    const std::string & nm = plist.name(pIter);
    paramNames.push_back(nm);
    pIter++;
  }

  // Change parameter names and values to upper case

  for (unsigned int i=0; i < paramNames.size(); i++){

    std::string origName(paramNames[i]);
    int paramNameChanged = 0;
    stringToUpper(paramNames[i], paramNameChanged, rmUnderscore);

    if (plist.isSublist(origName)){
      Teuchos::ParameterList &sublist = plist.sublist(origName);

      int sublistChanged=0;
      paramsToUpper(sublist, sublistChanged, false);

      if (paramNameChanged){

        // this didn't work, so I need to remove the old sublist
        // and create a new one
        //
        //sublist.setName(paramNames[i]);

        Teuchos::ParameterList newlist(sublist);
        plist.remove(origName);
        plist.set(paramNames[i], newlist);
      }
    }
    else if (plist.isParameter(origName)){

      std::string paramVal(plist.get<std::string>(origName));

      int paramValChanged=0;
      stringToUpper(paramVal, paramValChanged);

      if (paramNameChanged || paramValChanged){
        if (paramNameChanged){
          plist.remove(origName);
        }
        plist.set(paramNames[i], paramVal);
        changed++;
      }
    }
  } // next parameter or sublist
}