void ParameterList::validateMissingSublistMustExist(const std::string &baselist_name,
  const std::string &sublist_name, const bool mustAlreadyExist) const
{
  TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
    mustAlreadyExist, Exceptions::InvalidParameterName
    ,"The sublist "<<baselist_name<<"->\""<<sublist_name<<"\" does not exist!"
    );
}
void ParameterList::validateEntryIsList(
  const std::string &name_in, const ParameterEntry &entry_in
  ) const
{
  TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
    !entry_in.isList(), Exceptions::InvalidParameterType
    ,"Error, the parameter \"" << name_in << "\" is not a list, it is of type \""
    <<entry_in.getAny(false).typeName()<<"\"!" );
}
void ParameterList::validateEntryExists(
  const std::string & /*funcName*/, const std::string &name_in,
  const ParameterEntry *entry_in
  ) const
{
  TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
    entry_in==NULL, Exceptions::InvalidParameterName
    ,"Error!  The parameter \""<<name_in<<"\" does not exist"\
    "\nin the parameter (sub)list \""<<this->name()<<"\"."
    "\n\nThe current parameters set in (sub)list \""<<this->name()<<"\" are:\n\n"
    << this->currentParametersString()
    );
}
Example #4
0
  void ParameterListInterpreter<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::SetEasyParameterList(const Teuchos::ParameterList& constParamList) {
    // Create a non const copy of the parameter list
    // Working with a modifiable list is much much easier than with original one
    ParameterList paramList = constParamList;

    // Translate cycle type parameter
    if (paramList.isParameter("cycle type")) {
      std::map<std::string,CycleType> cycleMap;
      cycleMap["V"] = VCYCLE;
      cycleMap["W"] = WCYCLE;

      std::string cycleType = paramList.get<std::string>("cycle type");
      TEUCHOS_TEST_FOR_EXCEPTION(cycleMap.count(cycleType) == 0, Exceptions::RuntimeError, "Invalid cycle type: \"" << cycleType << "\"");
      Cycle_ = cycleMap[cycleType];
    }

    this->maxCoarseSize_    = paramList.get<int> ("coarse: max size",    Hierarchy::GetDefaultMaxCoarseSize());
    this->numDesiredLevel_  = paramList.get<int> ("max levels",          Hierarchy::GetDefaultMaxLevels());
    this->graphOutputLevel_ = paramList.get<int> ("debug: graph level", -1);
    blockSize_              = paramList.get<int> ("number of equations", 1);

    // Save level data
    if (paramList.isSublist("print")) {
      ParameterList printList = paramList.sublist("print");

      if (printList.isParameter("A"))
        this->matricesToPrint_     = Teuchos::getArrayFromStringParameter<int>(printList, "A");
      if (printList.isParameter("P"))
        this->prolongatorsToPrint_ = Teuchos::getArrayFromStringParameter<int>(printList, "P");
      if (printList.isParameter("R"))
        this->restrictorsToPrint_  = Teuchos::getArrayFromStringParameter<int>(printList, "R");
    }

    // Translate verbosity parameter
    this->verbosity_ = static_cast<MsgType>(Hierarchy::GetDefaultVerbLevel());      // cast int to enum
    if (paramList.isParameter("verbosity")) {
      std::map<std::string,MsgType> verbMap;
      verbMap["none"]    = None;
      verbMap["low"]     = Low;
      verbMap["medium"]  = Medium;
      verbMap["high"]    = High;
      verbMap["extreme"] = Extreme;
      verbMap["test"]    = Test;

      std::string verbosityLevel = paramList.get<std::string>("verbosity");
      TEUCHOS_TEST_FOR_EXCEPTION(verbMap.count(verbosityLevel) == 0, Exceptions::RuntimeError, "Invalid verbosity level: \"" << verbosityLevel << "\"");
      this->verbosity_ = verbMap[verbosityLevel];
      this->SetVerbLevel(this->verbosity_);
    }

    // Detect if we need to transfer coordinates to coarse levels. We do that iff
    //  - we use "laplacian" dropping on some level, or
    //  - we use repartitioning on some level
    // This is not ideal, as we may have "repartition: enable" turned on by default
    // and not present in the list, but it is better than nothing.
    useCoordinates_ = false;
    if ((paramList.isParameter("repartition: enable")      && paramList.get<bool>("repartition: enable")             == true) ||
        (paramList.isParameter("aggregation: drop scheme") && paramList.get<std::string>("aggregation: drop scheme") == "laplacian")) {
      useCoordinates_ = true;

    } else {
      for (int levelID = 0; levelID < this->numDesiredLevel_; levelID++) {
        std::string levelStr = "level" + toString(levelID);

        if (paramList.isSublist(levelStr)) {
          const ParameterList& levelList = paramList.sublist(levelStr);

          if ((levelList.isParameter("repartition: enable")      && levelList.get<bool>("repartition: enable")             == true) ||
              (levelList.isParameter("aggregation: drop scheme") && levelList.get<std::string>("aggregation: drop scheme") == "laplacian")) {
            useCoordinates_ = true;
            break;
          }
        }
      }
    }

    // Detect if we do implicit P and R rebalance
    if (paramList.isParameter("repartition: enable") && paramList.get<bool>("repartition: enable") == true)
      this->doPRrebalance_ = paramList.get<bool>("repartition: rebalance P and R", Hierarchy::GetDefaultPRrebalance());

    this->implicitTranspose_ = paramList.get<bool>("transpose: use implicit", Hierarchy::GetDefaultImplicitTranspose());

    // Create default manager
    RCP<FactoryManager> defaultManager = rcp(new FactoryManager());
    defaultManager->SetVerbLevel(this->verbosity_);
    UpdateFactoryManager(paramList, ParameterList(), *defaultManager);
    defaultManager->Print();

    for (int levelID = 0; levelID < this->numDesiredLevel_; levelID++) {
      RCP<FactoryManager> levelManager;

      if (paramList.isSublist("level " + toString(levelID))) {
        // Some level specific parameters, update default manager
        bool mustAlreadyExist = true;
        ParameterList& levelList = paramList.sublist("level " + toString(levelID), mustAlreadyExist);

        levelManager = rcp(new FactoryManager(*defaultManager));
        levelManager->SetVerbLevel(defaultManager->GetVerbLevel());

        UpdateFactoryManager(levelList, paramList, *levelManager);

      } else {
        // No level specific parameter, use default manager
        levelManager = defaultManager;
      }

      this->AddFactoryManager(levelID, 1, levelManager);
    }

    if (paramList.isParameter("strict parameter checking") &&
        paramList.get<bool>  ("strict parameter checking")) {
      ParameterList unusedParamList;

      // Check for unused parameters that aren't lists
      for (ParameterList::ConstIterator itr = paramList.begin(); itr != paramList.end(); ++itr) {
        const ParameterEntry& entry = paramList.entry(itr);

        if (!entry.isList() && !entry.isUsed())
          unusedParamList.setEntry(paramList.name(itr), entry);
      }
#if 0
      // Check for unused parameters in level-specific sublists
      for (int levelID = 0; levelID < this->numDesiredLevel_; levelID++) {
        std::string levelStr = "level" + toString(levelID);

        if (paramList.isSublist(levelStr)) {
          const ParameterList& levelList = paramList.sublist(levelStr);

          for (ParameterList::ConstIterator itr = levelList.begin(); itr != levelList.end(); ++itr) {
            const ParameterEntry& entry = levelList.entry(itr);

            if (!entry.isList() && !entry.isUsed())
              unusedParamList.sublist(levelStr).setEntry(levelList.name(itr), entry);
          }
        }
      }
#endif
      if (unusedParamList.numParams() > 0) {
        std::ostringstream unusedParamsStream;
        int indent = 4;
        unusedParamList.print(unusedParamsStream, indent);

        TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(true, Teuchos::Exceptions::InvalidParameter,
                                            "WARNING: Unused parameters were detected. Please check spelling and type." << std::endl << unusedParamsStream.str());
      }
    }

    // FIXME: parameters passed to packages, like Ifpack2, are not touched by us, resulting in "[unused]" flag
    // being displayed. On the other hand, we don't want to simply iterate through them touching. I don't know
    // what a good solution looks like
    this->GetOStream(static_cast<MsgType>(Runtime1 | Test), 0) << paramList << std::endl;
  }
void ParameterList::validateParametersAndSetDefaults(
  ParameterList const& validParamList,
  int const depth
  )
{
  typedef std::deque<ListPlusValidList> sublist_list_t;
#ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
  RCP<FancyOStream> out = VerboseObjectBase::getDefaultOStream();
  OSTab tab(out);
  *out << "\n*** Entering ParameterList::validateParametersAndSetDefaults(...) "
    "for this->name()=\""<<this->name()<<"\"...\n";
#endif
  //
  // A) loop through and validate the parameters at this level.
  //
  // Here we generate a list of sublists that we will search next
  //
  sublist_list_t sublist_list;
  {
    Iterator itr;
    for (itr = this->nonconstBegin(); itr != this->nonconstEnd(); ++itr) {
      const std::string &entryName = this->name(itr);
      ParameterEntry &theEntry = this->nonconstEntry(itr);
#ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
      OSTab tab(out);
      *out << "\nentryName=\""<<entryName<<"\"\n";
#endif
      const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
      TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
        !validEntry, Exceptions::InvalidParameterName
        ,"Error, the parameter {name=\""<<entryName<<"\","
        "type=\""<<theEntry.getAny(false).typeName()<<"\""
        ",value=\""<<filterValueToString(theEntry)<<"\"}"
        "\nin the parameter (sub)list \""<<this->name()<<"\""
        "\nwas not found in the list of valid parameters!"
        "\n\nThe valid parameters and types are:\n"
        <<validParamList.currentParametersString()
        );
      RCP<const ParameterEntryValidator> validator;
      if (nonnull(validator=validEntry->validator())) {
        validator->validateAndModify(entryName, this->name(), &theEntry);
        theEntry.setValidator(validator);
      }
      else {
        const bool validType =
          ( validEntry!=NULL
            ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
            : false
            );
        TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
          !validType, Exceptions::InvalidParameterType
          ,"Error, the parameter {name=\""<<entryName<<"\","
          "type=\""<<theEntry.getAny(false).typeName()<<"\""
          ",value=\""<<filterValueToString(theEntry)<<"\"}"
          "\nin the parameter (sub)list \""<<this->name()<<"\""
          "\nexists in the list of valid parameters but has the wrong type."
          "\n\nThe correct type is \""
          << validEntry->getAny(false).typeName() << "\"."
          );
        // Note: If there is no validator for this item, then we can not
        // validate the value of the parameter, only its type!
      }
      if( theEntry.isList() && depth > 0 ) {
        sublist_list.push_back(
          ListPlusValidList(
            &getValue<ParameterList>(theEntry),
            &getValue<ParameterList>(*validEntry)
            )
          );
      }
    }
  }
  //
  // B) Loop through the valid parameters at this level that are not set in
  // *this, and set their defaults.
  //
  {
    ConstIterator itr;
    for (itr = validParamList.begin(); itr != validParamList.end(); ++itr) {
      const std::string &validEntryName = validParamList.name(itr);
      const ParameterEntry &validEntry = validParamList.entry(itr);
      const ParameterEntry *theEntry = this->getEntryPtr(validEntryName);
      if (!theEntry) {
        // This entry does not exist, so add it.  Here we will only set the
        // value of the entry and its validator and and leave off the
        // documentation.  The reason that the validator is set is so that it
        // can be used to extract and validate entries in the transformed list
        // *this without having to refer back to the valid parameter list.
        ParameterEntry newEntry;
        newEntry.setAnyValue(
          validEntry.getAny(),
          true // isDefault
          );
        newEntry.setValidator(validEntry.validator());
        this->setEntry(validEntryName,newEntry);
      }
    }
  }
  //
  // C) Loop through the sublists and validate their parameters and set their
  // defaults!
  //
  for (
    sublist_list_t::iterator sl_itr = sublist_list.begin();
    sl_itr != sublist_list.end();
    ++sl_itr
    )
  {
    if (!sl_itr->validList->disableRecursiveValidation_) {
      sl_itr->list->validateParametersAndSetDefaults(*sl_itr->validList,depth-1);
    }
  }
#ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
  *out << "\n*** Existing ParameterList::validateParametersAndSetDefaults(...) "
    "for this->name()=\""<<this->name()<<"\"...\n";
#endif
}
void ParameterList::validateParameters(
  ParameterList const& validParamList,
  int const depth,
  EValidateUsed const validateUsed,
  EValidateDefaults const validateDefaults
  ) const
{
  typedef std::deque<ListPlusValidList> sublist_list_t;
#ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
  RCP<FancyOStream> out = VerboseObjectBase::getDefaultOStream();
  OSTab tab(out);
  *out << "\n*** Entering ParameterList::validateParameters(...) for "
    "this->name()=\""<<this->name()<<"\"...\n";
#endif
  //
  // First loop through and validate the parameters at this level.
  //
  // Here we generate a list of sublists that we will search next
  //
  sublist_list_t sublist_list;
  ConstIterator itr;
  for (itr = this->begin(); itr != this->end(); ++itr) {
    const std::string    &entryName   = this->name(itr);
    const ParameterEntry &theEntry       = this->entry(itr);
#ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
    OSTab tab(out);
    *out << "\nentryName=\""<<entryName<<"\"\n";
#endif
    if(
      ( theEntry.isUsed() && validateUsed!=VALIDATE_USED_ENABLED )
      ||
      ( theEntry.isDefault() && validateDefaults!=VALIDATE_DEFAULTS_ENABLED )
      )
    {
      continue;
    }
    const ParameterEntry *validEntry = validParamList.getEntryPtr(entryName);
    TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
      !validEntry, Exceptions::InvalidParameterName
      ,"Error, the parameter {name=\""<<entryName<<"\","
      "type=\""<<theEntry.getAny(false).typeName()<<"\""
      ",value=\""<<filterValueToString(theEntry)<<"\"}"
      "\nin the parameter (sub)list \""<<this->name()<<"\""
      "\nwas not found in the list of valid parameters!"
      "\n\nThe valid parameters and types are:\n"
      <<validParamList.currentParametersString()
      );
    RCP<const ParameterEntryValidator> validator;
    if (nonnull(validator=validEntry->validator())) {
      validator->validate(theEntry, entryName, this->name());
    }
    else {
      const bool validType =
        ( validEntry!=NULL
          ? theEntry.getAny(false).type() == validEntry->getAny(false).type()
          : false
          );
      TEUCHOS_TEST_FOR_EXCEPTION_PURE_MSG(
        !validType, Exceptions::InvalidParameterType
        ,"Error, the parameter {name=\""<<entryName<<"\","
        "type=\""<<theEntry.getAny(false).typeName()<<"\""
        ",value=\""<<filterValueToString(theEntry)<<"\"}"
        "\nin the parameter (sub)list \""<<this->name()<<"\""
        "\nexists in the list of valid parameters but has the wrong type."
        "\n\nThe correct type is \""
        << validEntry->getAny(false).typeName() << "\"."
        );
    }
    if( theEntry.isList() && depth > 0 ) {
      sublist_list.push_back(
        ListPlusValidList(
          &getValue<ParameterList>(theEntry),&getValue<ParameterList>(*validEntry)
          )
        );
    }
  }
  //
  // Now loop through the sublists and validate their parameters
  //
  for(
    sublist_list_t::const_iterator sl_itr = sublist_list.begin();
    sl_itr != sublist_list.end();
    ++sl_itr
    )
  {
    if (!sl_itr->validList->disableRecursiveValidation_) {
      sl_itr->list->validateParameters(
        *sl_itr->validList
        ,depth-1
        ,validateUsed
        ,validateDefaults
        );
    }
  }
#ifdef TEUCHOS_PARAMETER_LIST_SHOW_TRACE
  *out << "\n*** Existing ParameterList::validateParameters(...) for "
    "this->name()=\""<<this->name()<<"\"...\n";
#endif
}