void
Albany::ResponseFactory::
createResponseFunction(
  const std::string& name,
  Teuchos::ParameterList& responseParams,
  Teuchos::Array< Teuchos::RCP<AbstractResponseFunction> >& responses) const
{
  using std::string;
  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::ParameterList;
  using Teuchos::Array;

  RCP<const Epetra_Comm> comm = app->getComm();

  if (name == "Solution Average") {
    responses.push_back(rcp(new Albany::SolutionAverageResponseFunction(comm)));
  }

  else if (name == "Solution Two Norm") {
    responses.push_back(rcp(new Albany::SolutionTwoNormResponseFunction(comm)));
  }

  else if (name == "Solution Values") {
    responses.push_back(rcp(new Albany::SolutionValuesResponseFunction(app, responseParams)));
  }

  else if (name == "Solution Max Value") {
    int eq = responseParams.get("Equation", 0);
    int neq = responseParams.get("Num Equations", 1);
    bool inor =  responseParams.get("Interleaved Ordering", true);

    responses.push_back(
      rcp(new Albany::SolutionMaxValueResponseFunction(comm, neq, eq, inor)));
  }

  else if (name == "Solution Two Norm File") {
    responses.push_back(
      rcp(new Albany::SolutionFileResponseFunction<Albany::NormTwo>(comm)));
  }

  else if (name == "Solution Inf Norm File") {
    responses.push_back(
      rcp(new Albany::SolutionFileResponseFunction<Albany::NormInf>(comm)));
  }

  else if (name == "Aggregated") {
    int num_aggregate_responses = responseParams.get<int>("Number");
    Array< RCP<AbstractResponseFunction> > aggregated_responses;
    Array< RCP<ScalarResponseFunction> > scalar_responses;
    for (int i=0; i<num_aggregate_responses; i++) {
      std::string id = Albany::strint("Response",i);
      std::string name = responseParams.get<std::string>(id);
      std::string sublist_name = Albany::strint("ResponseParams",i);
      createResponseFunction(name, responseParams.sublist(sublist_name),
			     aggregated_responses);

    }
    scalar_responses.resize(aggregated_responses.size());
    for (int i=0; i<aggregated_responses.size(); i++) {
      TEUCHOS_TEST_FOR_EXCEPTION(
	aggregated_responses[i]->isScalarResponse() != true, std::logic_error,
	"Response function " << i << " is not a scalar response function." <<
	std::endl <<
	"The aggregated response can only aggregate scalar response " <<
	"functions!");
      scalar_responses[i] =
	Teuchos::rcp_dynamic_cast<ScalarResponseFunction>(
	  aggregated_responses[i]);
    }
    responses.push_back(
      rcp(new Albany::AggregateScalarResponseFunction(comm, scalar_responses)));
  }

  else if (name == "Field Integral" ||
	   name == "Field Value" ||
	   name == "Field Average" ||
	   name == "Surface Velocity Mismatch" ||
	   name == "Center Of Mass" ||
	   name == "Save Field" ||
	   name == "Region Boundary" ||
	   name == "Element Size Field" ||
	   name == "IP to Nodal Field" ||
	   name == "Save Nodal Fields" ||
	   name == "PHAL Field Integral") {
    responseParams.set("Name", name);
    for (int i=0; i<meshSpecs.size(); i++) {
      responses.push_back(
	rcp(new Albany::FieldManagerScalarResponseFunction(
	      app, prob, meshSpecs[i], stateMgr, responseParams)));
    }
  }

  else if (name == "Solution") {
    responses.push_back(
      rcp(new Albany::SolutionResponseFunction(app, responseParams)));
  }

  else if (name == "KL") {
    Array< RCP<AbstractResponseFunction> > base_responses;
    std::string name = responseParams.get<std::string>("Response");
    createResponseFunction(name, responseParams.sublist("ResponseParams"),
			   base_responses);
    for (int i=0; i<base_responses.size(); i++)
      responses.push_back(
	rcp(new Albany::KLResponseFunction(base_responses[i], responseParams)));
  }

#ifdef ALBANY_QCAD
  else if (name == "Saddle Value") {
    responseParams.set("Name", name);
    for (int i=0; i<meshSpecs.size(); i++) {
      responses.push_back(
	rcp(new QCAD::SaddleValueResponseFunction(
	      app, prob, meshSpecs[i], stateMgr, responseParams)));
    }
  }
#endif

  else {
    TEUCHOS_TEST_FOR_EXCEPTION(
      true, Teuchos::Exceptions::InvalidParameter,
      std::endl << "Error!  Unknown response function " << name <<
      "!" << std::endl << "Supplied parameter list is " <<
      std::endl << responseParams);
  }
}
  TEUCHOS_UNIT_TEST(gather_orientation, gather_constr)
  {

    const std::size_t workset_size = 4;
    const std::string fieldName_q1 = "U";
    const std::string fieldName_qedge1 = "V";

    Teuchos::RCP<panzer_stk_classic::STK_Interface> mesh = buildMesh(2,2);

    // build input physics block
    Teuchos::RCP<panzer::PureBasis> basis_q1 = buildBasis(workset_size,"Q1");
    Teuchos::RCP<panzer::PureBasis> basis_qedge1 = buildBasis(workset_size,"QEdge1");

    Teuchos::RCP<Teuchos::ParameterList> ipb = Teuchos::parameterList();
    testInitialization(ipb);

    const int default_int_order = 1;
    std::string eBlockID = "eblock-0_0";    
    Teuchos::RCP<user_app::MyFactory> eqset_factory = Teuchos::rcp(new user_app::MyFactory);
    panzer::CellData cellData(workset_size,mesh->getCellTopology("eblock-0_0"));
    Teuchos::RCP<panzer::GlobalData> gd = panzer::createGlobalData();
    Teuchos::RCP<panzer::PhysicsBlock> physicsBlock = 
      Teuchos::rcp(new PhysicsBlock(ipb,eBlockID,default_int_order,cellData,eqset_factory,gd,false));

    Teuchos::RCP<std::vector<panzer::Workset> > work_sets = panzer_stk_classic::buildWorksets(*mesh,*physicsBlock); 
    TEST_EQUALITY(work_sets->size(),1);

    // build connection manager and field manager
    const Teuchos::RCP<panzer::ConnManager<int,int> > conn_manager = Teuchos::rcp(new panzer_stk_classic::STKConnManager<int>(mesh));
    RCP<panzer::DOFManager<int,int> > dofManager = Teuchos::rcp(new panzer::DOFManager<int,int>(conn_manager,MPI_COMM_WORLD));
    dofManager->addField(fieldName_q1,Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_q1->getIntrepid2Basis())));
    dofManager->addField(fieldName_qedge1,Teuchos::rcp(new panzer::Intrepid2FieldPattern(basis_qedge1->getIntrepid2Basis())));
    dofManager->setOrientationsRequired(true);
    dofManager->buildGlobalUnknowns();

    // setup field manager, add evaluator under test
    /////////////////////////////////////////////////////////////
 
    PHX::FieldManager<panzer::Traits> fm;

    Teuchos::RCP<PHX::FieldTag> evalField_q1, evalField_qedge1;
    {
       Teuchos::RCP<std::vector<std::string> > dofNames = Teuchos::rcp(new std::vector<std::string>);
       dofNames->push_back(fieldName_q1);

       Teuchos::ParameterList pl;
       pl.set("Indexer Names",dofNames);
       pl.set("DOF Names",dofNames);
       pl.set("Basis",basis_q1);

       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator  
          = Teuchos::rcp(new panzer::GatherOrientation<panzer::Traits::Residual,panzer::Traits,int,int>(dofManager,pl));

       TEST_EQUALITY(evaluator->evaluatedFields().size(),1);
       evalField_q1 = evaluator->evaluatedFields()[0];

       TEST_EQUALITY(evalField_q1->name(),basis_q1->name()+" Orientation");
       TEST_EQUALITY(evalField_q1->dataLayout().dimension(0),basis_q1->functional->dimension(0));
       TEST_EQUALITY(evalField_q1->dataLayout().dimension(1),basis_q1->functional->dimension(1));

       fm.registerEvaluator<panzer::Traits::Residual>(evaluator);
       fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]);
    }
    {
       Teuchos::RCP<std::vector<std::string> > dofNames = Teuchos::rcp(new std::vector<std::string>);
       dofNames->push_back(fieldName_qedge1);

       Teuchos::ParameterList pl;
       pl.set("Indexer Names",dofNames);
       pl.set("DOF Names",dofNames);
       pl.set("Basis",basis_qedge1);

       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > evaluator  
          = Teuchos::rcp(new panzer::GatherOrientation<panzer::Traits::Residual,panzer::Traits,int,int>(dofManager,pl));

       TEST_EQUALITY(evaluator->evaluatedFields().size(),1);
       evalField_qedge1 = evaluator->evaluatedFields()[0];

       TEST_EQUALITY(evalField_qedge1->name(),basis_qedge1->name()+" Orientation");
       TEST_EQUALITY(evalField_qedge1->dataLayout().dimension(0),basis_qedge1->functional->dimension(0));
       TEST_EQUALITY(evalField_qedge1->dataLayout().dimension(1),basis_qedge1->functional->dimension(1));

       fm.registerEvaluator<panzer::Traits::Residual>(evaluator);
       fm.requireField<panzer::Traits::Residual>(*evaluator->evaluatedFields()[0]);
    }

    panzer::Traits::SetupData sd;
    fm.postRegistrationSetup(sd);

    // run tests
    /////////////////////////////////////////////////////////////

    panzer::Workset & workset = (*work_sets)[0];
    workset.alpha = 0.0;
    workset.beta = 0.0;
    workset.time = 0.0;
    workset.evaluate_transient_terms = false;

    fm.evaluateFields<panzer::Traits::Residual>(workset);

    // <cell,basis>
    PHX::MDField<panzer::Traits::Residual::ScalarT> 
       fieldData_q1(evalField_q1->name(),basis_q1->functional);
    // <cell,basis>
    PHX::MDField<panzer::Traits::Residual::ScalarT> 
       fieldData_qedge1(evalField_qedge1->name(),basis_qedge1->functional);

    fm.getFieldData<panzer::Traits::Residual::ScalarT,panzer::Traits::Residual>(fieldData_q1);
    fm.getFieldData<panzer::Traits::Residual::ScalarT,panzer::Traits::Residual>(fieldData_qedge1);

    for(int i=0;i<fieldData_q1.size();i++) {
       TEST_EQUALITY(fieldData_q1[i],1);
    }

    for(int i=0;i<fieldData_qedge1.dimension(0);i++) {
       TEST_EQUALITY(fieldData_qedge1(i,0), 1);
       TEST_EQUALITY(fieldData_qedge1(i,1), 1);
       TEST_EQUALITY(fieldData_qedge1(i,2),-1);
       TEST_EQUALITY(fieldData_qedge1(i,3),-1);
    }
  }
Exemple #3
0
  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::GetDefaultFactory(const std::string & varName) const {
    if (IsAvailable(varName, defaultFactoryTable_)) {

      return defaultFactoryTable_[varName];

    } else {

      if (varName == "A")             return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
      if (varName == "RAP Pattern")   return GetFactory("A");
      if (varName == "AP Pattern")    return GetFactory("A");
      if (varName == "P") {
        RCP<Factory> factory = rcp(new SaPFactory());
        factory->SetFactory("P", GetFactory("Ptent")); // GetFactory("Ptent"): Use the same factory instance for both "P" and "Nullspace"
        return SetAndReturnDefaultFactory(varName, factory);
      }

      if (varName == "R")             return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
#if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
      if (varName == "Partition")     {
        return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
      }
#endif //ifdef HAVE_MPI

      if (varName == "Importer") {
#ifdef HAVE_MPI
        return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
#else
        return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
#endif
      }
      if (varName == "number of partitions") {
        return GetFactory("Importer");
      }
      //JJH FIXME is this going to bite me in the backside?
//       if (varName == "Coordinates") {
//         return SetAndReturnDefaultFactory(varName, rcp(new MueLu::MultiVectorTransferFactory<SC,LO,GO,NO,LMO>(varName,"R")));
//       }

      if (varName == "Nullspace") {
        RCP<Factory> factory = rcp(new NullspaceFactory());
        factory->SetFactory("Nullspace", GetFactory("Ptent")); // GetFactory("Ptent"): Use the same factory instance for both "P" and "Nullspace"
        return SetAndReturnDefaultFactory(varName, factory);
      }

      if (varName == "Graph")               return SetAndReturnDefaultFactory(varName, rcp(new CoalesceDropFactory()));
      if (varName == "UnAmalgamationInfo")  return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory())); //GetFactory("Graph"));
      if (varName == "Aggregates")          return SetAndReturnDefaultFactory(varName, rcp(new CoupledAggregationFactory()));
      if (varName == "CoarseMap")           return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
      if (varName == "DofsPerNode")         return GetFactory("Graph");
      if (varName == "Filtering")           return GetFactory("Graph");

      // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
      if (varName == "PreSmoother")         return GetFactory("Smoother");
      if (varName == "PostSmoother")        return GetFactory("Smoother");

#ifdef HAVE_MUELU_EXPERIMENTAL
      if (varName == "Ppattern") {
        RCP<PatternFactory> PpFact = rcp(new PatternFactory);
        PpFact->SetFactory("P", GetFactory("Ptent"));
        return SetAndReturnDefaultFactory(varName, PpFact);
      }
      if (varName == "Constraint")          return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
#endif

      //if (varName == "Smoother")    return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new GaussSeidelSmoother()))));
      if (varName == "Smoother") {
        Teuchos::ParameterList smootherParamList;
        smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
        smootherParamList.set("relaxation: sweeps", (LO) 1);
        smootherParamList.set("relaxation: damping factor", (Scalar) 1.0); //FIXME once Ifpack2's parameter list validator is fixed, change this back to Scalar
        return SetAndReturnDefaultFactory(varName, rcp( new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
      }

      if (varName == "CoarseSolver")  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()),Teuchos::null)));

      if (varName == "Ptent") return SetAndReturnDefaultFactory(varName, rcp(new TentativePFactory())); // Use the same factory instance for both "P" and "Nullspace"

      TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '"+varName+"'.");
    }

  }
  void MLParameterListInterpreter<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps>::SetParameterList(const Teuchos::ParameterList & paramList_in) {
    Teuchos::ParameterList paramList = paramList_in;

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

    //
    // Read top-level of the parameter list
    //

    // hard-coded default values == ML defaults according to the manual
    MUELU_READ_PARAM(paramList, "ML output",                                int,                   0,       verbosityLevel);
    MUELU_READ_PARAM(paramList, "max levels",                               int,                  10,       maxLevels);
    MUELU_READ_PARAM(paramList, "PDE equations",                            int,                   1,       nDofsPerNode);

    MUELU_READ_PARAM(paramList, "coarse: max size",                         int,                 128,       maxCoarseSize);

    MUELU_READ_PARAM(paramList, "aggregation: type",                std::string,         "Uncoupled",       agg_type);
    //MUELU_READ_PARAM(paramList, "aggregation: threshold",                double,                 0.0,       agg_threshold);
    MUELU_READ_PARAM(paramList, "aggregation: damping factor",           double, (double)4/(double)3,       agg_damping);
    //MUELU_READ_PARAM(paramList, "aggregation: smoothing sweeps",            int,                   1,       agg_smoothingsweeps);
    MUELU_READ_PARAM(paramList, "aggregation: nodes per aggregate",         int,                   1,       minPerAgg);
    MUELU_READ_PARAM(paramList, "aggregation: keep Dirichlet bcs",         bool,               false,       bKeepDirichletBcs); // This is a MueLu specific extension that does not exist in ML
    MUELU_READ_PARAM(paramList, "aggregation: max neighbours already aggregated", int,             0,       maxNbrAlreadySelected); // This is a MueLu specific extension that does not exist in ML

    MUELU_READ_PARAM(paramList, "null space: type",                 std::string,   "default vectors",       nullspaceType);
    MUELU_READ_PARAM(paramList, "null space: dimension",                    int,                  -1,       nullspaceDim); // TODO: ML default not in documentation
    MUELU_READ_PARAM(paramList, "null space: vectors",                   double*,               NULL,       nullspaceVec); // TODO: ML default not in documentation

    MUELU_READ_PARAM(paramList, "energy minimization: enable",             bool,               false,       bEnergyMinimization);

    MUELU_READ_PARAM(paramList, "RAP: fix diagonal",                       bool,               false,       bFixDiagonal); // This is a MueLu specific extension that does not exist in 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

    // std::cout << std::endl << "Parameter list after CreateSublists" << std::endl;
    // std::cout << paramListWithSubList << std::endl;

    //
    // 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


    //
    //
    //



    // Matrix option
    blksize_ = nDofsPerNode;

    // Translate verbosity parameter

    // Translate verbosity parameter
    MsgType eVerbLevel = None;
    if (verbosityLevel == 0) eVerbLevel = None;
    if (verbosityLevel >  0) eVerbLevel = Low;
    if (verbosityLevel >  4) eVerbLevel = Medium;
    if (verbosityLevel >  7) eVerbLevel = High;
    if (verbosityLevel >  9) eVerbLevel = Extreme;
    if (verbosityLevel >  9) eVerbLevel = Test;
    this->verbosity_ = eVerbLevel;


    TEUCHOS_TEST_FOR_EXCEPTION(agg_type != "Uncoupled" && agg_type != "Coupled", Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter::Setup(): parameter \"aggregation: type\": only 'Uncoupled' or 'Coupled' aggregation is supported.");

    // Create MueLu factories
    RCP<CoalesceDropFactory> dropFact = rcp(new CoalesceDropFactory());

    RCP<FactoryBase> CoupledAggFact = Teuchos::null;
    if(agg_type == "Uncoupled") {
      // Uncoupled aggregation
      RCP<UncoupledAggregationFactory> CoupledAggFact2 = rcp(new UncoupledAggregationFactory());
      /*CoupledAggFact2->SetMinNodesPerAggregate(minPerAgg); //TODO should increase if run anything other than 1D
      CoupledAggFact2->SetMaxNeighAlreadySelected(maxNbrAlreadySelected);
      CoupledAggFact2->SetOrdering("natural");*/
      CoupledAggFact2->SetFactory("Graph", dropFact);
      CoupledAggFact2->SetFactory("DofsPerNode", dropFact);
      CoupledAggFact2->SetParameter("UsePreserveDirichletAggregationAlgorithm", Teuchos::ParameterEntry(bKeepDirichletBcs));
      CoupledAggFact2->SetParameter("aggregation: ordering",                Teuchos::ParameterEntry(std::string("natural")));
      CoupledAggFact2->SetParameter("aggregation: max selected neighbors",  Teuchos::ParameterEntry(maxNbrAlreadySelected));
      CoupledAggFact2->SetParameter("aggregation: min agg size",            Teuchos::ParameterEntry(minPerAgg));

      CoupledAggFact = CoupledAggFact2;
    } else {
      // Coupled Aggregation (default)
      RCP<CoupledAggregationFactory> CoupledAggFact2 = rcp(new CoupledAggregationFactory());
      CoupledAggFact2->SetMinNodesPerAggregate(minPerAgg); //TODO should increase if run anything other than 1D
      CoupledAggFact2->SetMaxNeighAlreadySelected(maxNbrAlreadySelected);
      CoupledAggFact2->SetOrdering("natural");
      CoupledAggFact2->SetPhase3AggCreation(0.5);
      CoupledAggFact2->SetFactory("Graph", dropFact);
      CoupledAggFact2->SetFactory("DofsPerNode", dropFact);
      CoupledAggFact = CoupledAggFact2;
    }
    if (verbosityLevel > 3) { // TODO fix me: Setup is a static function: we cannot use GetOStream without an object...
      *out << "========================= Aggregate option summary  =========================" << std::endl;
      *out << "min Nodes per aggregate :               " << minPerAgg << std::endl;
      *out << "min # of root nbrs already aggregated : " << maxNbrAlreadySelected << std::endl;
      *out << "aggregate ordering :                    natural" << std::endl;
      *out << "=============================================================================" << std::endl;
    }

    RCP<Factory> PFact;
    RCP<Factory> RFact;
    RCP<Factory> PtentFact = rcp( new TentativePFactory() );
    if (agg_damping == 0.0 && bEnergyMinimization == false) {
      // tentative prolongation operator (PA-AMG)
      PFact = PtentFact;
      RFact = rcp( new TransPFactory() );
    } else if (agg_damping != 0.0 && bEnergyMinimization == false) {
      // smoothed aggregation (SA-AMG)
      RCP<SaPFactory> SaPFact =  rcp( new SaPFactory() );
      SaPFact->SetDampingFactor(agg_damping);
      PFact  = SaPFact;
      RFact  = rcp( new TransPFactory() );
    } else if (bEnergyMinimization == true) {
      // Petrov Galerkin PG-AMG smoothed aggregation (energy minimization in ML)
      PFact  = rcp( new PgPFactory() );
      RFact  = rcp( new GenericRFactory() );
    }

    RCP<RAPFactory> AcFact = rcp( new RAPFactory() );
    AcFact->SetParameter("RepairMainDiagonal", Teuchos::ParameterEntry(bFixDiagonal));
    for (size_t i = 0; i<TransferFacts_.size(); i++) {
      AcFact->AddTransferFactory(TransferFacts_[i]);
    }

    //
    // introduce rebalancing
    //
#if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
    Teuchos::RCP<Factory>            RebalancedPFact = Teuchos::null;
    Teuchos::RCP<Factory>            RebalancedRFact = Teuchos::null;
    Teuchos::RCP<Factory>            RepartitionFact = Teuchos::null;
    Teuchos::RCP<RebalanceAcFactory> RebalancedAFact = Teuchos::null;

    MUELU_READ_PARAM(paramList, "repartition: enable",                      int,                   0,       bDoRepartition);
    if (bDoRepartition == 1) {
      // The Factory Manager will be configured to return the rebalanced versions of P, R, A by default.
      // Everytime we want to use the non-rebalanced versions, we need to explicitly define the generating factory.
      RFact->SetFactory("P", PFact);
      //
      AcFact->SetFactory("P", PFact);
      AcFact->SetFactory("R", RFact);

      MUELU_READ_PARAM(paramList, "repartition: max min ratio",            double,                 1.3,       maxminratio);
      MUELU_READ_PARAM(paramList, "repartition: min per proc",                int,                 512,       minperproc);

      // create "Partition"
      Teuchos::RCP<MueLu::IsorropiaInterface<LO, GO, NO, LMO> > isoInterface = Teuchos::rcp(new MueLu::IsorropiaInterface<LO, GO, NO, LMO>());
      isoInterface->SetFactory("A", AcFact);

      // Repartitioning (creates "Importer" from "Partition")
      RepartitionFact = Teuchos::rcp(new RepartitionFactory());
      {
        Teuchos::ParameterList paramListRepFact;
        paramListRepFact.set("repartition: min rows per proc", minperproc);
        paramListRepFact.set("repartition: max imbalance", maxminratio);
        RepartitionFact->SetParameterList(paramListRepFact);
      }
      RepartitionFact->SetFactory("A", AcFact);
      RepartitionFact->SetFactory("Partition", isoInterface);

      // Reordering of the transfer operators
      RebalancedPFact = Teuchos::rcp(new RebalanceTransferFactory());
      RebalancedPFact->SetParameter("type", Teuchos::ParameterEntry(std::string("Interpolation")));
      RebalancedPFact->SetFactory("P", PFact);

      RebalancedRFact = Teuchos::rcp(new RebalanceTransferFactory());
      RebalancedRFact->SetParameter("type", Teuchos::ParameterEntry(std::string("Restriction")));
      RebalancedRFact->SetFactory("R", RFact);
      RebalancedRFact->SetFactory("Nullspace", PtentFact);

      // Compute Ac from rebalanced P and R
      RebalancedAFact = Teuchos::rcp(new RebalanceAcFactory());
      RebalancedAFact->SetFactory("A", AcFact);
    }
int main(int argc, char *argv[])
{
#ifndef HAVE_TPETRA_COMPLEX_DOUBLE
#  error "Anasazi: This test requires Scalar = std::complex<double> to be enabled in Tpetra."
#else
  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::tuple;
  using std::cout;
  using std::endl;

  typedef std::complex<double>                ST;
  typedef Teuchos::ScalarTraits<ST>          SCT;
  typedef SCT::magnitudeType                  MT;
  typedef Tpetra::MultiVector<ST>             MV;
  typedef MV::global_ordinal_type             GO;
  typedef Tpetra::Operator<ST>                OP;
  typedef Anasazi::MultiVecTraits<ST,MV>     MVT;
  typedef Anasazi::OperatorTraits<ST,MV,OP>  OPT;

  Tpetra::ScopeGuard tpetraScope (&argc, &argv);

  bool success = false;

  const ST ONE = SCT::one ();

  int info = 0;

  RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm ();

  const int MyPID = comm->getRank ();

  bool verbose = false;
  bool debug = false;
  bool insitu = false;
  bool herm = false;
  std::string which("LM");
  std::string filename;
  int nev = 4;
  int blockSize = 4;
  MT tol = 1.0e-6;

  Teuchos::CommandLineProcessor cmdp(false,true);
  cmdp.setOption("verbose","quiet",&verbose,"Print messages and results.");
  cmdp.setOption("debug","nodebug",&debug,"Print debugging information.");
  cmdp.setOption("insitu","exsitu",&insitu,"Perform in situ restarting.");
  cmdp.setOption("sort",&which,"Targetted eigenvalues (SM or LM).");
  cmdp.setOption("herm","nonherm",&herm,"Solve Hermitian or non-Hermitian problem.");
  cmdp.setOption("filename",&filename,"Filename for Harwell-Boeing test matrix (assumes non-Hermitian unless specified otherwise).");
  cmdp.setOption("nev",&nev,"Number of eigenvalues to compute.");
  cmdp.setOption("blockSize",&blockSize,"Block size for the algorithm.");
  cmdp.setOption("tol",&tol,"Tolerance for convergence.");
  if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
    return -1;
  }
  if (debug) verbose = true;
  if (filename == "") {
    // get default based on herm
    if (herm) {
      filename = "mhd1280b.cua";
    }
    else {
      filename = "mhd1280a.cua";
    }
  }

  if (MyPID == 0) {
    cout << Anasazi::Anasazi_Version() << endl << endl;
  }

  // Get the data from the HB file
  int dim,dim2,nnz;
  int rnnzmax;
  double *dvals;
  int *colptr,*rowind;
  nnz = -1;
  if (MyPID == 0) {
    info = readHB_newmat_double(filename.c_str(),&dim,&dim2,&nnz,&colptr,&rowind,&dvals);
    // find maximum NNZ over all rows
    vector<int> rnnz(dim,0);
    for (int *ri=rowind; ri<rowind+nnz; ++ri) {
      ++rnnz[*ri-1];
    }
    rnnzmax = *std::max_element(rnnz.begin(),rnnz.end());
  }
  else {
    // address uninitialized data warnings
    dvals = NULL;
    colptr = NULL;
    rowind = NULL;
  }
  Teuchos::broadcast(*comm,0,&info);
  Teuchos::broadcast(*comm,0,&nnz);
  Teuchos::broadcast(*comm,0,&dim);
  Teuchos::broadcast(*comm,0,&rnnzmax);
  if (info == 0 || nnz < 0) {
    if (MyPID == 0) {
      cout << "Error reading '" << filename << "'" << endl
           << "End Result: TEST FAILED" << endl;
    }
    return -1;
  }
  // create map
  RCP<const Map<> > map = rcp (new Map<> (dim, 0, comm));
  RCP<CrsMatrix<ST> > K = rcp (new CrsMatrix<ST> (map, rnnzmax));
  if (MyPID == 0) {
    // Convert interleaved doubles to complex values
    // HB format is compressed column. CrsMatrix is compressed row.
    const double *dptr = dvals;
    const int *rptr = rowind;
    for (int c=0; c<dim; ++c) {
      for (int colnnz=0; colnnz < colptr[c+1]-colptr[c]; ++colnnz) {
        K->insertGlobalValues (static_cast<GO> (*rptr++ - 1), tuple<GO> (c), tuple (ST (dptr[0], dptr[1])));
        dptr += 2;
      }
    }
  }
  if (MyPID == 0) {
    // Clean up.
    free( dvals );
    free( colptr );
    free( rowind );
  }
  K->fillComplete();
  // cout << *K << endl;

  // Create initial vectors
  RCP<MV> ivec = rcp( new MV(map,blockSize) );
  ivec->randomize ();

  // Create eigenproblem
  RCP<Anasazi::BasicEigenproblem<ST,MV,OP> > problem =
    rcp( new Anasazi::BasicEigenproblem<ST,MV,OP>(K,ivec) );
  //
  // Inform the eigenproblem that the operator K is symmetric
  problem->setHermitian(herm);
  //
  // Set the number of eigenvalues requested
  problem->setNEV( nev );
  //
  // Inform the eigenproblem that you are done passing it information
  bool boolret = problem->setProblem();
  if (boolret != true) {
    if (MyPID == 0) {
      cout << "Anasazi::BasicEigenproblem::SetProblem() returned with error." << endl
           << "End Result: TEST FAILED" << endl;
    }
    return -1;
  }


  // Set verbosity level
  int verbosity = Anasazi::Errors + Anasazi::Warnings + Anasazi::FinalSummary + Anasazi::TimingDetails;
  if (verbose) {
    verbosity += Anasazi::IterationDetails;
  }
  if (debug) {
    verbosity += Anasazi::Debug;
  }



  // Eigensolver parameters
  int numBlocks = 8;
  int maxRestarts = 10;
  //
  // Create parameter list to pass into the solver manager
  Teuchos::ParameterList MyPL;
  MyPL.set( "Verbosity", verbosity );
  MyPL.set( "Which", which );
  MyPL.set( "Block Size", blockSize );
  MyPL.set( "Num Blocks", numBlocks );
  MyPL.set( "Maximum Restarts", maxRestarts );
  MyPL.set( "Convergence Tolerance", tol );
  MyPL.set( "In Situ Restarting", insitu );
  //
  // Create the solver manager
  Anasazi::BlockKrylovSchurSolMgr<ST,MV,OP> MySolverMgr(problem, MyPL);

  // Solve the problem to the specified tolerances or length
  Anasazi::ReturnType returnCode = MySolverMgr.solve();
  success = (returnCode == Anasazi::Converged);

  // Get the eigenvalues and eigenvectors from the eigenproblem
  Anasazi::Eigensolution<ST,MV> sol = problem->getSolution();
  RCP<MV> evecs = sol.Evecs;
  int numev = sol.numVecs;

  if (numev > 0) {
    std::ostringstream os;
    os.setf(std::ios::scientific, std::ios::floatfield);
    os.precision(6);

    // Compute the direct residual
    std::vector<MT> normV( numev );
    Teuchos::SerialDenseMatrix<int,ST> T (numev, numev);
    for (int i=0; i<numev; i++) {
      T(i,i) = ST(sol.Evals[i].realpart,sol.Evals[i].imagpart);
    }
    RCP<MV> Kvecs = MVT::Clone( *evecs, numev );

    OPT::Apply( *K, *evecs, *Kvecs );

    MVT::MvTimesMatAddMv( -ONE, *evecs, T, ONE, *Kvecs );
    MVT::MvNorm( *Kvecs, normV );

    os << "Direct residual norms computed in BlockKrylovSchurComplex_test.exe" << endl
       << std::setw(20) << "Eigenvalue" << std::setw(20) << "Residual  " << endl
       << "----------------------------------------" << endl;
    for (int i=0; i<numev; i++) {
      if ( SCT::magnitude(T(i,i)) != SCT::zero() ) {
        normV[i] = SCT::magnitude(normV[i]/T(i,i));
      }
      os << std::setw(20) << T(i,i) << std::setw(20) << normV[i] << endl;
      success = (normV[i] < tol);
    }
    if (MyPID==0) {
      cout << endl << os.str() << endl;
    }
  }

  if (MyPID==0) {
    if (success)
      cout << "End Result: TEST PASSED" << endl;
    else
      cout << "End Result: TEST FAILED" << endl;
  }

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
#endif // HAVE_TPETRA_COMPLEX_DOUBLE
}
int main(int argc, char *argv[]) {
#include "MueLu_UseShortNames.hpp"

  using Teuchos::RCP;
  using Teuchos::rcp;

  //
  // MPI initialization
  //

  Teuchos::oblackholestream blackhole;
  Teuchos::GlobalMPISession mpiSession(&argc, &argv, &blackhole);

  bool success = false;
  bool verbose = true;
  try {
    RCP< const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();

    //
    // Process command line arguments
    //
    Teuchos::CommandLineProcessor  clp(false);
    Galeri::Xpetra::Parameters<GO> matrixParameters(clp, 81); // manage parameters of the test case
    Xpetra::Parameters             xpetraParameters(clp);     // manage parameters of xpetra

    switch (clp.parse(argc,argv)) {
      case Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED:        return EXIT_SUCCESS;
      case Teuchos::CommandLineProcessor::PARSE_ERROR:
      case Teuchos::CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION: return EXIT_FAILURE;
      case Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL:          break;
      default:;
    }

    if (comm->getRank() == 0) std::cout << xpetraParameters << matrixParameters;

    //
    // Setup test case (Ax = b)
    //

    // Linear Algebra Library
    Xpetra::UnderlyingLib lib = xpetraParameters.GetLib();

    // Distribution
    RCP<const Map> map = MapFactory::Build(lib, matrixParameters.GetNumGlobalElements(), 0, comm);

    // Matrix
    RCP<Galeri::Xpetra::Problem<Map,CrsMatrixWrap,MultiVector> > Pr =
      Galeri::Xpetra::BuildProblem<SC, LO, GO, Map, CrsMatrixWrap, MultiVector>(matrixParameters.GetMatrixType(), map, matrixParameters.GetParameterList());
    RCP<Matrix> A = Pr->BuildMatrix();

    // User defined nullspace
    RCP<MultiVector> nullSpace = VectorFactory::Build(map,1); nullSpace->putScalar((SC) 1.0);

    // Define B
    RCP<Vector> X = VectorFactory::Build(map,1);
    RCP<Vector> B = VectorFactory::Build(map,1);
    X->setSeed(846930886);
    X->randomize();
    A->apply(*X, *B, Teuchos::NO_TRANS, (SC)1.0, (SC)0.0);

    // X = 0
    X->putScalar((SC) 0.0);

    //
    // Create a multigrid configuration
    //

    // Transfer operators
    RCP<TentativePFactory> TentativePFact = rcp( new TentativePFactory() );
    RCP<SaPFactory>        SaPFact        = rcp( new SaPFactory() );
    RCP<TransPFactory>     RFact          = rcp( new TransPFactory());

    FactoryManager M;
    M.SetFactory("Ptent", TentativePFact);
    M.SetFactory("P",     SaPFact);
    M.SetFactory("R",     RFact);

    M.SetFactory("Smoother", Teuchos::null);      //skips smoother setup
    M.SetFactory("CoarseSolver", Teuchos::null);  //skips coarsest solve setup

    //
    // Multigrid setup phase
    //

    int startLevel = 0;
    int maxLevels = 10;

    std::cout << "=============== Setup transfers only ====================" << std::endl;

    Hierarchy H;
    H.SetDefaultVerbLevel(MueLu::Medium);

    RCP<Level> finestLevel = H.GetLevel();
    finestLevel->Set("A", A);
    finestLevel->Set("Nullspace", nullSpace);

    // Indicate which Hierarchy operators we want to keep
    H.Keep("P", SaPFact.get());  //SaPFact is the generating factory for P.
    H.Keep("R", RFact.get());    //RFact is the generating factory for R.
    H.Keep("Ptent", TentativePFact.get());  //SaPFact is the generating factory for P.

    H.Setup(M,startLevel,maxLevels);

    std::cout << "=============== Setup smoothers only ====================" << std::endl;

    // Create a new A.
    RCP<Matrix> newA = Pr->BuildMatrix();
    finestLevel->Set("A", newA);

    // Create Gauss-Seidel smoother.
    std::string ifpackType = "RELAXATION";
    Teuchos::ParameterList ifpackList;
    ifpackList.set("relaxation: sweeps", (LO) 3);
    ifpackList.set("relaxation: damping factor", (SC) 1.0);
    RCP<SmootherPrototype> smootherPrototype = rcp(new TrilinosSmoother(ifpackType, ifpackList));

    M.SetFactory("Smoother", rcp(new SmootherFactory(smootherPrototype)));

    // Create coarsest solver.
    RCP<SmootherPrototype> coarseSolverPrototype = rcp( new DirectSolver() );
    RCP<SmootherFactory>   coarseSolverFact      = rcp( new SmootherFactory(coarseSolverPrototype, Teuchos::null) );
    M.SetFactory("CoarseSolver", coarseSolverFact);

    // Note that we pass the number of levels back in.
    H.Setup(M,startLevel, H.GetNumLevels());

    std::cout << "=============== Solve ====================" << std::endl;

    //
    // Solve Ax = B
    //

    LO nIts = 9;
    H.Iterate(*B, *X, nIts);

    //
    // Print relative residual norm
    //

    Teuchos::ScalarTraits<SC>::magnitudeType residualNorms = Utilities::ResidualNorm(*A, *X, *B)[0];
    if (comm->getRank() == 0) {
      std::ios::fmtflags f(std::cout.flags());
      std::cout << "||Residual|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(20) << residualNorms << std::endl;
       std::cout.flags(f);
    }

    success = true;
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}
Exemple #7
0
bool CompareWithAztecOO(Epetra_LinearProblem& Problem, const std::string what,
                       int Overlap, int ival)
{
  using std::cout;
  using std::endl;

  AztecOO AztecOOSolver(Problem);
  AztecOOSolver.SetAztecOption(AZ_solver,AZ_gmres);
  AztecOOSolver.SetAztecOption(AZ_output,AZ_none);
  AztecOOSolver.SetAztecOption(AZ_overlap,Overlap);
  AztecOOSolver.SetAztecOption(AZ_graph_fill,ival);
  AztecOOSolver.SetAztecOption(AZ_poly_ord, ival);
  AztecOOSolver.SetAztecParam(AZ_drop, 0.0);
  AztecOOSolver.SetAztecParam(AZ_athresh, 0.0);
  AztecOOSolver.SetAztecParam(AZ_rthresh, 0.0);

  Epetra_MultiVector& RHS = *(Problem.GetRHS());
  Epetra_MultiVector& LHS = *(Problem.GetLHS());
  Teuchos::RefCountPtr<Epetra_RowMatrix> A = Teuchos::rcp(Problem.GetMatrix(), false);

  LHS.Random();
  A->Multiply(false,LHS,RHS);

  Teuchos::ParameterList List;
  List.set("fact: level-of-fill", ival);
  List.set("relaxation: sweeps", ival);
  List.set("relaxation: damping factor", 1.0);
  List.set("relaxation: zero starting solution", true);

  //default combine mode is as for AztecOO
  List.set("schwarz: combine mode", Zero);

  Epetra_Time Time(A->Comm());

  Teuchos::RefCountPtr<Ifpack_Preconditioner> Prec;

  if (what == "Jacobi") {
    Prec = Teuchos::rcp( new Ifpack_PointRelaxation(&*A) );
    List.set("relaxation: type", "Jacobi");
    AztecOOSolver.SetAztecOption(AZ_precond,AZ_Jacobi);
    AztecOOSolver.SetAztecOption(AZ_reorder,0);
  }
  else if (what == "IC no reord") {
    Prec = Teuchos::rcp( new Ifpack_AdditiveSchwarz<Ifpack_IC>(&*A,Overlap) );
    AztecOOSolver.SetAztecOption(AZ_precond,AZ_dom_decomp);
    AztecOOSolver.SetAztecOption(AZ_subdomain_solve,AZ_icc);
    AztecOOSolver.SetAztecOption(AZ_reorder,0);
  }
  else if (what == "IC reord") {
    Prec = Teuchos::rcp( new Ifpack_AdditiveSchwarz<Ifpack_IC>(&*A,Overlap) );
    List.set("schwarz: use reordering", true);
    AztecOOSolver.SetAztecOption(AZ_precond,AZ_dom_decomp);
    AztecOOSolver.SetAztecOption(AZ_subdomain_solve,AZ_icc);
    AztecOOSolver.SetAztecOption(AZ_reorder,1);
  }
  else if (what == "ILU no reord") {
    Prec = Teuchos::rcp( new Ifpack_AdditiveSchwarz<Ifpack_ILU>(&*A,Overlap) );
    AztecOOSolver.SetAztecOption(AZ_precond,AZ_dom_decomp);
    AztecOOSolver.SetAztecOption(AZ_subdomain_solve,AZ_ilu);
    AztecOOSolver.SetAztecOption(AZ_reorder,0);
  }
  else if (what == "ILU reord") {
    Prec = Teuchos::rcp( new Ifpack_AdditiveSchwarz<Ifpack_ILU>(&*A,Overlap) );
    List.set("schwarz: use reordering", true);
    AztecOOSolver.SetAztecOption(AZ_precond,AZ_dom_decomp);
    AztecOOSolver.SetAztecOption(AZ_subdomain_solve,AZ_ilu);
    AztecOOSolver.SetAztecOption(AZ_reorder,1);
  }
#ifdef HAVE_IFPACK_AMESOS
  else if (what == "LU") {
    Prec = Teuchos::rcp( new Ifpack_AdditiveSchwarz<Ifpack_Amesos>(&*A,Overlap) );
    List.set("amesos: solver type", "Klu");
    AztecOOSolver.SetAztecOption(AZ_precond,AZ_dom_decomp);
    AztecOOSolver.SetAztecOption(AZ_subdomain_solve,AZ_lu);
  }
#endif
  else {
    cerr << "Option not recognized" << endl;
    exit(EXIT_FAILURE);
  }

  // ==================================== //
  // Solve with AztecOO's preconditioners //
  // ==================================== //

  LHS.PutScalar(0.0);

  Time.ResetStartTime();
  AztecOOSolver.Iterate(150,1e-5);

  if (verbose) {
    cout << endl;
    cout << "==================================================" << endl;
    cout << "Testing `" << what << "', Overlap = "
         << Overlap << ", ival = " << ival << endl;
    cout << endl;
    cout << "[AztecOO] Total time = " << Time.ElapsedTime() << " (s)" << endl;
    cout << "[AztecOO] Residual   = " << AztecOOSolver.TrueResidual() << " (s)" << endl;
    cout << "[AztecOO] Iterations = " << AztecOOSolver.NumIters() << endl;
    cout << endl;
  }

  int AztecOOPrecIters = AztecOOSolver.NumIters();

  // =========================================== //
  // Create the IFPACK preconditioner and solver //
  // =========================================== //

  Epetra_Time Time2(A->Comm());
  assert(Prec != Teuchos::null);
  IFPACK_CHK_ERR(Prec->SetParameters(List));

  Time.ResetStartTime();
  IFPACK_CHK_ERR(Prec->Initialize());
  if (verbose)
    cout << "[IFPACK] Time for Initialize() = "
         << Time.ElapsedTime() << " (s)" << endl;

  Time.ResetStartTime();
  IFPACK_CHK_ERR(Prec->Compute());
  if (verbose)
    cout << "[IFPACK] Time for Compute() = "
         << Time.ElapsedTime() << " (s)" << endl;


  AztecOOSolver.SetPrecOperator(&*Prec);

  LHS.PutScalar(0.0);

  Time.ResetStartTime();
  AztecOOSolver.Iterate(150,1e-5);

  if (verbose) {
    cout << "[IFPACK] Total time = " << Time2.ElapsedTime() << " (s)" << endl;
    cout << "[IFPACK] Residual   = " << AztecOOSolver.TrueResidual() << " (s)" << endl;
    cout << "[IFPACK] Iterations = " << AztecOOSolver.NumIters() << endl;
    cout << endl;
  }

  int IFPACKPrecIters = AztecOOSolver.NumIters();

  if (IFPACK_ABS(AztecOOPrecIters - IFPACKPrecIters) > 3) {
    cerr << "TEST FAILED (" << AztecOOPrecIters << " != "
         << IFPACKPrecIters << ")" << endl;
    return(false);
  }
  else
    return(true);

}
Exemple #8
0
// The solve is done in the felix_driver_run function, and the solution is passed back to Glimmer-CISM 
// IK, 12/3/13: time_inc_yr and cur_time_yr are not used here... 
void felix_driver_run(FelixToGlimmer * ftg_ptr, double& cur_time_yr, double time_inc_yr)
{
    //IK, 12/9/13: how come FancyOStream prints an all processors??    
    Teuchos::RCP<Teuchos::FancyOStream> out(Teuchos::VerboseObjectBase::getDefaultOStream());

    if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) {
      std::cout << "In felix_driver_run, cur_time, time_inc = " << cur_time_yr 
                << "   " << time_inc_yr << std::endl;
    }
    
    // ---------------------------------------------
    // get u and v velocity solution from Glimmer-CISM 
    // IK, 11/26/13: need to concatenate these into a single solve for initial condition for Albany/FELIX solve 
    // IK, 3/14/14: moved this step to felix_driver_run from felix_driver init, since we still want to grab and u and v velocities for CISM if the mesh hasn't changed, 
    // in which case only felix_driver_run will be called, not felix_driver_init.   
    // ---------------------------------------------
    if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) 
      std::cout << "In felix_driver_run: grabbing pointers to u and v velocities in CISM..." << std::endl; 
    uVel_ptr = ftg_ptr ->getDoubleVar("uvel", "velocity"); 
    vVel_ptr = ftg_ptr ->getDoubleVar("vvel", "velocity"); 

    // ---------------------------------------------
    // Set restart solution to the one passed from CISM
    // IK, 3/14/14: moved this from felix_driver_init to felix_driver_run.  
    // ---------------------------------------------
    
    if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) 
      std::cout << "In felix_driver_run: setting initial condition from CISM..." << std::endl;
    //Check what kind of ordering you have in the solution & create solutionField object.
    interleavedOrdering = meshStruct->getInterleavedOrdering();
    Albany::AbstractSTKFieldContainer::VectorFieldType* solutionField;
    if(interleavedOrdering)
      solutionField = Teuchos::rcp_dynamic_cast<Albany::OrdinarySTKFieldContainer<true> >(meshStruct->getFieldContainer())->getSolutionField();
    else
      solutionField = Teuchos::rcp_dynamic_cast<Albany::OrdinarySTKFieldContainer<false> >(meshStruct->getFieldContainer())->getSolutionField();

     //Create vector used to renumber nodes on each processor from the Albany convention (horizontal levels first) to the CISM convention (vertical layers first)
     nNodes2D = (global_ewn + 1)*(global_nsn+1); //number global nodes in the domain in 2D 
     nNodesProc2D = (nsn-2*nhalo+1)*(ewn-2*nhalo+1); //number of nodes on each processor in 2D  
     cismToAlbanyNodeNumberMap.resize(upn*nNodesProc2D);
     for (int j=0; j<nsn-2*nhalo+1;j++) { 
       for (int i=0; i<ewn-2*nhalo+1; i++) {
         for (int k=0; k<upn; k++) { 
           int index = k+upn*i + j*(ewn-2*nhalo+1)*upn; 
           cismToAlbanyNodeNumberMap[index] = k*nNodes2D + global_node_id_owned_map_Ptr[i+j*(ewn-2*nhalo+1)]; 
           //if (mpiComm->MyPID() == 0) 
           //  std::cout << "index: " << index << ", cismToAlbanyNodeNumberMap: " << cismToAlbanyNodeNumberMap[index] << std::endl; 
          }
        }
      }

     //The way it worked out, uVel_ptr and vVel_ptr have more nodes than the nodes in the mesh passed to Albany/CISM for the solve.  In particular, 
     //there is 1 row of halo elements in uVel_ptr and vVel_ptr.  To account for this, we copy uVel_ptr and vVel_ptr into std::vectors, which do not have the halo elements. 
     std::vector<double> uvel_vec(upn*nNodesProc2D); 
     std::vector<double> vvel_vec(upn*nNodesProc2D); 
     int counter1 = 0; 
     int counter2 = 0; 
     int local_nodeID; 
     for (int j=0; j<nsn-1; j++) {
       for (int i=0; i<ewn-1; i++) { 
         for (int k=0; k<upn; k++) {
           if (j >= nhalo-1 & j < nsn-nhalo) {
             if (i >= nhalo-1 & i < ewn-nhalo) {
#ifdef CISM_USE_EPETRA 
               local_nodeID = node_map->LID(cismToAlbanyNodeNumberMap[counter1]); 
#else
               local_nodeID = node_map->getLocalElement(cismToAlbanyNodeNumberMap[counter1]);
#endif
               uvel_vec[counter1] = uVel_ptr[counter2]; 
               vvel_vec[counter1] = vVel_ptr[counter2]; 
               counter1++;
            }
            }
            counter2++; 
         }
        }
     }
     //Loop over all the elements to find which nodes are active.  For the active nodes, copy uvel and vvel from CISM into Albany solution array to 
     //use as initial condition.
     //NOTE: there is some inefficiency here by looping over all the elements.  TO DO? pass only active nodes from Albany-CISM to improve this? 
     double velScale = seconds_per_year*vel_scaling_param;  
     for (int i=0; i<nElementsActive; i++) {
       for (int j=0; j<8; j++) {
        int node_GID =  global_element_conn_active_Ptr[i + nElementsActive*j]; //node_GID is 1-based
#ifdef CISM_USE_EPETRA      
        int node_LID =  node_map->LID(node_GID); //node_LID is 0-based
#else
        int node_LID =  node_map->getLocalElement(node_GID); //node_LID is 0-based
#endif
        stk::mesh::Entity node = meshStruct->bulkData->get_entity(stk::topology::NODE_RANK, node_GID);
        double* sol = stk::mesh::field_data(*solutionField, node);
        //IK, 3/18/14: added division by velScale to convert uvel and vvel from dimensionless to having units of m/year (the Albany units)  
        sol[0] = uvel_vec[node_LID]/velScale;
        sol[1] = vvel_vec[node_LID]/velScale;
      }
    }
    // ---------------------------------------------------------------------------------------------------
    // Solve 
    // ---------------------------------------------------------------------------------------------------

    if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) 
      std::cout << "In felix_driver_run: starting the solve... " << std::endl;
    //Need to set HasRestart solution such that uvel_Ptr and vvel_Ptr (u and v from Glimmer/CISM) are always set as initial condition?  
    meshStruct->setHasRestartSolution(!first_time_step);


    //Turn off homotopy if we're not in the first time-step. 
    //NOTE - IMPORTANT: Glen's Law Homotopy parameter should be set to 1.0 in the parameter list for this logic to work!!! 
    if (!first_time_step)
    {
       meshStruct->setRestartDataTime(parameterList->sublist("Problem").get("Homotopy Restart Step", 1.));
       double homotopy = parameterList->sublist("Problem").sublist("FELIX Viscosity").get("Glen's Law Homotopy Parameter", 1.0);
       if(meshStruct->restartDataTime()== homotopy) {
         parameterList->sublist("Problem").set("Solution Method", "Steady");
         parameterList->sublist("Piro").set("Solver Type", "NOX");
       }
    }

    albanyApp->createDiscretization();

    //IK, 10/30/14: Check that # of elements from previous time step hasn't changed. 
    //If it has not, use previous solution as initial guess for current time step.
    //Otherwise do not set initial solution.  It's possible this can be improved so some part of the previous solution is used
    //defined on the current mesh (if it receded, which likely it will in dynamic ice sheet simulations...). 
    if (nElementsActivePrevious != nElementsActive) previousSolution = Teuchos::null; 
    albanyApp->finalSetUp(parameterList, previousSolution);

    //if (!first_time_step) 
    //  std::cout << "previousSolution: " << *previousSolution << std::endl;
#ifdef CISM_USE_EPETRA 
    solver = slvrfctry->createThyraSolverAndGetAlbanyApp(albanyApp, mpiComm, mpiComm, Teuchos::null, false);
#else
   solver = slvrfctry->createAndGetAlbanyAppT(albanyApp, mpiCommT, mpiCommT, Teuchos::null, false);
#endif

    Teuchos::ParameterList solveParams;
    solveParams.set("Compute Sensitivities", true);
    Teuchos::Array<Teuchos::RCP<const Thyra::VectorBase<double> > > thyraResponses;
    Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Thyra::MultiVectorBase<double> > > > thyraSensitivities;
    Piro::PerformSolveBase(*solver, solveParams, thyraResponses, thyraSensitivities);

#ifdef CISM_USE_EPETRA
    const Epetra_Map& ownedMap(*albanyApp->getDiscretization()->getMap()); //owned map
    const Epetra_Map& overlapMap(*albanyApp->getDiscretization()->getOverlapMap()); //overlap map
    Epetra_Import import(overlapMap, ownedMap); //importer from ownedMap to overlapMap
    Epetra_Vector solutionOverlap(overlapMap); //overlapped solution
    solutionOverlap.Import(*albanyApp->getDiscretization()->getSolutionField(), import, Insert);
#else 
    Teuchos::RCP<const Tpetra_Map> ownedMap = albanyApp->getDiscretization()->getMapT(); //owned map
    Teuchos::RCP<const Tpetra_Map> overlapMap = albanyApp->getDiscretization()->getOverlapMapT(); //overlap map
    Teuchos::RCP<Tpetra_Import> import = Teuchos::rcp(new Tpetra_Import(ownedMap, overlapMap));
    Teuchos::RCP<Tpetra_Vector> solutionOverlap = Teuchos::rcp(new Tpetra_Vector(overlapMap));
    solutionOverlap->doImport(*albanyApp->getDiscretization()->getSolutionFieldT(), *import, Tpetra::INSERT);
    Teuchos::ArrayRCP<const ST> solutionOverlap_constView = solutionOverlap->get1dView();
#endif

#ifdef WRITE_TO_MATRIX_MARKET
#ifdef CISM_USE_EPETRA
    //For debug: write solution and maps to matrix market file
    EpetraExt::BlockMapToMatrixMarketFile("node_map.mm", *node_map);
    EpetraExt::BlockMapToMatrixMarketFile("map.mm", ownedMap);
    EpetraExt::BlockMapToMatrixMarketFile("overlap_map.mm", overlapMap);
    EpetraExt::MultiVectorToMatrixMarketFile("solution.mm", *albanyApp->getDiscretization()->getSolutionField());
#else 
    Tpetra_MatrixMarket_Writer::writeMapFile("node_map.mm", *node_map);
    Tpetra_MatrixMarket_Writer::writeMapFile("map.mm", *ownedMap);
    Tpetra_MatrixMarket_Writer::writeMapFile("overlap_map.mm", *overlapMap);
    Tpetra_MatrixMarket_Writer::writeDenseFile("solution.mm", app->getDiscretization()->getSolutionFieldT());
#endif
#endif
   
   //set previousSolution (used as initial guess for next time step) to final Albany solution. 
   previousSolution = Teuchos::rcp(new Tpetra_Vector(*albanyApp->getDiscretization()->getSolutionFieldT())); 
   nElementsActivePrevious = nElementsActive;   
 
   //std::cout << "Final solution: " << *albanyApp->getDiscretization()->getSolutionField() << std::endl;  
    // ---------------------------------------------------------------------------------------------------
    // Compute sensitivies / responses and perform regression tests
    // IK, 12/9/13: how come this is turned off in mpas branch? 
    // ---------------------------------------------------------------------------------------------------
 
    if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) 
      std::cout << "Computing responses and sensitivities..." << std::endl;
    int status=0; // 0 = pass, failures are incremented
#ifdef CISM_USE_EPETRA
    Teuchos::Array<Teuchos::RCP<const Epetra_Vector> > responses;
    Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Epetra_MultiVector> > > sensitivities;
    epetraFromThyra(mpiComm, thyraResponses, thyraSensitivities, responses, sensitivities);
#else
    Teuchos::Array<Teuchos::RCP<const Tpetra_Vector> > responses;
    Teuchos::Array<Teuchos::Array<Teuchos::RCP<const Tpetra_MultiVector> > > sensitivities;
    tpetraFromThyra(thyraResponses, thyraSensitivities, responses, sensitivities);
#endif

    const int num_p = solver->Np(); // Number of *vectors* of parameters
    const int num_g = solver->Ng(); // Number of *vectors* of responses

   if (debug_output_verbosity != 0) {
    *out << "Finished eval of first model: Params, Responses "
      << std::setprecision(12) << std::endl;
   }
   const Thyra::ModelEvaluatorBase::InArgs<double> nominal = solver->getNominalValues();

   if (debug_output_verbosity != 0) {
    for (int i=0; i<num_p; i++) {
#ifdef CISM_USE_EPETRA
      const Teuchos::RCP<const Epetra_Vector> p_init = epetraVectorFromThyra(mpiComm, nominal.get_p(i));
      p_init->Print(*out << "\nParameter vector " << i << ":\n");
#else
      Albany::printTpetraVector(*out << "\nParameter vector " << i << ":\n",
           ConverterT::getConstTpetraVector(nominal.get_p(i)));
#endif
    }
   }

    for (int i=0; i<num_g-1; i++) {
#ifdef CISM_USE_EPETRA
      const Teuchos::RCP<const Epetra_Vector> g = responses[i];
#else
      const Teuchos::RCP<const Tpetra_Vector> g = responses[i];
#endif
      bool is_scalar = true;

      if (albanyApp != Teuchos::null)
        is_scalar = albanyApp->getResponse(i)->isScalarResponse();

      if (is_scalar) {
        if (debug_output_verbosity != 0) {
#ifdef CISM_USE_EPETRA
         g->Print(*out << "\nResponse vector " << i << ":\n");
#else
         Albany::printTpetraVector(*out << "\nResponse vector " << i << ":\n", g);
#endif
        }

        if (num_p == 0 && cur_time_yr == final_time) {
          // Just calculate regression data -- only if in final time step
#ifdef CISM_USE_EPETRA
          status += slvrfctry->checkSolveTestResults(i, 0, g.get(), NULL);
#else
          status += slvrfctry->checkSolveTestResultsT(i, 0, g.get(), NULL);
#endif
        } else {
          for (int j=0; j<num_p; j++) {
#ifdef CISM_USE_EPETRA
            const Teuchos::RCP<const Epetra_MultiVector> dgdp = sensitivities[i][j];
#else
            const Teuchos::RCP<const Tpetra_MultiVector> dgdp = sensitivities[i][j];
#endif
            if (debug_output_verbosity != 0) {
              if (Teuchos::nonnull(dgdp)) {
#ifdef CISM_USE_EPETRA
                dgdp->Print(*out << "\nSensitivities (" << i << "," << j << "):!\n");
#else
                Albany::printTpetraVector(*out << "\nSensitivities (" << i << "," << j << "):!\n", dgdp);
#endif
              }
            }
            if (cur_time_yr == final_time) {
#ifdef CISM_USE_EPETRA
              status += slvrfctry->checkSolveTestResults(i, j, g.get(), dgdp.get());
#else
              status += slvrfctry->checkSolveTestResultsT(i, j, g.get(), dgdp.get());
#endif
            }
          }
        }
      }
    }
    if (debug_output_verbosity != 0 && cur_time_yr == final_time) //only print regression test result if you're in the final time step 
      *out << "\nNumber of Failed Comparisons: " << status << std::endl;
    //IK, 10/30/14: added the following line so that when you run ctest from CISM the test fails if there are some failed comparisons.
    if (status > 0)     
      TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "All regression comparisons did not pass!" << std::endl);

    // ---------------------------------------------------------------------------------------------------
    // Copy solution back to glimmer uvel and vvel arrays to be passed back
    // ---------------------------------------------------------------------------------------------------

    //std::cout << "overlapMap # global elements: " << overlapMap.NumGlobalElements() << std::endl; 
    //std::cout << "overlapMap # my elements: " << overlapMap.NumMyElements() << std::endl; 
    //std::cout << "overlapMap: " << overlapMap << std::endl; 
    //std::cout << "map # global elements: " << ownedMap.NumGlobalElements() << std::endl; 
    //std::cout << "map # my elements: " << ownedMap.NumMyElements() << std::endl; 
    //std::cout << "node_map # global elements: " << node_map->NumGlobalElements() << std::endl; 
    //std::cout << "node_map # my elements: " << node_map->NumMyElements() << std::endl; 
    //std::cout << "node_map: " << *node_map << std::endl; 

    if (debug_output_verbosity != 0 & mpiCommT->getRank() == 0) 
      std::cout << "In felix_driver_run: copying Albany solution to uvel and vvel to send back to CISM... " << std::endl;
#ifdef CISM_USE_EPETRA 
    //Epetra_Vectors to hold uvel and vvel to be passed to Glimmer/CISM
    Epetra_Vector uvel(*node_map, true); 
    Epetra_Vector vvel(*node_map, true);
#else
    //Tpetra_Vectors to hold uvel and vvel to be passed to Glimmer/CISM
    Teuchos::RCP<Tpetra_Vector> uvel = Teuchos::rcp(new Tpetra_Vector(node_map, true));
    Teuchos::RCP<Tpetra_Vector> vvel = Teuchos::rcp(new Tpetra_Vector(node_map, true));
#endif

#ifdef CISM_USE_EPETRA 
    if (interleavedOrdering == true) { 
      for (int i=0; i<overlapMap.NumMyElements(); i++) { 
        int global_dof = overlapMap.GID(i);
        double sol_value = solutionOverlap[i];  
        int modulo = (global_dof % 2); //check if dof is for u or for v 
        int vel_global_dof, vel_local_dof; 
        if (modulo == 0) { //u dof 
          vel_global_dof = global_dof/2+1; //add 1 because node_map is 1-based 
          vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map
          //std::cout << "uvel: global_dof = " << global_dof << ", uvel_global_dof = " << vel_global_dof << ", uvel_local_dof = " << vel_local_dof << std::endl; 
          uvel.ReplaceMyValues(1, &sol_value, &vel_local_dof); 
        }
        else { // v dof 
          vel_global_dof = (global_dof-1)/2+1; //add 1 because node_map is 1-based 
          vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map
          vvel.ReplaceMyValues(1, &sol_value, & vel_local_dof); 
        }
      }
    }
    else { //note: the case with non-interleaved ordering has not been tested...
      int numDofs = overlapMap.NumGlobalElements(); 
      for (int i=0; i<overlapMap.NumMyElements(); i++) { 
        int global_dof = overlapMap.GID(i);
        double sol_value = solutionOverlap[i];  
        int vel_global_dof, vel_local_dof; 
        if (global_dof < numDofs/2) { //u dof
          vel_global_dof = global_dof+1; //add 1 because node_map is 1-based 
          vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map
          uvel.ReplaceMyValues(1, &sol_value, &vel_local_dof); 
        }
        else { //v dofs 
          vel_global_dof = global_dof-numDofs/2+1; //add 1 because node_map is 1-based
          vel_local_dof = node_map->LID(vel_global_dof); //look up local id corresponding to global id in node_map
          vvel.ReplaceMyValues(1, &sol_value, & vel_local_dof);
        } 
      }
    }
#else
    if (interleavedOrdering == true) {
      for (int i=0; i<overlapMap->getNodeNumElements(); i++) {
        int global_dof = overlapMap->getGlobalElement(i);
        double sol_value = solutionOverlap_constView[i];
        int modulo = (global_dof % 2); //check if dof is for u or for v 
        int vel_global_dof, vel_local_dof;
        if (modulo == 0) { //u dof 
          vel_global_dof = global_dof/2+1; //add 1 because node_map is 1-based 
          vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map
          //std::cout << "uvel: global_dof = " << global_dof << ", uvel_global_dof = " << vel_global_dof << ", uvel_local_dof = " << vel_local_dof << std::endl; 
          uvel->replaceLocalValue(vel_local_dof, sol_value);
        }
        else { // v dof 
          vel_global_dof = (global_dof-1)/2+1; //add 1 because node_map is 1-based 
          vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map
          vvel->replaceLocalValue(vel_local_dof, sol_value);
        }
      }
    }
    else { //note: the case with non-interleaved ordering has not been tested...
      int numDofs = overlapMap->getGlobalNumElements();
      for (int i=0; i<overlapMap->getNodeNumElements(); i++) {
        int global_dof = overlapMap->getGlobalElement(i);
        double sol_value = solutionOverlap_constView[i];
        int vel_global_dof, vel_local_dof;
        if (global_dof < numDofs/2) { //u dof
          vel_global_dof = global_dof+1; //add 1 because node_map is 1-based 
          vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map
          uvel->replaceLocalValue(vel_local_dof, sol_value);
        }
        else { //v dofs 
          vel_global_dof = global_dof-numDofs/2+1; //add 1 because node_map is 1-based
          vel_local_dof = node_map->getLocalElement(vel_global_dof); //look up local id corresponding to global id in node_map
          vvel->replaceLocalValue(vel_local_dof, sol_value);
        }
      }
    }
#endif
 

#ifdef WRITE_TO_MATRIX_MARKET
    //For debug: write solution to matrix market file 
#ifdef CISM_USE_EPETRA
     EpetraExt::MultiVectorToMatrixMarketFile("uvel.mm", uvel); 
     EpetraExt::MultiVectorToMatrixMarketFile("vvel.mm", vvel);
#else
     Tpetra_MatrixMarket_Writer::writeDenseFile("uvel.mm", uvel);
     Tpetra_MatrixMarket_Writer::writeDenseFile("vvel.mm", vvel);
#endif
#endif
 
     //Copy uvel and vvel into uVel_ptr and vVel_ptr respectively (the arrays passed back to CISM) according to the numbering consistent w/ CISM. 
     counter1 = 0; 
     counter2 = 0;
#ifdef CISM_USE_EPETRA
#else
     Teuchos::ArrayRCP<const ST> uvel_constView = uvel->get1dView();
     Teuchos::ArrayRCP<const ST> vvel_constView = vvel->get1dView();
#endif 
     local_nodeID = 0;  
     for (int j=0; j<nsn-1; j++) {
       for (int i=0; i<ewn-1; i++) { 
         for (int k=0; k<upn; k++) {
           if (j >= nhalo-1 & j < nsn-nhalo) {
             if (i >= nhalo-1 & i < ewn-nhalo) {
#ifdef CISM_USE_EPETRA 
               local_nodeID = node_map->LID(cismToAlbanyNodeNumberMap[counter1]); 
               //if (mpiComm->MyPID() == 0) 
               //std::cout << "counter1:" << counter1 << ", cismToAlbanyNodeNumberMap[counter1]: " << cismToAlbanyNodeNumberMap[counter1] << ", local_nodeID: " 
               //<< local_nodeID << ", uvel: " << uvel[local_nodeID] << std::endl; //uvel[local_nodeID] << std::endl;  
               uVel_ptr[counter2] = uvel[local_nodeID];
               vVel_ptr[counter2] = vvel[local_nodeID];  
#else
               local_nodeID = node_map->getLocalElement(cismToAlbanyNodeNumberMap[counter1]);
               uVel_ptr[counter2] = uvel_constView[local_nodeID];
               vVel_ptr[counter2] = vvel_constView[local_nodeID];
#endif
               counter1++;
            }
            }
            else {
             uVel_ptr[counter2] = 0.0; 
             vVel_ptr[counter2] = 0.0; 
            }
            counter2++; 
         }
        }
      }
    


    first_time_step = false;
}
Exemple #9
0
int main(int argc, char *argv[])
{
  // MEMORY_CHECK(true, "Before initializing MPI");

  Teuchos::GlobalMPISession session(&argc, &argv, NULL);
  RCP<const Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
  int rank = comm->getRank();
  int nprocs = comm->getSize();

  MEMORY_CHECK(rank==0, "After initializing MPI");

  if (rank==0)
    cout << "Number of processes: " << nprocs << endl;

  // Default values
  double numGlobalCoords = 1000;
  int numTestCuts = 1;
  int nWeights = 0;
  string timingType("no_timers");
  string debugLevel("basic_status");
  string memoryOn("memoryOn");
  string memoryOff("memoryOff");
  string memoryProcs("0");
  bool doMemory=false;
  int numGlobalParts = nprocs;

  CommandLineProcessor commandLine(false, true);
  commandLine.setOption("size", &numGlobalCoords, 
    "Approximate number of global coordinates.");
  commandLine.setOption("testCuts", &numTestCuts, 
    "Number of test cuts to make when looking for bisector.");
  commandLine.setOption("numParts", &numGlobalParts, 
    "Number of parts (default is one per proc).");
  commandLine.setOption("nWeights", &nWeights, 
    "Number of weights per coordinate, zero implies uniform weights.");

  string balanceCount("balance_object_count");
  string balanceWeight("balance_object_weight");
  string mcnorm1("multicriteria_minimize_total_weight");
  string mcnorm2("multicriteria_balance_total_maximum");
  string mcnorm3("multicriteria_minimize_maximum_weight");

  string objective(balanceWeight);   // default

  string doc(balanceCount); doc.append(": ignore weights\n");

  doc.append(balanceWeight); doc.append(": balance on first weight\n");

  doc.append(mcnorm1);
  doc.append(": given multiple weights, balance their total.\n");

  doc.append(mcnorm3);
  doc.append(": given multiple weights, balance the maximum for each coordinate.\n");

  doc.append(mcnorm2);
  doc.append(": given multiple weights, balance the L2 norm of the weights.\n");

  commandLine.setOption("objective", &objective,  doc.c_str());

  commandLine.setOption("timers", &timingType,
    "no_timers, micro_timers, macro_timers, both_timers, test_timers");

  commandLine.setOption("debug", &debugLevel,
   "no_status, basic_status, detailed_status, verbose_detailed_status");

  commandLine.setOption(memoryOn.c_str(), memoryOff.c_str(), &doMemory,
    "do memory profiling");

  commandLine.setOption("memoryProcs", &memoryProcs,
   "list of processes that output memory usage");

  CommandLineProcessor::EParseCommandLineReturn rc = 
    commandLine.parse(argc, argv);

  if (rc != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL){
    if (rc == Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED){
      if (rank==0)
        cout << "PASS" << endl;
      return 1;
    }
    else{
      if (rank==0)
        cout << "FAIL" << endl;
      return 0;
    }
  }

  //MEMORY_CHECK(doMemory && rank==0, "After processing parameters");

  zgno_t globalSize = static_cast<zgno_t>(numGlobalCoords);

  RCP<tMVector_t> coordinates = getMeshCoordinates(comm, globalSize);
  size_t numLocalCoords = coordinates->getLocalLength();

#if 0
  comm->barrier();
  for (int p=0; p < nprocs; p++){
    if (p==rank){
      cout << "Rank " << rank << ", " << numLocalCoords << "coords" << endl;
      const zscalar_t *x = coordinates->getData(0).getRawPtr();
      const zscalar_t *y = coordinates->getData(1).getRawPtr();
      const zscalar_t *z = coordinates->getData(2).getRawPtr();
      for (zlno_t i=0; i < numLocalCoords; i++)
        cout << " " << x[i] << " " << y[i] << " " << z[i] << endl;
    }
    cout.flush();
    comm->barrier();
  }
#endif

  Array<ArrayRCP<zscalar_t> > weights(nWeights);

  if (nWeights > 0){
    int wt = 0;
    zscalar_t scale = 1.0;
    for (int i=0; i < nWeights; i++){
      weights[i] = 
        makeWeights(comm, numLocalCoords, weightTypes(wt++), scale, rank);
      if (wt == numWeightTypes){
        wt = 0;
        scale++;
      }
    }
  }

  MEMORY_CHECK(doMemory && rank==0, "After creating input");

  // Create an input adapter.
  const RCP<const tMap_t> &coordmap = coordinates->getMap();
  ArrayView<const zgno_t> ids = coordmap->getNodeElementList();
  const zgno_t *globalIds = ids.getRawPtr();
  
  size_t localCount = coordinates->getLocalLength();
  typedef Zoltan2::BasicVectorAdapter<tMVector_t> inputAdapter_t;
  RCP<inputAdapter_t> ia;
  
  if (nWeights == 0){
    ia = rcp(new inputAdapter_t (localCount, globalIds, 
      coordinates->getData(0).getRawPtr(), coordinates->getData(1).getRawPtr(),
      coordinates->getData(2).getRawPtr(), 1,1,1));
  }
  else{
    vector<const zscalar_t *> values(3);
    for (int i=0; i < 3; i++)
      values[i] = coordinates->getData(i).getRawPtr();
    vector<int> valueStrides(0);  // implies stride is one
    vector<const zscalar_t *> weightPtrs(nWeights);
    for (int i=0; i < nWeights; i++)
      weightPtrs[i] = weights[i].getRawPtr();
    vector<int> weightStrides(0); // implies stride is one

    ia = rcp(new inputAdapter_t (localCount, globalIds, 
      values, valueStrides, weightPtrs, weightStrides));
  }

  MEMORY_CHECK(doMemory && rank==0, "After creating input adapter");

  // Parameters

  Teuchos::ParameterList params;

  if (timingType != "no_timers"){
    params.set("timer_output_stream" , "std::cout");
    params.set("timer_type" , timingType);
  }

  if (doMemory){
    params.set("memory_output_stream" , "std::cout");
    params.set("memory_procs" , memoryProcs);
  }

  params.set("debug_output_stream" , "std::cerr");
  params.set("debug_procs" , "0");

  if (debugLevel != "basic_status"){
    params.set("debug_level" , debugLevel);
  }

  params.set("algorithm", "rcb");
  params.set("partitioning_objective", objective);
  double tolerance = 1.1;
  params.set("imbalance_tolerance", tolerance );

  if (numGlobalParts != nprocs)
    params.set("num_global_parts" , numGlobalParts);

  if (rank==0){
    cout << "Number of parts: " << numGlobalParts << endl;
  }

  // Create a problem, solve it, and display the quality.

  Zoltan2::PartitioningProblem<inputAdapter_t> problem(&(*ia), &params);

  problem.solve();

  comm->barrier();

  problem.printTimers();

  comm->barrier();

  if (rank == 0){
    cout << "PASS" << endl;
  }

  return 0;
}
Exemple #10
0
/* Find the DBBD form */
int shylu_symbolic_factor
(
    Epetra_CrsMatrix *A,    // i/p: A matrix
    shylu_symbolic *ssym,   // symbolic structure
    shylu_data *data,       // numeric structure, TODO: Required ?
    shylu_config *config    // i/p: library configuration
)
{
#ifdef TIMING_OUTPUT
    Teuchos::Time symtime("symbolic time");
    symtime.start();
#endif
    int myPID = A->Comm().MyPID();
    int n = A->NumGlobalRows();

    int Dnr;
    int Snr;
    int *DRowElems;
    int *SRowElems;
    int sym = config->sym;

    checkMaps(A);

    // Get column map
    Epetra_Map AColMap = A->ColMap();
    int ncols = AColMap.NumMyElements();
    int *cols = AColMap.MyGlobalElements();

    // Get row map
    Epetra_Map ARowMap = A->RowMap();
    int nrows = ARowMap.NumMyElements();
    int *rows = ARowMap.MyGlobalElements();

    // Find all columns in this proc
    int *gvals = new int[n];       // vector of size n, not ncols !
    // gvals[local cols] = 1, gvals[shared cols] > 1.
    int SNumGlobalCols;
    findLocalColumns(A, gvals, SNumGlobalCols);

    // See if you can shrink the separator by assigning more rows/columns to
    // the block diagonals
    // TODO: This is because of a bug in coloring remove the if once that is
    // fixed
    //if (config->schurApproxMethod == 2)
    if (config->sep_type == 2)
        findNarrowSeparator(A, gvals);

    // 3. Assemble diagonal block and the border in convenient form [
    /* In each processor, we have (in a permuted form)
     *  | D_i    C_i   |
     *  | R_i    S_i   |
     * D_i - diagonal block, C_i - Column Separator, R_i - Row separator
     * S_i - A22 block corresponding to Schur complement part of A
     * Assemble all four blocks in local matrices. */

     ostringstream ssmsg1;
     ssmsg1 << "PID =" << myPID << " ";
     string msg = ssmsg1.str();
     ssmsg1.clear(); ssmsg1.str("");

    // Find #cols in each block
    int Dnc = 0;        // #cols in diagonal block
    int Snc = 0;        // #cols in the col. separator
    /* Looping on cols will work only for wide separator
     * as for narrow sep there will be some sep cols with gvals[col] ==1
     * */
    /*for (int i = 0; i < ncols ; i++)
    {
        if (gvals[cols[i]] == 1)
            Dnc++;
        else
            Snc++;
    }
    // Find #rows in each block 
    Dnr = Dnc;          // #rows in square diagonal block
    Snr = nrows - Dnr;  // #rows in the row separator*/

    // Find #rows in each block
    Dnr = 0;
    Snr = 0;
    for (int i = 0; i < nrows ; i++)
    {
        if (gvals[rows[i]] == 1)
            Dnr++;
        else
            Snr++;
    }
    Dnc = Dnr;
    // TODO: Snc is no longer useful, should remove it
    for (int i = 0; i < ncols ; i++)
    {
        if (gvals[cols[i]] != 1)
            Snc++;
    }

    assert(Snc >= 0);

    // TODO : The above assignment may not be correct in the unsymetric case

    ////config->dm.print(2, msg + " Mycols=");
    cout << msg << " Mycols="<< ncols << "Myrows ="<< nrows << endl;
    cout << msg << " #rows and #cols in diagonal blk ="<< Dnr << endl;
    cout << msg << " #columns in S ="<< Snc << endl;
    cout << msg << " #rows in S ="<< Snr << endl;

    ostringstream pidstr;
    pidstr <<  myPID ;
    // Create a row map for the D and S blocks [
    DRowElems = new int[Dnr];
    SRowElems = new int[Snr];
    int gid;
    // Assemble row ids in two arrays (for D and R blocks)
    if (sym)
    {
        findBlockElems(A, nrows, rows, gvals, Dnr, DRowElems, Snr, SRowElems,
                    "D"+pidstr.str()+"Rows", "S"+pidstr.str()+"Rows", false) ;
    }
    else
    {
        // SRowElems are not known until factorization, TODO
        assert(0 == 1);
    }

    data->Dnr = Dnr;
    data->Snr = Snr;
    data->Dnc = Dnc;
    data->DRowElems = DRowElems;
    data->SRowElems = SRowElems;

    // Create a column map for the D and S blocks [
    int *DColElems = new int[Dnc]; // Elems in column map of D 
    int *SColElems = new int[Snc]; // Elems in column map of C TODO: Unused
    // Assemble column ids in two arrays (for D and C blocks)
    findBlockElems(A, ncols, cols, gvals, Dnc, DColElems, Snc, SColElems,
                    "D"+pidstr.str()+"Cols", "S"+pidstr.str()+"Cols", true) ;

    data->DColElems = DColElems;
    data->gvals = gvals;

    for (int i = 0; i < Snr; i++)
    {
        // Epetra guarentees columns corresponding to local rows will be first
        // in the column map.
        assert(SRowElems[i] == SColElems[i]);
    }
    // ]

    /*--Create the Epetra Matrices with the maps (does not insert values) --- */
    create_matrices(A, ssym, data, config);

    /*--Extract the Epetra Matrices and call fillComplete --- */
    extract_matrices(A, ssym, data, config, true);

    delete[] SColElems;

    Amesos Factory;
    const char* SolverType = config->diagonalBlockSolver.c_str();
    bool IsAvailable = Factory.Query(SolverType);
    assert(IsAvailable == true);

    Teuchos::RCP<Epetra_LinearProblem> LP = Teuchos::RCP<Epetra_LinearProblem> 
                                        (new Epetra_LinearProblem());
    LP->SetOperator((ssym->D).getRawPtr());
    //LP->SetOperator((ssym->DT).getRawPtr()); // for transpose

    // Create temp vectors
    ssym->Dlhs = Teuchos::RCP<Epetra_MultiVector>
                    (new Epetra_MultiVector(ssym->D->RowMap(), 16));
    ssym->Drhs = Teuchos::RCP<Epetra_MultiVector>
                    (new Epetra_MultiVector(ssym->D->RowMap(), 16));
    ssym->Gvec = Teuchos::RCP<Epetra_MultiVector>
                    (new Epetra_MultiVector(ssym->G->RowMap(), 16));

    LP->SetRHS(ssym->Drhs.getRawPtr());
    LP->SetLHS(ssym->Dlhs.getRawPtr());

    ssym->ReIdx_LP = Teuchos::RCP<
                    EpetraExt::ViewTransform<Epetra_LinearProblem> >
                    (new EpetraExt::LinearProblem_Reindex2(0));
    ssym->LP = Teuchos::RCP<Epetra_LinearProblem>(&((*(ssym->ReIdx_LP))(*LP)),
                                        false);

    Teuchos::RCP<Amesos_BaseSolver> Solver = Teuchos::RCP<Amesos_BaseSolver>
                                    (Factory.Create(SolverType, *(ssym->LP)));
    //config->dm.print(5, "Created the diagonal solver");

#ifdef TIMING_OUTPUT
    Teuchos::Time ftime("setup time");
    ftime.start();
#endif
    //Solver->SetUseTranspose(true); // for transpose
    Teuchos::ParameterList aList;
    aList.set("TrustMe", true);
    Solver->SetParameters(aList);
    Solver->SymbolicFactorization();
    //config->dm.print(3, "Symbolic Factorization done");

#ifdef TIMING_OUTPUT
    ftime.stop();
    cout << "Symbolic Factorization Time" << ftime.totalElapsedTime() << endl;
    ftime.reset();
#endif

    ssym->OrigLP = LP;
    //ssym->LP = LP;
    ssym->Solver = Solver;

    if (config->schurApproxMethod == 1)
    {
        Teuchos::ParameterList pList;
        Teuchos::RCP<Isorropia::Epetra::Prober> prober = 
                         Teuchos::RCP<Isorropia::Epetra::Prober> (new
                          Isorropia::Epetra::Prober((ssym->Sg).getRawPtr(),
                                                     pList, false));
        //config->dm.print(3, "Doing Coloring");
#ifdef TIMING_OUTPUT
        ftime.start();
#endif
        prober->color();
#ifdef TIMING_OUTPUT
        ftime.stop();
        cout << "Time to color" << ftime.totalElapsedTime() << endl;
        ftime.reset();
        ftime.start();
#endif
        ssym->prober = prober;
    }
#ifdef TIMING_OUTPUT
    symtime.stop();
    cout << "Symbolic Time" << symtime.totalElapsedTime() << endl;
    symtime.reset();
#endif
}
  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetDefaultFactory(const std::string& varName) const {
    if (defaultFactoryTable_.count(varName)) {
      // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
      return defaultFactoryTable_.find(varName)->second;

    } else {
      // No factory was created for this name, but we may know which one to create
      if (varName == "A")                               return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
      if (varName == "RAP Pattern")                     return GetFactory("A");
      if (varName == "AP Pattern")                      return GetFactory("A");
      if (varName == "Ptent")                           return SetAndReturnDefaultFactory(varName, rcp(new TentativePFactory()));
      if (varName == "P") {
        // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
        RCP<Factory> factory = rcp(new SaPFactory());
        factory->SetFactory("P", GetFactory("Ptent"));
        return SetAndReturnDefaultFactory(varName, factory);
      }
      if (varName == "Nullspace") {
        // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
        RCP<Factory> factory = rcp(new NullspaceFactory());
        factory->SetFactory("Nullspace", GetFactory("Ptent"));
        return SetAndReturnDefaultFactory(varName, factory);
      }

      if (varName == "R")                               return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
#if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
      if (varName == "Partition")                       return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
#endif //ifdef HAVE_MPI

      if (varName == "Importer") {
#ifdef HAVE_MPI
                                                        return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
#else
                                                        return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
#endif
      }

      if (varName == "Graph")                           return SetAndReturnDefaultFactory(varName, rcp(new CoalesceDropFactory()));
      if (varName == "UnAmalgamationInfo")              return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory())); //GetFactory("Graph"));
      if (varName == "Aggregates")                      return SetAndReturnDefaultFactory(varName, rcp(new UncoupledAggregationFactory()));
      if (varName == "CoarseMap")                       return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
      if (varName == "DofsPerNode")                     return GetFactory("Graph");
      if (varName == "Filtering")                       return GetFactory("Graph");
      if (varName == "LineDetection_VertLineIds")       return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
      if (varName == "LineDetection_Layers")            return GetFactory("LineDetection_VertLineIds");
      if (varName == "CoarseNumZLayers")                return GetFactory("LineDetection_VertLineIds");

      // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
      if (varName == "PreSmoother")                     return GetFactory("Smoother");
      if (varName == "PostSmoother")                    return GetFactory("Smoother");

      if (varName == "Ppattern") {
        RCP<PatternFactory> PpFact = rcp(new PatternFactory);
        PpFact->SetFactory("P", GetFactory("Ptent"));
        return SetAndReturnDefaultFactory(varName, PpFact);
      }
      if (varName == "Constraint")                      return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));

      if (varName == "Smoother") {
        Teuchos::ParameterList smootherParamList;
        smootherParamList.set("relaxation: type",           "Symmetric Gauss-Seidel");
        smootherParamList.set("relaxation: sweeps",         Teuchos::OrdinalTraits<LO>::one());
        smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
        return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
      }
      if (varName == "CoarseSolver")                    return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));

      TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
    }
  }
Exemple #12
0
int main(int argc, char *argv[]) {
#include <MueLu_UseShortNames.hpp>

  using Teuchos::RCP; // reference count pointers
  using Teuchos::rcp;
  using Teuchos::TimeMonitor;

  // =========================================================================
  // MPI initialization using Teuchos
  // =========================================================================
  Teuchos::GlobalMPISession mpiSession(&argc, &argv, NULL);
  RCP< const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
  int MyPID   = comm->getRank();
  int NumProc = comm->getSize();

  const Teuchos::RCP<Epetra_Comm> epComm = Teuchos::rcp_const_cast<Epetra_Comm>(Xpetra::toEpetra(comm));

  // =========================================================================
  // Convenient definitions
  // =========================================================================
  //SC zero = Teuchos::ScalarTraits<SC>::zero(), one = Teuchos::ScalarTraits<SC>::one();

  // Instead of checking each time for rank, create a rank 0 stream
  RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
  Teuchos::FancyOStream& fancyout = *fancy;
  fancyout.setOutputToRootOnly(0);



  // =========================================================================
  // Parameters initialization
  // =========================================================================
  Teuchos::CommandLineProcessor clp(false);
  GO nx = 100, ny = 100;
  clp.setOption("nx",                   &nx,              "mesh size in x direction");
  clp.setOption("ny",                   &ny,              "mesh size in y direction");
  std::string xmlFileName = "xml/s3a.xml"; clp.setOption("xml", &xmlFileName,     "read parameters from a file. Otherwise, this example uses by default 'tutorial1a.xml'");
  int mgridSweeps = 1; clp.setOption("mgridSweeps", &mgridSweeps, "number of multigrid sweeps within Multigrid solver.");
  std::string printTimings = "no";   clp.setOption("timings", &printTimings,     "print timings to screen [yes/no]");
  double tol               = 1e-12;  clp.setOption("tol",                   &tol,              "solver convergence tolerance");

  switch (clp.parse(argc,argv)) {
    case Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED:        return EXIT_SUCCESS; break;
    case Teuchos::CommandLineProcessor::PARSE_ERROR:
    case Teuchos::CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION: return EXIT_FAILURE; break;
    case Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL:                               break;
  }

  // =========================================================================
  // Problem construction
  // =========================================================================
  RCP<TimeMonitor> globalTimeMonitor = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: S - Global Time"))), tm;

  comm->barrier();
  tm = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: 1 - Matrix Build")));

  Teuchos::ParameterList GaleriList;
  GaleriList.set("nx", nx);
  GaleriList.set("ny", ny);
  GaleriList.set("mx", epComm->NumProc());
  GaleriList.set("my", 1);
  GaleriList.set("lx", 1.0); // length of x-axis
  GaleriList.set("ly", 1.0); // length of y-axis
  GaleriList.set("diff", 1e-5);
  GaleriList.set("conv", 1.0);

  // create map
  Teuchos::RCP<Epetra_Map> epMap = Teuchos::rcp(Galeri::CreateMap("Cartesian2D", *epComm, GaleriList));

  // create coordinates
  Teuchos::RCP<Epetra_MultiVector> epCoord = Teuchos::rcp(Galeri::CreateCartesianCoordinates("2D", epMap.get(), GaleriList));

  // create matrix
  Teuchos::RCP<Epetra_CrsMatrix> epA = Teuchos::rcp(Galeri::CreateCrsMatrix("Recirc2D", epMap.get(), GaleriList));

  // Epetra -> Xpetra
  Teuchos::RCP<CrsMatrix> exA = Teuchos::rcp(new Xpetra::EpetraCrsMatrix(epA));
  Teuchos::RCP<CrsMatrixWrap> exAWrap = Teuchos::rcp(new CrsMatrixWrap(exA));

  RCP<Matrix> A = Teuchos::rcp_dynamic_cast<Matrix>(exAWrap);
  int numPDEs = 1;
  A->SetFixedBlockSize(numPDEs);

  // set rhs and solution vector
  RCP<Epetra_Vector> B = Teuchos::rcp(new Epetra_Vector(*epMap));
  RCP<Epetra_Vector> X = Teuchos::rcp(new Epetra_Vector(*epMap));
  B->PutScalar(1.0);
  X->PutScalar(0.0);

  // Epetra -> Xpetra
  RCP<Vector> xB = Teuchos::rcp(new Xpetra::EpetraVector(B));
  RCP<Vector> xX = Teuchos::rcp(new Xpetra::EpetraVector(X));

  xX->setSeed(100);
  xX->randomize();

  // build null space vector
  RCP<const Map> map = A->getRowMap();
  RCP<MultiVector> nullspace = MultiVectorFactory::Build(map, numPDEs);

  for (int i=0; i<numPDEs; ++i) {
    Teuchos::ArrayRCP<Scalar> nsValues = nullspace->getDataNonConst(i);
    int numBlocks = nsValues.size() / numPDEs;
    for (int j=0; j< numBlocks; ++j) {
      nsValues[j*numPDEs + i] = 1.0;
    }
  }

  comm->barrier();
  tm = Teuchos::null;

  fancyout << "========================================================\nGaleri complete.\n========================================================" << std::endl;

  // =========================================================================
  // Preconditioner construction
  // =========================================================================
  comm->barrier();
  tm = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: 1.5 - MueLu read XML")));
  ParameterListInterpreter mueLuFactory(xmlFileName, *comm);
  comm->barrier();
  tm = Teuchos::null;

  tm = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: 2 - MueLu Setup")));

  RCP<Hierarchy> H = mueLuFactory.CreateHierarchy();

  H->GetLevel(0)->Set("A",           A);
  H->GetLevel(0)->Set("Nullspace",   nullspace);

  mueLuFactory.SetupHierarchy(*H);

  comm->barrier();
  tm = Teuchos::null;

  // =========================================================================
  // System solution (Ax = b)
  // =========================================================================

    //
    // generate exact solution using a direct solver
    //
    RCP<Epetra_Vector> exactLsgVec = rcp(new Epetra_Vector(X->Map()));
    {
      fancyout << "========================================================\nCalculate exact solution." << std::endl;
      tm = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: 3 - direct solve")));
      exactLsgVec->PutScalar(0.0);
      exactLsgVec->Update(1.0,*X,1.0);
      Epetra_LinearProblem epetraProblem(epA.get(), exactLsgVec.get(), B.get());

      Amesos amesosFactory;
      RCP<Amesos_BaseSolver> rcp_directSolver = Teuchos::rcp(amesosFactory.Create("Amesos_Klu", epetraProblem));
      rcp_directSolver->SymbolicFactorization();
      rcp_directSolver->NumericFactorization();
      rcp_directSolver->Solve();

      comm->barrier();
      tm = Teuchos::null;
    }

    //
    // Solve Ax = b using AMG as a preconditioner in AztecOO
    //

    RCP<Epetra_Vector> precLsgVec = rcp(new Epetra_Vector(X->Map()));
    {
      fancyout << "========================================================\nUse multigrid hierarchy as preconditioner within CG." << std::endl;
      tm = rcp(new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: 4 - AMG as preconditioner")));

      precLsgVec->PutScalar(0.0);
      precLsgVec->Update(1.0,*X,1.0);
      Epetra_LinearProblem epetraProblem(epA.get(), precLsgVec.get(), B.get());

      AztecOO aztecSolver(epetraProblem);
      aztecSolver.SetAztecOption(AZ_solver, AZ_gmres);

      MueLu::EpetraOperator aztecPrec(H);
      aztecSolver.SetPrecOperator(&aztecPrec);

      int maxIts = 50;

      aztecSolver.Iterate(maxIts, tol);

      comm->barrier();
      tm = Teuchos::null;
    }

    //////////////////

    // use multigrid hierarchy as solver
    RCP<Vector> mgridLsgVec = VectorFactory::Build(map);
    mgridLsgVec->putScalar(0.0);
    {
      fancyout << "========================================================\nUse multigrid hierarchy as solver." << std::endl;
      tm = rcp (new TimeMonitor(*TimeMonitor::getNewTimer("ScalingTest: 5 - Multigrid Solve")));
      mgridLsgVec->update(1.0,*xX,1.0);
      H->IsPreconditioner(false);
      H->Iterate(*xB, mgridSweeps, *mgridLsgVec);
      comm->barrier();
      tm = Teuchos::null;
    }

    //////////////////

    fancyout << "========================================================\nExport results.\n========================================================" << std::endl;
    std::ofstream myfile;
    std::stringstream ss; ss << "example" << MyPID << ".txt";
    myfile.open (ss.str().c_str());

    //////////////////

    // loop over all procs
    for (int iproc=0; iproc < NumProc; iproc++) {
      if (MyPID==iproc) {
        int NumVectors1 = 2;
        int NumMyElements1 = epCoord->Map(). NumMyElements();
        int MaxElementSize1 = epCoord->Map().MaxElementSize();
        int * FirstPointInElementList1 = NULL;
        if (MaxElementSize1!=1) FirstPointInElementList1 = epCoord->Map().FirstPointInElementList();
        double ** A_Pointers = epCoord->Pointers();

        if (MyPID==0) {
          myfile.width(8);
          myfile <<  "#     MyPID"; myfile << "    ";
          myfile.width(12);
          if (MaxElementSize1==1)
            myfile <<  "GID  ";
          else
            myfile <<  "     GID/Point";
          for (int j = 0; j < NumVectors1 ; j++)
          {
            myfile.width(20);
            myfile <<  "Value  ";
          }
          myfile << std::endl;
        }
        for (int i=0; i < NumMyElements1; i++) {
          for (int ii=0; ii< epCoord->Map().ElementSize(i); ii++) {
            int iii;
            myfile.width(10);
            myfile <<  MyPID; myfile << "    ";
            myfile.width(10);
            if (MaxElementSize1==1) {
              if(epCoord->Map().GlobalIndicesInt())
              {
                int * MyGlobalElements1 = epCoord->Map().MyGlobalElements();
                myfile << MyGlobalElements1[i] << "    ";
              }

              iii = i;
            }
            else {
              if(epCoord->Map().GlobalIndicesInt())
              {

                int * MyGlobalElements1 = epCoord->Map().MyGlobalElements();
                myfile <<  MyGlobalElements1[i]<< "/" << ii << "    ";
              }

              iii = FirstPointInElementList1[i]+ii;
            }
            for (int j = 0; j < NumVectors1 ; j++)
            {
              myfile.width(20);
              myfile <<  A_Pointers[j][iii];
            }

            myfile.precision(18); // set high precision for output

            // add solution vector entry
            myfile.width(25); myfile << (*exactLsgVec)[iii];

            // add preconditioned solution vector entry
            myfile.width(25); myfile << (*precLsgVec)[iii];

            Teuchos::ArrayRCP<SC> mgridLsgVecData = mgridLsgVec->getDataNonConst(0);
            myfile.width(25); myfile << mgridLsgVecData[iii];


            myfile.precision(6); // set default precision
            myfile << std::endl;
          }
        } // end loop over all lines on current proc
        myfile << std::flush;

        // syncronize procs
        comm->barrier();
        comm->barrier();
        comm->barrier();

      } // end myProc
    }

    ////////////
    myfile.close();

  comm->barrier();
  tm = Teuchos::null;
  globalTimeMonitor = Teuchos::null;

  if (printTimings == "yes") {
    TimeMonitor::summarize(A->getRowMap()->getComm().ptr(), std::cout, false, true, false, Teuchos::Union);
  }

  return 0;
} //main
  void testInitialzation(const Teuchos::RCP<Teuchos::ParameterList>& ipb,
			 std::vector<panzer::BC>& bcs)
  {
    // Physics block
    Teuchos::ParameterList& physics_block = ipb->sublist("test physics");
    {
      Teuchos::ParameterList& p = physics_block.sublist("a");
      p.set("Type","Energy");
      p.set("Prefix","");
      p.set("Model ID","solid");
      p.set("Basis Type","HGrad");
      p.set("Basis Order",2);
    }
    {
      Teuchos::ParameterList& p = physics_block.sublist("b");
      p.set("Type","Energy");
      p.set("Prefix","ION_");
      p.set("Model ID","solid");
      p.set("Basis Type","HGrad");
      p.set("Basis Order",1);
    }

    {
      std::size_t bc_id = 0;
      panzer::BCType neumann = BCT_Dirichlet;
      std::string sideset_id = "left";
      std::string element_block_id = "eblock-0_0";
      std::string dof_name = "TEMPERATURE";
      std::string strategy = "Constant";
      double value = 5.0;
      Teuchos::ParameterList p;
      p.set("Value",value);
      panzer::BC bc(bc_id, neumann, sideset_id, element_block_id, dof_name, 
		    strategy, p);
      bcs.push_back(bc);
    } 
    {
      std::size_t bc_id = 1;
      panzer::BCType neumann = BCT_Dirichlet;
      std::string sideset_id = "right";
      std::string element_block_id = "eblock-1_0";
      std::string dof_name = "TEMPERATURE";
      std::string strategy = "Constant";
      double value = 5.0;
      Teuchos::ParameterList p;
      p.set("Value",value);
      panzer::BC bc(bc_id, neumann, sideset_id, element_block_id, dof_name, 
		    strategy, p);
      bcs.push_back(bc);
    }   
    {
      std::size_t bc_id = 2;
      panzer::BCType neumann = BCT_Dirichlet;
      std::string sideset_id = "top";
      std::string element_block_id = "eblock-1_0";
      std::string dof_name = "TEMPERATURE";
      std::string strategy = "Constant";
      double value = 5.0;
      Teuchos::ParameterList p;
      p.set("Value",value);
      panzer::BC bc(bc_id, neumann, sideset_id, element_block_id, dof_name, 
		    strategy, p);
      bcs.push_back(bc);
    }

  }
  TEUCHOS_UNIT_TEST(scatter_field_evaluators, cell_field)
  {

    const std::size_t workset_size = 5;
    linBasis = buildLinearBasis(workset_size);

    Teuchos::RCP<panzer_stk::STK_Interface> mesh = buildMesh(5,5,false);

    RCP<Epetra_Comm> Comm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));

     Teuchos::RCP<shards::CellTopology> topo = 
        Teuchos::rcp(new shards::CellTopology(shards::getCellTopologyData< shards::Quadrilateral<4> >()));
    panzer::CellData cellData(workset_size,topo);
    Teuchos::RCP<panzer::IntegrationRule> intRule = Teuchos::rcp(new panzer::IntegrationRule(1,cellData));

    Teuchos::RCP<Teuchos::ParameterList> ipb = Teuchos::parameterList("Physics Blocks");
    std::vector<panzer::BC> bcs;
    testInitialzation(ipb, bcs);

    Teuchos::RCP<PHX::FieldManager<panzer::Traits> > fm = 
      Teuchos::rcp(new PHX::FieldManager<panzer::Traits>);
    {
       Teuchos::ParameterList pl;
       pl.set("Data Layout",linBasis->functional);
       fm->registerEvaluator<panzer::Traits::Residual>(Teuchos::rcp(new XCoordinate<panzer::Traits::Residual,panzer::Traits>(pl)));
    }

    {
       Teuchos::ParameterList pl;
       pl.set("Nodes",1);
       pl.set("Data Layout",intRule->dl_scalar);
       fm->registerEvaluator<panzer::Traits::Residual>(Teuchos::rcp(new XCoordinate<panzer::Traits::Residual,panzer::Traits>(pl)));
    }

    {
       Teuchos::RCP<std::vector<std::string> > fieldNames
             = Teuchos::rcp(new std::vector<std::string>);
       fieldNames->push_back("x-coord");
    
       Teuchos::ParameterList pl;
       pl.set("Mesh",mesh);
       pl.set("IR",intRule);
       pl.set("Field Names",fieldNames);
       pl.set("Scatter Name", "xcoord-scatter-cell-residual");
       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > eval
             = Teuchos::rcp(new panzer_stk::ScatterCellAvgQuantity<panzer::Traits::Residual,panzer::Traits>(pl));
       fm->registerEvaluator<panzer::Traits::Residual>(eval);
       fm->requireField<panzer::Traits::Residual>(*eval->evaluatedFields()[0]);
    }

    {
       Teuchos::RCP<std::vector<std::string> > fieldNames
             = Teuchos::rcp(new std::vector<std::string>);
       fieldNames->push_back("x-coord");

       std::string scatterName = "xcoord-scatter-residual";
       Teuchos::RCP<PHX::Evaluator<panzer::Traits> > eval
             = Teuchos::rcp(new panzer_stk::ScatterFields<panzer::Traits::Residual,panzer::Traits>(scatterName,mesh,linBasis,*fieldNames));
       fm->registerEvaluator<panzer::Traits::Residual>(eval);
       fm->requireField<panzer::Traits::Residual>(*eval->evaluatedFields()[0]);
    }

    // build physics blocks
    //////////////////////////////////////////////////////////////
    std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physicsBlocks;
    {
      Teuchos::RCP<user_app::MyFactory> eqset_factory = Teuchos::rcp(new user_app::MyFactory);
      user_app::BCFactory bc_factory;
      const int default_integration_order = 1;

      std::map<std::string,std::string> block_ids_to_physics_ids;
      block_ids_to_physics_ids["eblock-0_0"] = "test physics";

      std::map<std::string,Teuchos::RCP<const shards::CellTopology> > block_ids_to_cell_topo;
      block_ids_to_cell_topo["eblock-0_0"] = mesh->getCellTopology("eblock-0_0");
      
      Teuchos::RCP<panzer::GlobalData> gd = panzer::createGlobalData();

      panzer::buildPhysicsBlocks(block_ids_to_physics_ids,
				 block_ids_to_cell_topo,
				 ipb,
				 default_integration_order,
				 workset_size,
				 eqset_factory,
				 gd,
				 false,
				 physicsBlocks);
    }

    // register jacobian size
    //////////////////////////////////////////////////////////////
    std::vector<PHX::index_size_type> derivative_dimensions;
    derivative_dimensions.push_back(9+4);
    fm->setKokkosExtendedDataTypeDimensions<panzer::Traits::Jacobian>(derivative_dimensions);

    // build worksets
    //////////////////////////////////////////////////////////////

    Teuchos::RCP<panzer::PhysicsBlock> physics_block_one = panzer::findPhysicsBlock("eblock-0_0",physicsBlocks);
    Teuchos::RCP<std::vector<panzer::Workset> > volume_worksets = panzer_stk::buildWorksets(*mesh,*physics_block_one);


    panzer::Traits::SetupData sd;
    sd.worksets_ = volume_worksets;
    fm->postRegistrationSetupForType<panzer::Traits::Residual>(sd);
    fm->writeGraphvizFile<panzer::Traits::Residual>("resi-eval-graph.dot");

    std::vector<panzer::Workset> & worksets = *volume_worksets;
    panzer::Traits::PreEvalData preEvalData;
    fm->preEvaluate<panzer::Traits::Residual>(preEvalData);
    for(std::size_t ws=0;ws<worksets.size();ws++) {
       fm->evaluateFields<panzer::Traits::Residual>(worksets[ws]);
    }
    fm->postEvaluate<panzer::Traits::Residual>(0);

    if(mesh->isWritable()) 
       mesh->writeToExodus("x-coord-cell.exo");
  }
QCAD::ResponseCenterOfMass<EvalT, Traits>::
ResponseCenterOfMass(Teuchos::ParameterList& p,
		     const Teuchos::RCP<Albany::Layouts>& dl) :
  coordVec("Coord Vec", dl->qp_vector),
  weights("Weights", dl->qp_scalar)
{
  // get and validate Response parameter list
  Teuchos::ParameterList* plist = 
    p.get<Teuchos::ParameterList*>("Parameter List");
  Teuchos::RCP<const Teuchos::ParameterList> reflist = 
    this->getValidResponseParameters();
  plist->validateParameters(*reflist,0);

  // number of quad points per cell and dimension of space
  Teuchos::RCP<PHX::DataLayout> scalar_dl = dl->qp_scalar;
  Teuchos::RCP<PHX::DataLayout> vector_dl = dl->qp_vector;
  
  std::vector<PHX::DataLayout::size_type> dims;
  vector_dl->dimensions(dims);
  numQPs  = dims[1];
  numDims = dims[2];

  //! Get material DB from parameters passed down from problem (if given)
  Teuchos::RCP<QCAD::MaterialDatabase> materialDB;
  Teuchos::RCP<Teuchos::ParameterList> paramsFromProblem = 
    p.get< Teuchos::RCP<Teuchos::ParameterList> >("Parameters From Problem");
  if(paramsFromProblem != Teuchos::null)
    materialDB = paramsFromProblem->get< Teuchos::RCP<QCAD::MaterialDatabase> >("MaterialDB");
  else materialDB = Teuchos::null;
  
  // User-specified parameters
  fieldName = plist->get<std::string>("Field Name");
  opRegion  = Teuchos::rcp( new QCAD::MeshRegion<EvalT, Traits>("Coord Vec","Weights",*plist,materialDB,dl) );
  
  // setup field
  PHX::MDField<ScalarT> f(fieldName, scalar_dl); field = f;

  // add dependent fields
  this->addDependentField(field);
  this->addDependentField(coordVec);
  this->addDependentField(weights);
  opRegion->addDependentFields(this);

  this->setName(fieldName+" Response Center of Mass" );

  using PHX::MDALayout;

  // Setup scatter evaluator
  p.set("Stand-alone Evaluator", false);
  std::string local_response_name = 
    fieldName + " Local Response Center of Mass";
  std::string global_response_name = 
    fieldName + " Global Response Center of Mass";
  int worksetSize = scalar_dl->dimension(0);
  int responseSize = 4;
  Teuchos::RCP<PHX::DataLayout> local_response_layout =
    Teuchos::rcp(new MDALayout<Cell,Dim>(worksetSize, responseSize));
  Teuchos::RCP<PHX::DataLayout> global_response_layout =
    Teuchos::rcp(new MDALayout<Dim>(responseSize));
  PHX::Tag<ScalarT> local_response_tag(local_response_name, 
				       local_response_layout);
  PHX::Tag<ScalarT> global_response_tag(global_response_name, 
					global_response_layout);
  p.set("Local Response Field Tag", local_response_tag);
  p.set("Global Response Field Tag", global_response_tag);
  PHAL::SeparableScatterScalarResponse<EvalT,Traits>::setup(p,dl);
}
int main(int argc, char *argv[]) {
  int i;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  int MyPID = Comm.MyPID();

  // Number of dimension of the domain
  int space_dim = 2;
  
  // Size of each of the dimensions of the domain
  std::vector<double> brick_dim( space_dim );
  brick_dim[0] = 1.0;
  brick_dim[1] = 1.0;
  
  // Number of elements in each of the dimensions of the domain
  std::vector<int> elements( space_dim );
  elements[0] = 10;
  elements[1] = 10;
  
  // Create problem
  Teuchos::RCP<ModalProblem> testCase = Teuchos::rcp( new ModeLaplace2DQ2(Comm, brick_dim[0], elements[0], brick_dim[1], elements[1]) );
  
  // Get the stiffness and mass matrices
  Teuchos::RCP<Epetra_CrsMatrix> K = Teuchos::rcp( const_cast<Epetra_CrsMatrix *>(testCase->getStiffness()), false );
  Teuchos::RCP<Epetra_CrsMatrix> M = Teuchos::rcp( const_cast<Epetra_CrsMatrix *>(testCase->getMass()), false );
	
  //
  // *******************************************************
  // Set up Amesos direct solver for inner iteration
  // *******************************************************
  //

  // Create the shifted system K - sigma * M.
  // For the buckling transformation, this shift must be nonzero.

  double sigma = 1.0;
  Epetra_CrsMatrix Kcopy( *K );

  int addErr = EpetraExt::MatrixMatrix::Add( *M, false, -sigma, Kcopy, 1.0 );
  if (addErr != 0) {
    if (MyPID == 0) {
      std::cout << "EpetraExt::MatrixMatrix::Add returned with error: " << addErr << std::endl;
    }
#ifdef HAVE_MPI
    MPI_Finalize() ;
#endif
    return -1;
  }

  // Create Epetra linear problem class to solve "x = b"
  Epetra_LinearProblem AmesosProblem;
  AmesosProblem.SetOperator(&Kcopy);
  
  // Create Amesos factory and solver for solving "(K - sigma*M)x = b" using a direct factorization
  Amesos amesosFactory;
  Teuchos::RCP<Amesos_BaseSolver> AmesosSolver = 
    Teuchos::rcp( amesosFactory.Create( "Klu", AmesosProblem ) );

  // The AmesosBucklingOp class assumes that the symbolic/numeric factorizations have already
  // been performed on the linear problem.
  AmesosSolver->SymbolicFactorization();
  AmesosSolver->NumericFactorization();

  //
  // ************************************
  // Start the block Arnoldi iteration
  // ************************************
  //
  //  Variables used for the Block Arnoldi Method
  //
  int nev = 10;
  int blockSize = 3;  
  int numBlocks = 3*nev/blockSize;
  int maxRestarts = 5;
  //int step = 5;
  double tol = 1.0e-8;
  std::string which = "LM";
  int verbosity = Anasazi::Errors + Anasazi::Warnings + Anasazi::FinalSummary;
  //
  // Create parameter list to pass into solver
  //
  Teuchos::ParameterList MyPL;
  MyPL.set( "Verbosity", verbosity );
  MyPL.set( "Which", which );
  MyPL.set( "Block Size", blockSize );
  MyPL.set( "Num Blocks", numBlocks );
  MyPL.set( "Maximum Restarts", maxRestarts );
  MyPL.set( "Convergence Tolerance", tol );
  //MyPL.set( "Step Size", step );
  
  typedef Epetra_MultiVector MV;
  typedef Epetra_Operator OP;
  typedef Anasazi::MultiVecTraits<double, MV> MVT;
  typedef Anasazi::OperatorTraits<double, MV, OP> OPT;
  
  // Create an Epetra_MultiVector for an initial vector to start the solver.
  // Note:  This needs to have the same number of columns as the blocksize.
  Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(K->Map(), blockSize) );
  MVT::MvRandom( *ivec );
  
  // Create the Epetra_Operator for the buckling transformation using the Amesos direct solver.
  Teuchos::RCP<AmesosBucklingOp> BucklingOp 
    = Teuchos::rcp( new AmesosBucklingOp(AmesosProblem, AmesosSolver, K) );
  
  Teuchos::RCP<Anasazi::BasicEigenproblem<double,MV,OP> > MyProblem = 
    Teuchos::rcp( new Anasazi::BasicEigenproblem<double,MV,OP>(BucklingOp, K, ivec) );
  
  // Inform the eigenproblem that the matrix pencil (K,M) is symmetric
  MyProblem->setHermitian(true);
  
  // Set the number of eigenvalues requested 
  MyProblem->setNEV( nev );
  
  // Inform the eigenproblem that you are finished passing it information
  bool boolret = MyProblem->setProblem();
  if (boolret != true) {
    if (MyPID == 0) {
      std::cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << std::endl;
    }
#ifdef HAVE_MPI
    MPI_Finalize() ;
#endif
    return -1;
  }

  // Initialize the Block Arnoldi solver
  Anasazi::BlockKrylovSchurSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL);
  
  // Solve the problem to the specified tolerances or length
  Anasazi::ReturnType returnCode = MySolverMgr.solve();
  if (returnCode != Anasazi::Converged && MyPID==0) {
    std::cout << "Anasazi::EigensolverMgr::solve() returned unconverged." << std::endl;
  }

  // Get the eigenvalues and eigenvectors from the eigenproblem
  Anasazi::Eigensolution<double,MV> sol = MyProblem->getSolution();
  std::vector<Anasazi::Value<double> > evals = sol.Evals;
  Teuchos::RCP<MV> evecs = sol.Evecs;
  int numev = sol.numVecs;
  
  if (numev > 0) {

    // Undo buckling transformation; computed eigenvalues are real
    std::vector<double> compEvals(numev);
    for (i=0; i<numev; ++i) {
      compEvals[i] = sigma*evals[i].realpart/(evals[i].realpart-1.0);
    }
    
    // Remember, eigenvectors are constructed K-orthogonal to preserve symmetry,
    // so numerator of the Rayleigh quotient is 1.0.
    Teuchos::SerialDenseMatrix<int,double> dmatr(numev,numev);
    Epetra_MultiVector tempvec(M->Map(), MVT::GetNumberVecs( *evecs ));
    OPT::Apply( *M, *evecs, tempvec );
    MVT::MvTransMv( 1.0, tempvec, *evecs, dmatr );
    
    if (MyPID==0) {
      double rq_eval = 0.0;
      std::cout.setf(std::ios_base::right, std::ios_base::adjustfield);
      std::cout<<"Actual Eigenvalues (obtained by Rayleigh quotient) : "<<std::endl;
      std::cout<<"------------------------------------------------------"<<std::endl;
      std::cout<<std::setw(16)<<"Real Part"
        <<std::setw(16)<<"Rayleigh Error"<<std::endl;
      std::cout<<"------------------------------------------------------"<<std::endl;
      for (i=0; i<numev; i++) {
        rq_eval = 1.0 / dmatr(i,i);
        std::cout<<std::setw(16)<<rq_eval
          <<std::setw(16)<<Teuchos::ScalarTraits<double>::magnitude(rq_eval-compEvals[i])
          <<std::endl;
      }
      std::cout<<"------------------------------------------------------"<<std::endl;
    }
    
  }

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return 0;
}
int main(int argc, char** argv) {
#if defined(HAVE_MPI) && defined(HAVE_EPETRA)

  int numProcs = 1;
  int localProc = 0;

  //first, set up our MPI environment...
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &localProc);
  MPI_Comm_size(MPI_COMM_WORLD, &numProcs);

// This program can only run on 3 processors, to make things
// work out easy.
//
  if (numProcs != 3) {
    std::cout << "num-procs="<<numProcs<<". This program can only "
      << "run on 3 procs. Exiting."<<std::endl;
    MPI_Finalize();
    return(0);
  }

//Consider the following mesh of 4 2-D quad elements:
//
//  *-------*-------*
// 8|      7|      6|
//  |  E2   |  E3   |
//  *-------*-------*
// 3|      2|      5|
//  |  E0   |  E1   |
//  *-------*-------*
// 0       1       4
//
// Node-ids are to the lower-left of each node (*).
//
// Mimicing a finite-element application, we will say that
// each node has 1 scalar degree-of-freedom, and assemble
// a matrix which would have 9 global rows and columns.
//
// Each processor will have 3 rows. We'll set up a strange
// initial map, where nodes are distributed as follows:
//
// proc 0: nodes 0,3,8,
// proc 1: nodes 1,2,7
// proc 2: nodes 4,5,6.
//
// After we assemble our matrix, we'll create another matrix
// and populate it with graph edge weights such that the
// partitioner repartitions the problem so that nodes are
// laid out as follows:
//
// proc 0: nodes 0, 1, 4
// proc 1: nodes 3, 2, 5
// proc 2: nodes 8, 7, 6
//

  int nodesPerElem = 4;
  int global_n = 9;

  //First, set up the initial map:

  std::vector<int> mynodes(3);
  if (localProc == 0) {
    mynodes[0] = 0; mynodes[1] = 3; mynodes[2] = 8;
  }
  if (localProc == 1) {
    mynodes[0] = 1; mynodes[1] = 2; mynodes[2] = 7;
  }
  if (localProc == 2) {
    mynodes[0] = 4; mynodes[1] = 5; mynodes[2] = 6;
  }

  Epetra_MpiComm comm(MPI_COMM_WORLD);
  Epetra_Map origmap(global_n, 3, &mynodes[0], 0, comm);

  Teuchos::RCP<Epetra_FECrsMatrix> matrix =
    Teuchos::rcp(new Epetra_FECrsMatrix(Copy, origmap, 0));

  //We'll assemble elements E0 and E1 on proc 0,
  //               element E2 or proc 1,
  //               element E3 on proc 2.

  std::vector<int> indices(nodesPerElem);
  std::vector<double> coefs(nodesPerElem*nodesPerElem,2.0);

  if (localProc == 0) {
    //element E0:
    indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 3;
    matrix->InsertGlobalValues(nodesPerElem, &indices[0], &coefs[0]);

    //element E1:
    indices[0] = 1; indices[1] = 4; indices[2] = 5; indices[3] = 2;
    matrix->InsertGlobalValues(nodesPerElem, &indices[0], &coefs[0]);
  }
  else if (localProc == 1) {
    //element E2:
    indices[0] = 3; indices[1] = 2; indices[2] = 7; indices[3] = 8;
    matrix->InsertGlobalValues(nodesPerElem, &indices[0], &coefs[0]);
  }
  else { //localProc==2
    //element E3:
    indices[0] = 2; indices[1] = 5; indices[2] = 6; indices[3] = 7;
    matrix->InsertGlobalValues(nodesPerElem, &indices[0], &coefs[0]);
  }

  int err = matrix->GlobalAssemble();
  if (err != 0) {
    std::cout << "err="<<err<<" returned from matrix->GlobalAssemble()"
      << std::endl;
  }

//  std::cout << "matrix: " << std::endl;
//  std::cout << *matrix << std::endl;

  //We'll need a Teuchos::ParameterList object to pass to the
  //Isorropia::Epetra::Partitioner class.
  Teuchos::ParameterList paramlist;

#ifdef HAVE_ISORROPIA_ZOLTAN
  // If Zoltan is available, we'll specify that the Zoltan package be
  // used for the partitioning operation, by creating a parameter
  // sublist named "Zoltan".
  // In the sublist, we'll set parameters that we want sent to Zoltan.

  paramlist.set("PARTITIONING METHOD", "GRAPH");
  paramlist.set("PRINT ZOLTAN METRICS", "2");
  Teuchos::ParameterList& sublist = paramlist.sublist("Zoltan");
  sublist.set("GRAPH_PACKAGE", "PHG");

  //sublist.set("DEBUG_LEVEL", "1"); // Zoltan will print out parameters
  //sublist.set("DEBUG_LEVEL", "5");   // proc 0 will trace Zoltan calls
  //sublist.set("DEBUG_MEMORY", "2");  // Zoltan will trace alloc & free

#else
  // If Zoltan is not available, a simple linear partitioner will be
  // used to partition such that the number of nonzeros is equal (or
  // close to equal) on each processor. No parameter is necessary to
  // specify this.
#endif


  Teuchos::RCP<Isorropia::Epetra::CostDescriber> costs =
    Teuchos::rcp(new Isorropia::Epetra::CostDescriber);

  //Next create a matrix which is a copy of the matrix we just
  //assembled, but we'll replace the values with graph edge weights.

  Teuchos::RCP<Epetra_FECrsMatrix> ge_weights =
    Teuchos::rcp(new Epetra_FECrsMatrix(*matrix));

  Teuchos::RCP<Epetra_CrsMatrix> crs_ge_weights;
  crs_ge_weights = ge_weights;

  //Fill the matrix with a "default" weight of 1.0.
  crs_ge_weights->PutScalar(1.0);

  //Now we'll put a "large" weight on edges that connect nodes
  //0 and 1, 1 and 4,
  //3 and 2, 2 and 5,
  //8 and 7, 7 and 6.

  double weight = 500.0;

  if (localProc == 0) {
    //row 0, edge 1
    indices[0] = 1;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(0, 1, &coefs[0], &indices[0]);

    //row 3, edge 2
    indices[0] = 2;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(3, 1, &coefs[0], &indices[0]);

    //row 8, edge 7
    indices[0] = 7;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(8, 1, &coefs[0], &indices[0]);
  }

  if (localProc == 1) {
    //row 1, edges 0 and 4
    indices[0] = 0; indices[1] = 4;
    coefs[0] = weight; coefs[1] = weight;
    crs_ge_weights->ReplaceGlobalValues(1, 2, &coefs[0], &indices[0]);

    //row 2, edges 3 and 5
    indices[0] = 3; indices[1] = 5;
    coefs[0] = weight; coefs[1] = weight;
    crs_ge_weights->ReplaceGlobalValues(2, 2, &coefs[0], &indices[0]);

    //row 7, edges 6 and 8
    indices[0] = 6; indices[1] = 8;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(7, 2, &coefs[0], &indices[0]);
  }

  if (localProc == 2) {
    //row 4, edge 1
    indices[0] = 1;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(4, 1, &coefs[0], &indices[0]);

    //row 5, edge 2
    indices[0] = 2;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(5, 1, &coefs[0], &indices[0]);

    //row 6, edge 7
    indices[0] = 7;
    coefs[0] = weight;
    crs_ge_weights->ReplaceGlobalValues(6, 1, &coefs[0], &indices[0]);
  }

// std::cout << "crs_ge_weights: " << std::endl
//       << *crs_ge_weights << std::endl;

  //Now give the graph edge weights to the CostDescriber:
  costs->setGraphEdgeWeights(crs_ge_weights);

  Teuchos::RCP<const Epetra_RowMatrix> rowmatrix;
  rowmatrix = matrix;

  //Now create the partitioner object using an Isorropia factory-like
  //function...
  Teuchos::RCP<Isorropia::Epetra::Partitioner> partitioner =
    Teuchos::rcp(new Isorropia::Epetra::Partitioner(rowmatrix, costs, paramlist));

  //Next create a Redistributor object and use it to create a
  //repartitioned copy of the matrix

  Isorropia::Epetra::Redistributor rd(partitioner);

  Teuchos::RCP<Epetra_CrsMatrix> bal_matrix;

  //Use a try-catch block because Isorropia will throw an exception
  //if it encounters an error.

  if (localProc == 0) {
    std::cout << " calling Isorropia::Epetra::Redistributor::redistribute..."
        << std::endl;
  }

  try {
    bal_matrix = rd.redistribute(*rowmatrix);
  }
  catch(std::exception& exc) {
    std::cout << "linsys example: Isorropia::Epetra::Redistributor threw "
         << "exception '" << exc.what() << "' on proc "
         << localProc << std::endl;
    MPI_Finalize();
    return(-1);
  }
  // Results

  double bal0, bal1, cutn0, cutn1, cutl0, cutl1, cutWgt0, cutWgt1;
  int numCuts0, numCuts1;

#if 1

  // Balance and cut quality before partitioning

  double goalWeight = 1.0 / (double)numProcs;
  ispatest::compute_graph_metrics(*rowmatrix, *costs, goalWeight,
                     bal0, numCuts0, cutWgt0, cutn0, cutl0);

  // Balance and cut quality after partitioning

  Teuchos::RCP<Epetra_CrsMatrix> new_weights = rd.redistribute(*crs_ge_weights);
  Isorropia::Epetra::CostDescriber new_costs;
  new_costs.setGraphEdgeWeights(new_weights);

  ispatest::compute_graph_metrics(*bal_matrix, new_costs, goalWeight,
                     bal1, numCuts1, cutWgt1, cutn1, cutl1);
#else
  std::vector<double> bal(2), cutwgt(2), cutn(2), cutl(2);
  std::vector<int >ncuts(2);

  Epetra_Import &importer = rd.get_importer();

  costs->compareBeforeAndAfterGraph(*rowmatrix, *bal_matrix, importer,
             bal, ncuts, cutwgt, cutn, cutl);

  bal0 = bal[0]; cutn0 = cutn[0]; cutl0 = cutl[0]; cutWgt0 = cutwgt[0]; numCuts0 = ncuts[0];
  bal1 = bal[1]; cutn1 = cutn[1]; cutl1 = cutl[1]; cutWgt1 = cutwgt[1]; numCuts1 = ncuts[1];
#endif

  bal_matrix.release();

  if (localProc == 0){
    std::cout << "Before partitioning: Number of cuts " << numCuts0 << " Cut weight " << cutWgt0 << std::endl;
    std::cout << "                     Balance " << bal0 << " cutN " << cutn0 << " cutL " << cutl0;
    std::cout << std::endl;

    std::cout << "After partitioning:  Number of cuts " << numCuts1 << " Cut weight " << cutWgt1 << std::endl;
    std::cout << "                     Balance " << bal1 << " cutN " << cutn1 << " cutL " << cutl1;
    std::cout << std::endl;
  }



  MPI_Finalize();

#else
  std::cout << "part_redist: must have both MPI and EPETRA. Make sure Trilinos "
    << "is configured with --enable-mpi and --enable-epetra." << std::endl;
#endif

  return(0);
}
void
Albany::ResponseFactory::
createResponseFunction(
  const std::string& name,
  Teuchos::ParameterList& responseParams,
  Teuchos::Array< Teuchos::RCP<AbstractResponseFunction> >& responses) const
{
  using std::string;
  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::ParameterList;
  using Teuchos::Array;

  RCP<const Teuchos_Comm> comm = app->getComm();

  if (name == "Solution Average") {
    responses.push_back(rcp(new Albany::SolutionAverageResponseFunction(comm)));
  }

  else if (name == "Solution Two Norm") {
    responses.push_back(rcp(new Albany::SolutionTwoNormResponseFunction(comm)));
  }
  else if (name == "Solution Values") {
    responses.push_back(rcp(new Albany::SolutionValuesResponseFunction(app, responseParams)));
  }

  else if (name == "Solution Max Value") {
    int eq = responseParams.get("Equation", 0);
    int neq = responseParams.get("Num Equations", 1);
    bool inor =  responseParams.get("Interleaved Ordering", true);

    responses.push_back(
      rcp(new Albany::SolutionMaxValueResponseFunction(comm, neq, eq, inor)));
  }

  else if (name == "Solution Two Norm File") {
    responses.push_back(
      rcp(new Albany::SolutionFileResponseFunction<Albany::NormTwo>(comm)));
  }

  else if (name == "Solution Inf Norm File") {
    responses.push_back(
      rcp(new Albany::SolutionFileResponseFunction<Albany::NormInf>(comm)));
  }

  else if (name == "OBC Functional") {
#ifdef ALBANY_PERIDIGM
#ifdef ALBANY_EPETRA
    responses.push_back(rcp(new Albany::AlbanyPeridigmOBCFunctional(comm)));
#endif
#endif
  }

  else if (name == "Aggregated") {
    int num_aggregate_responses = responseParams.get<int>("Number");
    Array< RCP<AbstractResponseFunction> > aggregated_responses;
    Array< RCP<ScalarResponseFunction> > scalar_responses;
    for (int i=0; i<num_aggregate_responses; i++) {
      std::string id = Albany::strint("Response",i);
      std::string name = responseParams.get<std::string>(id);
      std::string sublist_name = Albany::strint("ResponseParams",i);
      createResponseFunction(name, responseParams.sublist(sublist_name),
			     aggregated_responses);

    }
    scalar_responses.resize(aggregated_responses.size());
    for (int i=0; i<aggregated_responses.size(); i++) {
      TEUCHOS_TEST_FOR_EXCEPTION(
	aggregated_responses[i]->isScalarResponse() != true, std::logic_error,
	"Response function " << i << " is not a scalar response function." <<
	std::endl <<
	"The aggregated response can only aggregate scalar response " <<
	"functions!");
      scalar_responses[i] =
	Teuchos::rcp_dynamic_cast<ScalarResponseFunction>(
	  aggregated_responses[i]);
    }
    responses.push_back(
      rcp(new Albany::AggregateScalarResponseFunction(comm, scalar_responses)));
  }

  else if (name == "Field Integral" ||
	   name == "Field Value" ||
	   name == "Field Average" ||
	   name == "Surface Velocity Mismatch" ||
           name == "Aeras Shallow Water L2 Error" ||
           name == "Aeras Total Volume" ||
	   name == "Center Of Mass" ||
	   name == "Save Field" ||
	   name == "Region Boundary" ||
	   name == "Element Size Field" ||
	   name == "Save Nodal Fields" ||
	   name == "Stiffness Objective" ||
	   name == "Internal Energy Objective" ||
	   name == "Tensor PNorm Objective" ||
	   name == "Homogenized Constants Response" ||
	   name == "Modal Objective" ||
           name == "PHAL Field Integral" ||
           name == "PHAL Field IntegralT") {
    responseParams.set("Name", name);
    for (int i=0; i<meshSpecs.size(); i++) {
#if defined(ALBANY_LCM)
      // Skip if dealing with interface block
      //if (meshSpecs[i]->ebName == "Surface Element") continue;
#endif
      responses.push_back(
          rcp(new Albany::FieldManagerScalarResponseFunction(
              app, prob, meshSpecs[i], stateMgr, responseParams)));
    }
  }

  else if (name == "IP to Nodal Field" ||
           name == "Project IP to Nodal Field") {
    responseParams.set("Name", name);
    for (int i=0; i<meshSpecs.size(); i++) {
#if defined(ALBANY_LCM)
      // Skip if dealing with interface block
      //if (meshSpecs[i]->ebName == "Surface Element") continue;
#endif
      // For these RFs, default to true for this parm.
      const char* reb_parm = "Restrict to Element Block";
      if ( ! responseParams.isType<bool>(reb_parm) &&
          (name == "IP to Nodal Field" ||
           name == "Project IP to Nodal Field"))
        responseParams.set<bool>(reb_parm, true);
      responses.push_back(
        rcp(new Albany::FieldManagerResidualOnlyResponseFunction(
              app, prob, meshSpecs[i], stateMgr, responseParams)));
    }
  }

  else if (name == "Solution") {
#if defined(ALBANY_EPETRA)
    responses.push_back(
      rcp(new Albany::SolutionResponseFunction(app, responseParams)));
#endif
  }

  else if (name == "KL") {
    Array< RCP<AbstractResponseFunction> > base_responses;
    std::string name = responseParams.get<std::string>("Response");
    createResponseFunction(name, responseParams.sublist("ResponseParams"),
			   base_responses);
    for (int i=0; i<base_responses.size(); i++)
      responses.push_back(
	rcp(new Albany::KLResponseFunction(base_responses[i], responseParams)));
  }

#ifdef ALBANY_QCAD
#if defined(ALBANY_EPETRA)
  else if (name == "Saddle Value") {
    responseParams.set("Name", name);
    for (int i=0; i<meshSpecs.size(); i++) {
      responses.push_back(
	rcp(new QCAD::SaddleValueResponseFunction(
	      app, prob, meshSpecs[i], stateMgr, responseParams)));
    }
  }
#endif
#endif

  else {
    TEUCHOS_TEST_FOR_EXCEPTION(
      true, Teuchos::Exceptions::InvalidParameter,
      std::endl << "Error!  Unknown response function " << name <<
      "!" << std::endl << "Supplied parameter list is " <<
      std::endl << responseParams);
  }
}
Exemple #19
0
// ======================================================================
int main(int argc, char *argv[])
{

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  int nx = 30;
  Teuchos::ParameterList GaleriList;
  GaleriList.set("n", nx * nx);
  GaleriList.set("nx", nx);
  GaleriList.set("ny", nx);

  Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap("Linear", Comm, GaleriList) );
  Teuchos::RefCountPtr<Epetra_RowMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) );
  Epetra_Vector LHS(*Map);
  Epetra_Vector RHS(*Map);
  Epetra_LinearProblem Problem(&*A, &LHS, &RHS);

  int TestPassed = true;

  // Jacobi as in AztecOO (no overlap)
  for (int ival = 1 ; ival < 10 ; ival += 3) {
    TestPassed = TestPassed &&
      CompareWithAztecOO(Problem,"Jacobi",0,ival);
  }

#if 0
  // AztecOO with IC and overlap complains, also with
  // large fill-ins (in parallel)
  TestPassed = TestPassed &&
    CompareWithAztecOO(Problem,"IC no reord",0,0);
  TestPassed = TestPassed &&
    CompareWithAztecOO(Problem,"IC reord",0,0);

  vector<std::string> Tests;
  // now test solvers that accept overlap
  Tests.push_back("ILU no reord");
  Tests.push_back("ILU reord");
  // following requires --enable-aztecoo-azlu
#ifdef HAVE_IFPACK_AMESOS
  //Tests.push_back("LU");
#endif

  for (unsigned int i = 0 ; i < Tests.size() ; ++i) {
    for (int overlap = 0 ; overlap < 1 ; overlap += 2) {
      for (int ival = 0 ; ival < 10 ; ival += 4)
        TestPassed = TestPassed &&
          CompareWithAztecOO(Problem,Tests[i],overlap,ival);
    }
  }
#endif

  if (!TestPassed) {
    cerr << "Test `CompareWithAztecOO.exe' FAILED!" << endl;
    exit(EXIT_FAILURE);
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif
  cout << "Test `CompareWithAztecOO.exe' passed!" << endl;

  exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[]) {
  //
  bool haveM = false;

#ifdef EPETRA_MPI  
  // Initialize MPI  
  MPI_Init(&argc,&argv);   
  Epetra_MpiComm Comm( MPI_COMM_WORLD );  
#else  
  Epetra_SerialComm Comm;  
#endif
  
  int MyPID = Comm.MyPID();

  int nev = 5;
  int blockSize = 5;
  int maxIterations = 1000;
  double tol = 1.0e-8;
  bool verbose=false, locking=false, fullOrtho=true;
  std::string k_filename = "";
  std::string m_filename = "";
  std::string which = "SM";
  Teuchos::CommandLineProcessor cmdp(false,true);
  cmdp.setOption("nev",&nev,"Number of eigenvalues to compute.");
  cmdp.setOption("blocksize",&blockSize,"Block size used in LOBPCG.");
  cmdp.setOption("maxiters",&maxIterations,"Maximum number of iterations used in LOBPCG.");
  cmdp.setOption("tol",&tol,"Convergence tolerance requested for computed eigenvalues.");
  cmdp.setOption("verbose","quiet",&verbose,"Print messages and results.");
  cmdp.setOption("locking","nolocking",&locking,"Use locking of converged eigenvalues.");
  cmdp.setOption("fullortho","nofullortho",&fullOrtho,"Use full orthogonalization.");
  cmdp.setOption("sort",&which,"Targetted eigenvalues (SM,LM,SR,or LR).");
  cmdp.setOption("K-filename",&k_filename,"Filename and path of the stiffness matrix.");
  cmdp.setOption("M-filename",&m_filename,"Filename and path of the mass matrix.");
  if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    return -1;
  }
  if (k_filename=="") {
    cout << "The matrix K must be supplied through an input file!!!" << endl;
#ifdef HAVE_MPI
    MPI_Finalize();
#endif
    return -1;
  }
  if (m_filename!="") {
    haveM = true;
  }
  //
  //**********************************************************************
  //******************Set up the problem to be solved*********************
  //**********************************************************************
  //
  // *****Read in matrix from file******
  //
  Teuchos::RCP<Epetra_Map> Map;
  Teuchos::RCP<Epetra_CrsMatrix> K, M;
  EpetraExt::readEpetraLinearSystem( k_filename, Comm, &K, &Map );

  if (haveM) {
    EpetraExt::readEpetraLinearSystem( m_filename, Comm, &M, &Map );
  }
  //
  //************************************
  // Start the block Davidson iteration 
  //***********************************         
  //
  //  Variables used for the LOBPCG Method
  // 
  // Set verbosity level
  int verbosity = Anasazi::Errors + Anasazi::Warnings;
  if (verbose) {
    verbosity += Anasazi::FinalSummary + Anasazi::TimingDetails;
  }
  //
  // Create parameter list to pass into solver
  //
  Teuchos::ParameterList MyPL;
  MyPL.set( "Verbosity", verbosity );
  MyPL.set( "Which", which );
  MyPL.set( "Block Size", blockSize );
  MyPL.set( "Maximum Iterations", maxIterations );
  MyPL.set( "Convergence Tolerance", tol );
  MyPL.set( "Use Locking", locking );
  MyPL.set( "Locking Tolerance", tol/10 );
  MyPL.set( "Full Ortho", fullOrtho );

  typedef Epetra_MultiVector MV;
  typedef Epetra_Operator OP;
  typedef Anasazi::MultiVecTraits<double, MV> MVT;
  typedef Anasazi::OperatorTraits<double, MV, OP> OPT;
  //
  // Create the eigenproblem to be solved.
  //
  Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(*Map, blockSize) );
  ivec->Random();
  
  Teuchos::RCP<Anasazi::BasicEigenproblem<double, MV, OP> > MyProblem;
  if (haveM) {
    MyProblem = Teuchos::rcp( new Anasazi::BasicEigenproblem<double, MV, OP>( K, M, ivec ) );
  } 
  else {
    MyProblem = Teuchos::rcp( new Anasazi::BasicEigenproblem<double, MV, OP>( K, ivec ) );
  } 
 
  // Inform the eigenproblem that (K,M) is Hermitian
  MyProblem->setHermitian(true);

  // Set the number of eigenvalues requested 
  MyProblem->setNEV( nev );

  // Inform the eigenproblem that you are finished passing it information
  bool boolret = MyProblem->setProblem();
  if (boolret != true) {
    if (verbose && MyPID == 0) {
      cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << endl;
    }
#ifdef HAVE_MPI
    MPI_Finalize() ;
#endif
    return -1;
  }

  // Initialize the LOBPCG solver
  Anasazi::LOBPCGSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL);
    
  // Solve the problem to the specified tolerances or length
  Anasazi::ReturnType returnCode = MySolverMgr.solve();
  if (returnCode != Anasazi::Converged && MyPID==0 && verbose) {
    cout << "Anasazi::EigensolverMgr::solve() returned unconverged." << endl;
  }
  
  // Get the eigenvalues and eigenvectors from the eigenproblem
  Anasazi::Eigensolution<double,MV> sol = MyProblem->getSolution();
  std::vector<Anasazi::Value<double> > evals = sol.Evals;
  Teuchos::RCP<MV> evecs = sol.Evecs;
  std::vector<int> index = sol.index;
  int numev = sol.numVecs;

  if (numev > 0) {
    // Compute residuals.
    Teuchos::LAPACK<int,double> lapack;
    std::vector<double> normEV(numev);
    
    // Get storage
    Teuchos::RCP<Epetra_MultiVector> Kevecs, Mevecs;
    Teuchos::SerialDenseMatrix<int,double> B(numev,numev);
    B.putScalar(0.0); 
    for (int i=0; i<numev; i++) {B(i,i) = evals[i].realpart;}
    
    // Compute K*evecs
    Kevecs = Teuchos::rcp(new Epetra_MultiVector(*Map,numev) );
    OPT::Apply( *K, *evecs, *Kevecs );

    // Compute M*evecs
    if (haveM) {
      Mevecs = Teuchos::rcp(new Epetra_MultiVector(*Map,numev) );
      OPT::Apply( *M, *evecs, *Mevecs );
    }
    else {
      Mevecs = evecs;
    }

    // Compute K*evecs - lambda*M*evecs and its norm
    MVT::MvTimesMatAddMv( -1.0, *Mevecs, B, 1.0, *Kevecs );
    MVT::MvNorm( *Kevecs, normEV );
    
    // Scale the norms by the eigenvalue
    for (int i=0; i<numev; i++) {
      normEV[i] /= Teuchos::ScalarTraits<double>::magnitude( evals[i].realpart );
    }
    
    // Output computed eigenvalues and their direct residuals
    if (verbose && MyPID==0) {
      cout.setf(std::ios_base::right, std::ios_base::adjustfield);
      cout<<endl<< "Actual Residuals"<<endl;
      cout<< std::setw(16) << "Real Part"
        << std::setw(20) << "Direct Residual"<< endl;
      cout<<"-----------------------------------------------------------"<<endl;
      for (int i=0; i<numev; i++) {
        cout<< std::setw(16) << evals[i].realpart 
          << std::setw(20) << normEV[i] << endl;
      }  
      cout<<"-----------------------------------------------------------"<<endl;
    }
  }
  
#ifdef EPETRA_MPI
  MPI_Finalize() ;
#endif
  return 0;
  
} // end LOBPCGEpetraExFile.cpp
int main(int argc, char *argv[]) {
#if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_EPETRAEXT)
    typedef double Scalar;
    typedef int LocalOrdinal;
    typedef int GlobalOrdinal;
    typedef LocalOrdinal LO;
    typedef GlobalOrdinal GO;
    typedef Xpetra::EpetraNode Node;
#include "MueLu_UseShortNames.hpp"


    using Teuchos::RCP;
    using Teuchos::rcp;
    using Teuchos::rcpFromRef;
    using namespace MueLuTests;

    Teuchos::oblackholestream blackhole;
    Teuchos::GlobalMPISession mpiSession(&argc,&argv,&blackhole);

    bool success = false;
    bool verbose = true;
    try {
        RCP<const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
        RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
        out->setOutputToRootOnly(0);
        *out << MueLu::MemUtils::PrintMemoryUsage() << std::endl;

        // Timing
        Teuchos::Time myTime("global");
        Teuchos::TimeMonitor MM(myTime);

        // read in some command line parameters
        Teuchos::CommandLineProcessor clp(false);

        int rebalanceBlocks = 1;
        clp.setOption("rebalanceBlocks",       &rebalanceBlocks,     "rebalance blocks (1=yes, else=no)");

        switch (clp.parse(argc,argv)) {
        case Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED:
            return EXIT_SUCCESS;
            break;
        case Teuchos::CommandLineProcessor::PARSE_ERROR:
        case Teuchos::CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION:
            return EXIT_FAILURE;
            break;
        case Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL:
            break;
        }


#if defined(HAVE_MPI) && defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MUELU_ISORROPIA)
#ifndef HAVE_XPETRA_INT_LONG_LONG
        *out << "Warning: scaling test was not compiled with long long int support" << std::endl;


        // custom parameters
        LocalOrdinal maxLevels = 3;

        GlobalOrdinal maxCoarseSize=1; //FIXME clp doesn't like long long int

        int globalNumDofs = 1500;  // used for the maps
        int nDofsPerNode = 3;      // used for generating the fine level null-space

        // build strided maps
        // striding information: 2 velocity dofs and 1 pressure dof = 3 dofs per node
        std::vector<size_t> stridingInfo;
        stridingInfo.push_back(2);
        stridingInfo.push_back(1);

        /////////////////////////////////////// build strided maps
        // build strided maps:
        // xstridedfullmap: full map (velocity and pressure dof gids), continous
        // xstridedvelmap: only velocity dof gid maps (i.e. 0,1,3,4,6,7...)
        // xstridedpremap: only pressure dof gid maps (i.e. 2,5,8,...)
        Xpetra::UnderlyingLib lib = Xpetra::UseEpetra;
        RCP<const StridedMap> xstridedfullmap = StridedMapFactory::Build(lib,globalNumDofs,0,stridingInfo,comm,-1);
        RCP<const StridedMap> xstridedvelmap  = StridedMapFactory::Build(xstridedfullmap,0);
        RCP<const StridedMap> xstridedpremap  = StridedMapFactory::Build(xstridedfullmap,1);

        /////////////////////////////////////// transform Xpetra::Map objects to Epetra
        // this is needed for AztecOO
        const RCP<const Epetra_Map> fullmap = rcpFromRef(Xpetra::toEpetra(*xstridedfullmap));
        RCP<const Epetra_Map>       velmap  = rcpFromRef(Xpetra::toEpetra(*xstridedvelmap));
        RCP<const Epetra_Map>       premap  = rcpFromRef(Xpetra::toEpetra(*xstridedpremap));

        /////////////////////////////////////// import problem matrix and RHS from files (-> Epetra)

        // read in problem
        Epetra_CrsMatrix * ptrA = 0;
        Epetra_Vector * ptrf = 0;
        Epetra_MultiVector* ptrNS = 0;

        *out << "Reading matrix market file" << std::endl;

        EpetraExt::MatrixMarketFileToCrsMatrix("A_re1000_5932.txt",*fullmap,*fullmap,*fullmap,ptrA);
        EpetraExt::MatrixMarketFileToVector("b_re1000_5932.txt",*fullmap,ptrf);
        //EpetraExt::MatrixMarketFileToCrsMatrix("/home/tobias/promotion/trilinos/fc17-dyn/packages/muelu/test/navierstokes/A_re1000_5932.txt",*fullmap,*fullmap,*fullmap,ptrA);
        //EpetraExt::MatrixMarketFileToVector("/home/tobias/promotion/trilinos/fc17-dyn/packages/muelu/test/navierstokes/b_re1000_5932.txt",*fullmap,ptrf);

        RCP<Epetra_CrsMatrix> epA = Teuchos::rcp(ptrA);
        RCP<Epetra_Vector> epv = Teuchos::rcp(ptrf);
        RCP<Epetra_MultiVector> epNS = Teuchos::rcp(ptrNS);


        /////////////////////////////////////// split system into 2x2 block system

        *out << "Split matrix into 2x2 block matrix" << std::endl;

        // split fullA into A11,..., A22
        Teuchos::RCP<Epetra_CrsMatrix> A11;
        Teuchos::RCP<Epetra_CrsMatrix> A12;
        Teuchos::RCP<Epetra_CrsMatrix> A21;
        Teuchos::RCP<Epetra_CrsMatrix> A22;

        if(SplitMatrix2x2(epA,*velmap,*premap,A11,A12,A21,A22)==false)
            *out << "Problem with splitting matrix"<< std::endl;

        /////////////////////////////////////// transform Epetra objects to Xpetra (needed for MueLu)

        // build Xpetra objects from Epetra_CrsMatrix objects
        Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > xA11 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node>(A11));
        Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > xA12 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node>(A12));
        Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > xA21 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node>(A21));
        Teuchos::RCP<Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > xA22 = Teuchos::rcp(new Xpetra::EpetraCrsMatrixT<GlobalOrdinal,Node>(A22));

        /////////////////////////////////////// generate MapExtractor object

        std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > > xmaps;
        xmaps.push_back(xstridedvelmap);
        xmaps.push_back(xstridedpremap);

        Teuchos::RCP<const Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node> > map_extractor = Xpetra::MapExtractorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(xstridedfullmap,xmaps);

        /////////////////////////////////////// build blocked transfer operator
        // using the map extractor
        Teuchos::RCP<Xpetra::BlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > bOp = Teuchos::rcp(new Xpetra::BlockedCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>(map_extractor,map_extractor,10));
        bOp->setMatrix(0,0,Teuchos::rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xA11)));
        bOp->setMatrix(0,1,Teuchos::rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xA12)));
        bOp->setMatrix(1,0,Teuchos::rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xA21)));
        bOp->setMatrix(1,1,Teuchos::rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xA22)));

        bOp->fillComplete();

        //////////////////////////////////////////////////// create Hierarchy
        RCP<Hierarchy> H = rcp ( new Hierarchy() );
        H->setDefaultVerbLevel(Teuchos::VERB_HIGH);
        //H->setDefaultVerbLevel(Teuchos::VERB_NONE);
        H->SetMaxCoarseSize(maxCoarseSize);

        //////////////////////////////////////////////////////// finest Level
        RCP<MueLu::Level> Finest = H->GetLevel();
        Finest->setDefaultVerbLevel(Teuchos::VERB_HIGH);
        Finest->Set("A",Teuchos::rcp_dynamic_cast<Matrix>(bOp));


        ////////////////////////////////////////// prepare null space for A11
        RCP<MultiVector> nullspace11 = MultiVectorFactory::Build(xstridedvelmap, 2);  // this is a 2D standard null space

        for (int i=0; i<nDofsPerNode-1; ++i) {
            Teuchos::ArrayRCP<Scalar> nsValues = nullspace11->getDataNonConst(i);
            int numBlocks = nsValues.size() / (nDofsPerNode - 1);
            for (int j=0; j< numBlocks; ++j) {
                nsValues[j*(nDofsPerNode - 1) + i] = 1.0;
            }
        }

        Finest->Set("Nullspace1",nullspace11);

        ////////////////////////////////////////// prepare null space for A22
        RCP<MultiVector> nullspace22 = MultiVectorFactory::Build(xstridedpremap, 1);  // this is a 2D standard null space
        Teuchos::ArrayRCP<Scalar> nsValues22 = nullspace22->getDataNonConst(0);
        for (int j=0; j< nsValues22.size(); ++j) {
            nsValues22[j] = 1.0;
        }

        Finest->Set("Nullspace2",nullspace22);


        /////////////////////////////////////////// define rebalanced block AC factory
        // This is the main factory for "A" and defines the input for
        //   - the SubBlockAFactory objects
        //   - the rebalanced block Ac factory
        RCP<RebalanceBlockAcFactory> RebalancedAcFact = rcp(new RebalanceBlockAcFactory());

        /////////////////////////////////////////// define non-rebalanced blocked transfer ops
        RCP<BlockedPFactory> PFact = rcp(new BlockedPFactory()); // use row map index base from bOp
        RCP<GenericRFactory> RFact = rcp(new GenericRFactory());
        RFact->SetFactory("P", PFact);

        // non-rebalanced block coarse matrix factory
        // output is non-rebalanced coarse block matrix Ac
        // used as input for rebalanced block coarse factory RebalancedAcFact
        RCP<Factory> AcFact = rcp(new BlockedRAPFactory());
        AcFact->SetFactory("A", MueLu::NoFactory::getRCP());
        AcFact->SetFactory("P", PFact);  // use non-rebalanced block prolongator as input
        AcFact->SetFactory("R", RFact);  // use non-rebalanced block restrictor as input

        // Repartitioning (decides how many partitions are built)
        RCP<Factory> RepartitionHeuristicFact = rcp(new RepartitionHeuristicFactory());
        {
            Teuchos::ParameterList paramList;
            paramList.set("repartition: min rows per proc", 200);
            paramList.set("repartition: max imbalance", 1.3);
            if(rebalanceBlocks == 1)
                paramList.set("repartition: start level",1);
            else
                paramList.set("repartition: start level",10); // supress rebalancing
            RepartitionHeuristicFact->SetParameterList(paramList);
        }
        RepartitionHeuristicFact->SetFactory("A", AcFact);


        // define matrix sub-blocks of possibly rebalanced block matrix A
        // These are used as input for
        //   - the sub blocks of the transfer operators
        RCP<SubBlockAFactory> A11Fact = Teuchos::rcp(new SubBlockAFactory());
        A11Fact->SetFactory("A",MueLu::NoFactory::getRCP());
        A11Fact->SetParameter("block row",Teuchos::ParameterEntry(0));
        A11Fact->SetParameter("block col",Teuchos::ParameterEntry(0));
        RCP<SubBlockAFactory> A22Fact = Teuchos::rcp(new SubBlockAFactory());
        A22Fact->SetFactory("A",MueLu::NoFactory::getRCP());
        A22Fact->SetParameter("block row",Teuchos::ParameterEntry(1));
        A22Fact->SetParameter("block col",Teuchos::ParameterEntry(1));

        /////////////////////////////////////////// define rebalancing factories
        // define sub blocks of the coarse non-rebalanced block matrix Ac
        // input is the block operator generated by AcFact
        RCP<SubBlockAFactory> rebA11Fact = Teuchos::rcp(new SubBlockAFactory());
        rebA11Fact->SetFactory("A",AcFact);
        rebA11Fact->SetParameter("block row",Teuchos::ParameterEntry(0));
        rebA11Fact->SetParameter("block col",Teuchos::ParameterEntry(0));
        RCP<SubBlockAFactory> rebA22Fact = Teuchos::rcp(new SubBlockAFactory());
        rebA22Fact->SetFactory("A",AcFact);
        rebA22Fact->SetParameter("block row",Teuchos::ParameterEntry(1));
        rebA22Fact->SetParameter("block col",Teuchos::ParameterEntry(1));

        // define rebalancing factory for coarse block matrix A(1,1)
        RCP<AmalgamationFactory> rebAmalgFact11 = rcp(new AmalgamationFactory());
        rebAmalgFact11->SetFactory("A", rebA11Fact);
        rebAmalgFact11->setDefaultVerbLevel(Teuchos::VERB_EXTREME);

        RCP<MueLu::IsorropiaInterface<LO, GO, NO> > isoInterface1 = rcp(new MueLu::IsorropiaInterface<LO, GO, NO>());
        isoInterface1->SetFactory("A", rebA11Fact);
        isoInterface1->SetFactory("number of partitions", RepartitionHeuristicFact);
        isoInterface1->SetFactory("UnAmalgamationInfo", rebAmalgFact11);

        RCP<MueLu::RepartitionInterface<LO, GO, NO> > repInterface1 = rcp(new MueLu::RepartitionInterface<LO, GO, NO>());
        repInterface1->SetFactory("A", rebA11Fact);
        repInterface1->SetFactory("number of partitions", RepartitionHeuristicFact);
        repInterface1->SetFactory("AmalgamatedPartition", isoInterface1);

        // Repartitioning (creates "Importer" from "Partition")
        RCP<Factory> RepartitionFact = rcp(new RepartitionFactory());
        RepartitionFact->SetFactory("A", rebA11Fact);
        RepartitionFact->SetFactory("number of partitions", RepartitionHeuristicFact);
        RepartitionFact->SetFactory("Partition", repInterface1);

        // define rebalancing factory for coarse block matrix A(1,1)
        RCP<AmalgamationFactory> rebAmalgFact22 = rcp(new AmalgamationFactory());
        rebAmalgFact22->SetFactory("A", rebA22Fact);
        rebAmalgFact22->setDefaultVerbLevel(Teuchos::VERB_EXTREME);

        RCP<MueLu::RepartitionInterface<LO, GO, NO> > repInterface2 = rcp(new MueLu::RepartitionInterface<LO, GO, NO>());
        repInterface2->SetFactory("A", rebA22Fact);
        repInterface2->SetFactory("number of partitions", RepartitionHeuristicFact);
        repInterface2->SetFactory("AmalgamatedPartition", isoInterface1);

        // second repartition factory
        RCP<Factory> RepartitionFact2 = rcp(new RepartitionFactory());
        RepartitionFact2->SetFactory("A", rebA22Fact);
        RepartitionFact2->SetFactory("number of partitions", RepartitionHeuristicFact);
        RepartitionFact2->SetFactory("Partition", repInterface2); // this is not valid

        ////////////////////////////////////////// build non-rebalanced matrix blocks
        // build factories for transfer operator P(1,1) and R(1,1)
        RCP<AmalgamationFactory> amalgFact11 = rcp(new AmalgamationFactory());
        amalgFact11->SetFactory("A", A11Fact);
        amalgFact11->setDefaultVerbLevel(Teuchos::VERB_EXTREME);

        RCP<CoalesceDropFactory> dropFact11 = rcp(new CoalesceDropFactory());
        dropFact11->SetFactory("A", A11Fact);
        dropFact11->SetFactory("UnAmalgamationInfo", amalgFact11);
        dropFact11->setDefaultVerbLevel(Teuchos::VERB_EXTREME);

        RCP<UncoupledAggregationFactory> UncoupledAggFact11 = rcp(new UncoupledAggregationFactory());
        UncoupledAggFact11->SetFactory("Graph", dropFact11);
        UncoupledAggFact11->SetMinNodesPerAggregate(9);
        UncoupledAggFact11->SetMaxNeighAlreadySelected(2);
        UncoupledAggFact11->SetOrdering("natural");

        RCP<CoarseMapFactory> coarseMapFact11 = Teuchos::rcp(new CoarseMapFactory());
        coarseMapFact11->setStridingData(stridingInfo);
        coarseMapFact11->setStridedBlockId(0);

        RCP<TentativePFactory> P11Fact = rcp(new TentativePFactory());
        RCP<TransPFactory> R11Fact = rcp(new TransPFactory());

        Teuchos::RCP<NullspaceFactory> nspFact11 = Teuchos::rcp(new NullspaceFactory("Nullspace1"));
        nspFact11->SetFactory("Nullspace1",P11Fact); // pick "Nullspace1" from Finest level

        //////////////////////////////// define factory manager for (1,1) block
        RCP<FactoryManager> M11 = rcp(new FactoryManager());
        M11->SetFactory("A", A11Fact);  // rebalanced fine-level block operator
        M11->SetFactory("P", P11Fact);  // non-rebalanced transfer operator block P(1,1)
        M11->SetFactory("R", R11Fact);  // non-rebalanced transfer operator block R(1,1)
        M11->SetFactory("Aggregates", UncoupledAggFact11);
        M11->SetFactory("Graph", dropFact11);
        M11->SetFactory("DofsPerNode", dropFact11);
        M11->SetFactory("UnAmalgamationInfo", amalgFact11);
        M11->SetFactory("Nullspace", nspFact11); // TODO check me?
        M11->SetFactory("CoarseMap", coarseMapFact11);
        M11->SetIgnoreUserData(true);               // always use data from factories defined in factory manager

        ////////////////////////////////////////// build non-rebalanced matrix blocks
        // build factories for transfer operator P(2,2) and R(2,2)
        RCP<AmalgamationFactory> amalgFact22 = rcp(new AmalgamationFactory());
        RCP<TentativePFactory> P22Fact = rcp(new TentativePFactory());
        RCP<TransPFactory> R22Fact = rcp(new TransPFactory());

        // connect null space and tentative PFactory
        Teuchos::RCP<NullspaceFactory> nspFact22 = Teuchos::rcp(new NullspaceFactory("Nullspace2"));
        nspFact22->SetFactory("Nullspace2", P22Fact); // define null space generated by P22Fact as null space for coarse level (non-rebalanced)

        RCP<CoarseMapFactory> coarseMapFact22 = Teuchos::rcp(new CoarseMapFactory());
        coarseMapFact22->setStridingData(stridingInfo);
        coarseMapFact22->setStridedBlockId(1);

        //////////////////////////////// define factory manager for (2,2) block
        RCP<FactoryManager> M22 = rcp(new FactoryManager());
        M22->SetFactory("A", A22Fact); // rebalanced fine-level block operator
        M22->SetFactory("P", P22Fact); // non-rebalanced transfer operator P(2,2)
        M22->SetFactory("R", R22Fact); // non-rebalanced transfer operator R(2,2)
        M22->SetFactory("Aggregates", UncoupledAggFact11); // aggregates from block (1,1)
        M22->SetFactory("Nullspace", nspFact22);
        M22->SetFactory("UnAmalgamationInfo", amalgFact22);
        M22->SetFactory("Ptent", P22Fact);
        M22->SetFactory("CoarseMap", coarseMapFact22);
        M22->SetIgnoreUserData(true);

        /////////////////////////////////////////// define rebalanced blocked transfer ops
        //////////////////////////////// define factory manager for (1,1) block
        RCP<FactoryManager> rebM11 = rcp(new FactoryManager());
        rebM11->SetFactory("A", AcFact ); // important: must be a 2x2 block A Factory
        rebM11->SetFactory("Importer", RepartitionFact);
        rebM11->SetFactory("Nullspace", nspFact11);
        //rebM11->SetIgnoreUserData(true);

        RCP<FactoryManager> rebM22 = rcp(new FactoryManager());
        rebM22->SetFactory("A", AcFact ); // important: must be a 2x2 block A Factory
        rebM22->SetFactory("Importer", RepartitionFact2); // use dummy repartitioning factory
        rebM22->SetFactory("Nullspace", nspFact22);

        // Reordering of the transfer operators
        RCP<RebalanceBlockInterpolationFactory> RebalancedBlockPFact = rcp(new RebalanceBlockInterpolationFactory());
        RebalancedBlockPFact->SetFactory("P", PFact); // use non-rebalanced block P operator as input
        RebalancedBlockPFact->AddFactoryManager(rebM11);
        RebalancedBlockPFact->AddFactoryManager(rebM22);

        RCP<RebalanceBlockRestrictionFactory> RebalancedBlockRFact = rcp(new RebalanceBlockRestrictionFactory());
        //RebalancedBlockRFact->SetParameter("type", Teuchos::ParameterEntry(std::string("Restriction")));
        RebalancedBlockRFact->SetFactory("R", RFact); // non-rebalanced block P operator
        RebalancedBlockRFact->AddFactoryManager(rebM11);
        RebalancedBlockRFact->AddFactoryManager(rebM22);

        ///////////////////////////////////////// initialize non-rebalanced block transfer operators
        // output are the non-rebalanced block transfer operators used as input in AcFact to build
        // the non-rebalanced coarse level block matrix Ac
        PFact->AddFactoryManager(M11);  // use non-rebalanced information from sub block factory manager M11
        PFact->AddFactoryManager(M22);  // use non-rebalanced information from sub block factory manager M22

        ///////////////////////////////////////// initialize rebalanced coarse block AC factory
        RebalancedAcFact->SetFactory("A", AcFact);   // use non-rebalanced block operator as input
        RebalancedAcFact->AddFactoryManager(rebM11);
        RebalancedAcFact->AddFactoryManager(rebM22);

        //////////////////////////////////////////////////////////////////////
        // Smoothers

        //Another factory manager for braes sarazin smoother
        //Schur Complement Factory, using the factory to generate AcFact
        SC omega = 1.3;
        RCP<SchurComplementFactory> SFact = Teuchos::rcp(new SchurComplementFactory());
        SFact->SetParameter("omega", Teuchos::ParameterEntry(omega));
        SFact->SetFactory("A", MueLu::NoFactory::getRCP()); // this finally be the rebalanced block operator!

        //Smoother Factory, using SFact as a factory for A
        std::string ifpackSCType;
        Teuchos::ParameterList ifpackSCList;
        ifpackSCList.set("relaxation: sweeps", (LocalOrdinal) 3);
        ifpackSCList.set("relaxation: damping factor", (Scalar) 1.0);
        ifpackSCType = "RELAXATION";
        ifpackSCList.set("relaxation: type", "Gauss-Seidel");
        RCP<SmootherPrototype> smoProtoSC     = rcp( new TrilinosSmoother(ifpackSCType, ifpackSCList, 0) );
        smoProtoSC->SetFactory("A", SFact);
        RCP<SmootherFactory> SmooSCFact = rcp( new SmootherFactory(smoProtoSC) );

        RCP<BraessSarazinSmoother> smootherPrototype     = rcp( new BraessSarazinSmoother() );
        smootherPrototype->SetParameter("Sweeps", Teuchos::ParameterEntry(3));
        smootherPrototype->SetParameter("Damping factor", Teuchos::ParameterEntry(omega));
        smootherPrototype->SetFactory("A",MueLu::NoFactory::getRCP());
        RCP<SmootherFactory>   smootherFact          = rcp( new SmootherFactory(smootherPrototype) );

        RCP<BraessSarazinSmoother> coarseSolverPrototype = rcp( new BraessSarazinSmoother() );
        coarseSolverPrototype->SetParameter("Sweeps", Teuchos::ParameterEntry(3));
        coarseSolverPrototype->SetParameter("Damping factor", Teuchos::ParameterEntry(omega));
        coarseSolverPrototype->SetFactory("A",MueLu::NoFactory::getRCP());
        RCP<SmootherFactory>   coarseSolverFact      = rcp( new SmootherFactory(coarseSolverPrototype, Teuchos::null) );

        RCP<FactoryManager> MB = rcp(new FactoryManager());
        MB->SetFactory("A",     SFact);
        MB->SetFactory("Smoother",    SmooSCFact);
        MB->SetIgnoreUserData(true);               // always use data from factories defined in factory manager
        smootherPrototype->AddFactoryManager(MB,0);
        coarseSolverPrototype->AddFactoryManager(MB,0);


        ////////////////////////////////////////// define main factory manager
        FactoryManager M;
        M.SetFactory("A",            RebalancedAcFact);     // rebalance block AC Factory using importer
        M.SetFactory("P",            RebalancedBlockPFact); // rebalance prolongator using non-balanced Ac
        M.SetFactory("R",            RebalancedBlockRFact); // rebalance restrictor and null space using non-balanced Ac
        M.SetFactory("Smoother",     smootherFact);
        M.SetFactory("PreSmoother",     smootherFact);
        M.SetFactory("PostSmoother",     smootherFact);
        M.SetFactory("CoarseSolver", coarseSolverFact);

        H->Setup(M,0,maxLevels);

        /**out << std::endl;
         *out << "print content of multigrid levels:" << std::endl;

         Finest->print(*out);

         RCP<Level> coarseLevel = H->GetLevel(1);
         coarseLevel->print(*out);

         RCP<Level> coarseLevel2 = H->GetLevel(2);
         coarseLevel2->print(*out);*/

        RCP<MultiVector> xLsg = MultiVectorFactory::Build(xstridedfullmap,1);

        // Use AMG directly as an iterative method
#if 0
        {
            xLsg->putScalar( (SC) 0.0);

            // Epetra_Vector -> Xpetra::Vector
            RCP<Vector> xRhs = Teuchos::rcp(new Xpetra::EpetraVector(epv));

            // calculate initial (absolute) residual
            Teuchos::Array<Teuchos::ScalarTraits<SC>::magnitudeType> norms(1);
            xRhs->norm2(norms);
            *out << "||x_0|| = " << norms[0] << std::endl;

            // apply ten multigrid iterations
            H->Iterate(*xRhs,*xLsg,100);


            // calculate and print residual
            RCP<MultiVector> xTmp = MultiVectorFactory::Build(xstridedfullmap,1);
            bOp->apply(*xLsg,*xTmp,Teuchos::NO_TRANS,(SC)1.0,(SC)0.0);
            xRhs->update((SC)-1.0,*xTmp,(SC)1.0);
            xRhs->norm2(norms);
            *out << "||x|| = " << norms[0] << std::endl;
        }
#endif

        //
        // Solve Ax = b using AMG as a preconditioner in AztecOO
        //
        {
            RCP<Epetra_Vector> X = rcp(new Epetra_Vector(epv->Map()));
            X->PutScalar(0.0);
            Epetra_LinearProblem epetraProblem(epA.get(), X.get(), epv.get());

            AztecOO aztecSolver(epetraProblem);
            aztecSolver.SetAztecOption(AZ_solver, AZ_gmres);

            MueLu::EpetraOperator aztecPrec(H);
            aztecSolver.SetPrecOperator(&aztecPrec);

            int maxIts = 50;
            double tol = 1e-8;

            aztecSolver.Iterate(maxIts, tol);
        }

#endif // end ifndef HAVE_LONG_LONG_INT
#endif // #if defined(HAVE_MPI) && defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MUELU_ISORROPIA)
        success = true;
    }
    TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

    return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
#else
    std::cout << "Epetra (and/or EpetraExt) are not available. Skip test." << std::endl;
    return EXIT_SUCCESS;
#endif
}
Teuchos::ParameterList Ifpack_GetValidParameters()
{
  Teuchos::ParameterList List; // empty list

  // ============================================================ //
  // Parameters are reported from each used file in IFPACK. Files //
  // are listed in alphabetical order, first all *.cpp, then *.h. //
  // Some options not very tested or documented anywhere          //
  // are not reported here.                                       //
  // ============================================================ //
  
  // Ifpack_Amesos.cpp
  List.set("amesos: solver type", "Amesos_Klu");

  // Ifpack_IC.cpp
  List.set("fact: level-of-fill", (int)1);
  List.set("fact: absolute threshold", (double)0.0);
  List.set("fact: relative threshold", (double)0.0);
  List.set("fact: drop tolerance", (double)0.0);

  // Ifpack_ICT.cpp
  List.set("fact: ict level-of-fill", (double)1.0);
  List.set("fact: absolute threshold", (double)0.0);
  List.set("fact: relative threshold", (double)1.0);
  List.set("fact: relax value", (double)0.0);
  List.set("fact: drop tolerance", (double)0.0);

  // Ifpack_ILU.cpp
  List.set("fact: level-of-fill", (int)0);
  List.set("fact: absolute threshold", (double)0.0);
  List.set("fact: relative threshold", (double)1.0);
  List.set("fact: relax value", (double)0.0);

  // Ifpack_ILUT.cpp
  List.set("fact: ilut level-of-fill", (double)1.0);
  List.set("fact: absolute threshold", (double)0.0);
  List.set("fact: relative threshold", (double)1.0);
  List.set("fact: relax value", (double)0.0);

#ifdef HAVE_IFPACK_SUPERLU
  // Ifpack_SILU.cpp
  List.set("fact: drop tolerance",1e-4);
  List.set("fact: zero pivot threshold",1e-2);
  List.set("fact: maximum fill factor",10.0);
  List.set("fact: silu drop rule",9);
#endif

  // Ifpack_METISPartitioner.cpp
  List.set("partitioner: local parts", (int)1);
  List.set("partitioner: overlap", (int)0);
  List.set("partitioner: print level", (int)0);

  // Ifpack_PointRelaxation.cpp
  List.set("relaxation: type", "Jacobi");
  List.set("relaxation: sweeps", (int)1);
  List.set("relaxation: damping factor", (double)1.0);
  List.set("relaxation: min diagonal value", (double)1.0);
  List.set("relaxation: zero starting solution", true);
  List.set("relaxation: backward mode",false);
  List.set("relaxation: use l1",false);
  List.set("relaxation: l1 eta",(double)1.5);

  // Ifpack_SPARSKIT.cpp
  List.set("fact: sparskit: lfil", (int)0);
  List.set("fact: sparskit: tol", (double)0.0);
  List.set("fact: sparskit: droptol", (double)0.0);
  List.set("fact: sparskit: permtol", (double)0.1);
  List.set("fact: sparskit: alph", (double)0.0);
  List.set("fact: sparskit: mbloc", (int)(-1));
  List.set("fact: sparskit: type", ("ILUT"));

  // Additive Schwarz preconditioner
  List.set("schwarz: compute condest", true);
  List.set("schwarz: combine mode", "Zero"); // use string mode for this
  List.set("schwarz: reordering type", "none");
  List.set("schwarz: filter singletons", false);

  // Ifpack_BlockRelaxation.h
  // List.set("relaxation: type", "Jacobi"); // already set
  // List.set("relaxation: sweeps", 1); // already set
  // List.get("relaxation: damping factor", 1.0); // already set
  // List.get("relaxation: zero starting solution", true); // already set
  List.set("partitioner: type", "greedy");
  List.set("partitioner: local parts", (int)1);
  List.set("partitioner: overlap", (int)0);

  // Ifpack_METISPartitioner.h
  List.set("partitioner: use symmetric graph", true);

  // Krylov smoother
  List.set("krylov: iterations",(int)5);
  List.set("krylov: tolerance",(double)0.001);
  List.set("krylov: solver",(int)1);
  List.set("krylov: preconditioner",(int)0);
  List.set("krylov: number of sweeps",(int)1);
  List.set("krylov: block size",(int)1);
  List.set("krylov: damping parameter",(double)1.0);
  List.set("krylov: zero starting solution",true);

  return(List);
}
Exemple #23
0
int main(int argc, char *argv[]) {
  int n = 32;                        // spatial discretization (per dimension)
  int num_KL = 2;                    // number of KL terms
  int p = 3;                         // polynomial order
  double mu = 0.1;                   // mean of exponential random field
  double s = 0.2;                    // std. dev. of exponential r.f.
  bool nonlinear_expansion = false;  // nonlinear expansion of diffusion coeff
                                     // (e.g., log-normal)
  bool matrix_free = true;           // use matrix-free stochastic operator
  bool symmetric = false;            // use symmetric formulation

  double g_mean_exp = 0.172988;      // expected response mean
  double g_std_dev_exp = 0.0380007;  // expected response std. dev.
  double g_tol = 1e-6;               // tolerance on determining success

// Initialize MPI
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  int MyPID;

  try {

    {
    TEUCHOS_FUNC_TIME_MONITOR("Total PCE Calculation Time");

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();
    
    // Create Stochastic Galerkin basis and expansion
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(num_KL); 
    for (int i=0; i<num_KL; i++)
      bases[i] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p, true));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    if (nonlinear_expansion)
      Cijk = basis->computeTripleProductTensor();
    else
      Cijk = basis->computeLinearTripleProductTensor();
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    if (argc > 1)
      num_spatial_procs = std::atoi(argv[1]);
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();

    // Create application
    Teuchos::RCP<twoD_diffusion_ME> model =
      Teuchos::rcp(new twoD_diffusion_ME(app_comm, n, num_KL, mu, s, basis, 
					 nonlinear_expansion, symmetric));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    Teuchos::ParameterList& sgOpParams = 
      sgParams->sublist("SG Operator");
    Teuchos::ParameterList& sgPrecParams = 
      sgParams->sublist("SG Preconditioner");
    if (!nonlinear_expansion) {
      sgParams->set("Parameter Expansion Type", "Linear");
      sgParams->set("Jacobian Expansion Type", "Linear");
    }
    if (matrix_free) {
      sgOpParams.set("Operator Method", "Matrix Free");
      sgPrecParams.set("Preconditioner Method", "Approximate Gauss-Seidel");
      sgPrecParams.set("Symmetric Gauss-Seidel", symmetric);
      sgPrecParams.set("Mean Preconditioner Type", "ML");
      Teuchos::ParameterList& precParams = 
      	sgPrecParams.sublist("Mean Preconditioner Parameters");
      precParams.set("default values", "SA");
      precParams.set("ML output", 0);
      precParams.set("max levels",5);
      precParams.set("increasing or decreasing","increasing");
      precParams.set("aggregation: type", "Uncoupled");
      precParams.set("smoother: type","ML symmetric Gauss-Seidel");
      precParams.set("smoother: sweeps",2);
      precParams.set("smoother: pre or post", "both");
      precParams.set("coarse: max size", 200);
#ifdef HAVE_ML_AMESOS
      precParams.set("coarse: type","Amesos-KLU");
#else
      precParams.set("coarse: type","Jacobi");
#endif
    }
    else {
      sgOpParams.set("Operator Method", "Fully Assembled");
      sgPrecParams.set("Preconditioner Method", "None");
    }

   // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
                                                 expansion, sg_parallel_data, 
						 sgParams));

    // Set up stochastic parameters
    // The current implementation of the model doesn't actually use these 
    // values, but is hard-coded to certain uncertainty models
    Teuchos::Array<double> point(num_KL, 1.0);
    Teuchos::Array<double> basis_vals(sz);
    basis->evaluateBases(point, basis_vals);
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_p_init =
      sg_model->create_p_sg(0);
    for (int i=0; i<num_KL; i++) {
      sg_p_init->term(i,0)[i] = 0.0;
      sg_p_init->term(i,1)[i] = 1.0 / basis_vals[i+1];
    }
    sg_model->set_p_sg_init(0, *sg_p_init);

    // Setup stochastic initial guess
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_init = 
      sg_model->create_x_sg();
    sg_x_init->init(0.0);
    sg_model->set_x_sg_init(*sg_x_init);

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams = 
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = noxParams->sublist("Printing");
    printParams.set("MyPID", MyPID); 
    printParams.set("Output Precision", 3);
    printParams.set("Output Processor", 0);
    printParams.set("Output Information", 
                    NOX::Utils::OuterIteration + 
                    NOX::Utils::OuterIterationStatusTest + 
                    NOX::Utils::InnerIteration +
                    NOX::Utils::LinearSolverDetails +
                    NOX::Utils::Warning + 
                    NOX::Utils::Error);

    // Create printing utilities
    NOX::Utils utils(printParams);

    // Sublist for line search 
    Teuchos::ParameterList& searchParams = noxParams->sublist("Line Search");
    searchParams.set("Method", "Full Step");

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->sublist("Direction");
    dirParams.set("Method", "Newton");
    Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
    if (symmetric)
      lsParams.set("Aztec Solver", "CG");
    else
      lsParams.set("Aztec Solver", "GMRES");
    lsParams.set("Max Iterations", 1000);
    lsParams.set("Size of Krylov Subspace", 100);
    lsParams.set("Tolerance", 1e-12); 
    lsParams.set("Output Frequency", 1);
    if (matrix_free)
      lsParams.set("Preconditioner", "User Defined");
    else {
      lsParams.set("Preconditioner", "ML");
      Teuchos::ParameterList& precParams = 
	lsParams.sublist("ML");
      ML_Epetra::SetDefaults("DD", precParams);
      lsParams.set("Write Linear System", false);
    }

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", 1e-10);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 1);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys;
    if (matrix_free) {
      Teuchos::RCP<Epetra_Operator> M = sg_model->create_WPrec()->PrecOp;
      Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = nox_interface;
      linsys = 
	Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							  iJac, A, iPrec, M,
							  *u));
    }
    else {
      linsys = 
	Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
							  iReq, iJac, A, 
							  *u));
    }

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));

    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver = 
      NOX::Solver::buildSolver(grp, statusTests, noxParams);

    // Solve the system
    NOX::StatusTest::StatusType status = solver->solve();

    // Get final solution
    const NOX::Epetra::Group& finalGroup = 
      dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
    const Epetra_Vector& finalSolution = 
      (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector();

    // Save final solution to file
    EpetraExt::VectorToMatrixMarketFile("nox_stochastic_solution.mm", 
					finalSolution);

    // Save mean and variance to file
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_x_poly = 
      sg_model->create_x_sg(View, &finalSolution);
    Epetra_Vector mean(*(model->get_x_map()));
    Epetra_Vector std_dev(*(model->get_x_map()));
    sg_x_poly->computeMean(mean);
    sg_x_poly->computeStandardDeviation(std_dev);
    EpetraExt::VectorToMatrixMarketFile("mean_gal.mm", mean);
    EpetraExt::VectorToMatrixMarketFile("std_dev_gal.mm", std_dev);
      
    // Evaluate SG responses at SG parameters
    EpetraExt::ModelEvaluator::InArgs sg_inArgs = sg_model->createInArgs();
    EpetraExt::ModelEvaluator::OutArgs sg_outArgs = 
      sg_model->createOutArgs();
    Teuchos::RCP<const Epetra_Vector> sg_p = sg_model->get_p_init(1);
    Teuchos::RCP<Epetra_Vector> sg_g = 
      Teuchos::rcp(new Epetra_Vector(*(sg_model->get_g_map(0))));
    sg_inArgs.set_p(1, sg_p);
    sg_inArgs.set_x(Teuchos::rcp(&finalSolution,false));
    sg_outArgs.set_g(0, sg_g);
    sg_model->evalModel(sg_inArgs, sg_outArgs);

    // Print mean and standard deviation of response
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> sg_g_poly =
      sg_model->create_g_sg(0, View, sg_g.get());
    Epetra_Vector g_mean(*(model->get_g_map(0)));
    Epetra_Vector g_std_dev(*(model->get_g_map(0)));
    sg_g_poly->computeMean(g_mean);
    sg_g_poly->computeStandardDeviation(g_std_dev);
    std::cout.precision(16);
    // std::cout << "\nResponse Expansion = " << std::endl;
    // std::cout.precision(12);
    // sg_g_poly->print(std::cout);
    std::cout << std::endl;
    std::cout << "Response Mean =      " << std::endl << g_mean << std::endl;
    std::cout << "Response Std. Dev. = " << std::endl << g_std_dev << std::endl;

    // Determine if example passed
    bool passed = false;
    if (status == NOX::StatusTest::Converged &&
	std::abs(g_mean[0]-g_mean_exp) < g_tol &&
	std::abs(g_std_dev[0]-g_std_dev_exp) < g_tol)
      passed = true;
    if (MyPID == 0) {
      if (passed)
	std::cout << "Example Passed!" << std::endl;
      else
	std::cout << "Example Failed!" << std::endl;
    }

    }

    Teuchos::TimeMonitor::summarize(std::cout);
    Teuchos::TimeMonitor::zeroOutTimers();

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
Exemple #24
0
int main(int argc, char *argv[]) {

// Initialize MPI
#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
#endif

  int MyPID;

  try {

    // Create a communicator for Epetra objects
    Teuchos::RCP<const Epetra_Comm> globalComm;
#ifdef HAVE_MPI
    globalComm = Teuchos::rcp(new Epetra_MpiComm(MPI_COMM_WORLD));
#else
    globalComm = Teuchos::rcp(new Epetra_SerialComm);
#endif
    MyPID = globalComm->MyPID();
    
    // Create Stochastic Galerkin basis and expansion
    int p = 5;
    Teuchos::Array< Teuchos::RCP<const Stokhos::OneDOrthogPolyBasis<int,double> > > bases(1); 
    bases[0] = Teuchos::rcp(new Stokhos::LegendreBasis<int,double>(p));
    Teuchos::RCP<const Stokhos::CompletePolynomialBasis<int,double> > basis = 
      Teuchos::rcp(new Stokhos::CompletePolynomialBasis<int,double>(bases));
    int sz = basis->size();
    Teuchos::RCP<Stokhos::Sparse3Tensor<int,double> > Cijk;
    Cijk = basis->computeTripleProductTensor(sz);
    Teuchos::RCP<Stokhos::OrthogPolyExpansion<int,double> > expansion = 
      Teuchos::rcp(new Stokhos::AlgebraicOrthogPolyExpansion<int,double>(basis,
									 Cijk));
    if (MyPID == 0)
      std::cout << "Stochastic Galerkin expansion size = " << sz << std::endl;

    // Create stochastic parallel distribution
    int num_spatial_procs = -1;
    Teuchos::ParameterList parallelParams;
    parallelParams.set("Number of Spatial Processors", num_spatial_procs);
    Teuchos::RCP<Stokhos::ParallelData> sg_parallel_data =
      Teuchos::rcp(new Stokhos::ParallelData(basis, Cijk, globalComm,
					     parallelParams));
    Teuchos::RCP<const EpetraExt::MultiComm> sg_comm = 
      sg_parallel_data->getMultiComm();
    Teuchos::RCP<const Epetra_Comm> app_comm = 
      sg_parallel_data->getSpatialComm();
    
    // Create application model evaluator
    Teuchos::RCP<EpetraExt::ModelEvaluator> model = 
      Teuchos::rcp(new SimpleME(app_comm));
    
    // Setup stochastic Galerkin algorithmic parameters
    Teuchos::RCP<Teuchos::ParameterList> sgParams = 
      Teuchos::rcp(new Teuchos::ParameterList);
    sgParams->set("Jacobian Method", "Matrix Free");
    sgParams->set("Mean Preconditioner Type", "Ifpack");

    // Create stochastic Galerkin model evaluator
    Teuchos::RCP<Stokhos::SGModelEvaluator> sg_model =
      Teuchos::rcp(new Stokhos::SGModelEvaluator(model, basis, Teuchos::null,
    						 expansion, sg_parallel_data, 
						 sgParams));

    // Stochastic Galerkin initial guess
    // Set the mean to the deterministic initial guess, higher-order terms
    // to zero
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> x_init_sg = 
      sg_model->create_x_sg();
    x_init_sg->init(0.0);
    (*x_init_sg)[0] = *(model->get_x_init());
    sg_model->set_x_sg_init(*x_init_sg);

    // Stochastic Galerkin parameters
    // Linear expansion with the mean given by the deterministic initial
    // parameter values, linear terms equal to 1, and higher order terms
    // equal to zero.
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> p_init_sg =
      sg_model->create_p_sg(0);
    p_init_sg->init(0.0);
    (*p_init_sg)[0] = *(model->get_p_init(0));
    for (int i=0; i<model->get_p_map(0)->NumMyElements(); i++)
      (*p_init_sg)[i+1][i] = 1.0;
    sg_model->set_p_sg_init(0, *p_init_sg);
    std::cout << "Stochatic Galerkin parameter expansion = " << std::endl
	      << *p_init_sg << std::endl;

    // Set up NOX parameters
    Teuchos::RCP<Teuchos::ParameterList> noxParams =
      Teuchos::rcp(new Teuchos::ParameterList);

    // Set the nonlinear solver method
    noxParams->set("Nonlinear Solver", "Line Search Based");

    // Set the printing parameters in the "Printing" sublist
    Teuchos::ParameterList& printParams = noxParams->sublist("Printing");
    printParams.set("MyPID", MyPID); 
    printParams.set("Output Precision", 3);
    printParams.set("Output Processor", 0);
    printParams.set("Output Information", 
                    NOX::Utils::OuterIteration + 
                    NOX::Utils::OuterIterationStatusTest + 
                    NOX::Utils::InnerIteration +
                    //NOX::Utils::Parameters + 
                    //NOX::Utils::Details + 
                    NOX::Utils::LinearSolverDetails +
                    NOX::Utils::Warning + 
                    NOX::Utils::Error);

    // Create printing utilities
    NOX::Utils utils(printParams);

    // Sublist for line search 
    Teuchos::ParameterList& searchParams = noxParams->sublist("Line Search");
    searchParams.set("Method", "Full Step");

    // Sublist for direction
    Teuchos::ParameterList& dirParams = noxParams->sublist("Direction");
    dirParams.set("Method", "Newton");
    Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton");
    newtonParams.set("Forcing Term Method", "Constant");

    // Sublist for linear solver for the Newton method
    Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver");
    lsParams.set("Aztec Solver", "GMRES");  
    lsParams.set("Max Iterations", 100);
    lsParams.set("Size of Krylov Subspace", 100);
    lsParams.set("Tolerance", 1e-4); 
    lsParams.set("Output Frequency", 10);
    lsParams.set("Preconditioner", "Ifpack");

    // Sublist for convergence tests
    Teuchos::ParameterList& statusParams = noxParams->sublist("Status Tests");
    statusParams.set("Test Type", "Combo");
    statusParams.set("Number of Tests", 2);
    statusParams.set("Combo Type", "OR");
    Teuchos::ParameterList& normF = statusParams.sublist("Test 0");
    normF.set("Test Type", "NormF");
    normF.set("Tolerance", 1e-10);
    normF.set("Scale Type", "Scaled");
    Teuchos::ParameterList& maxIters = statusParams.sublist("Test 1");
    maxIters.set("Test Type", "MaxIters");
    maxIters.set("Maximum Iterations", 10);

    // Create NOX interface
    Teuchos::RCP<NOX::Epetra::ModelEvaluatorInterface> nox_interface = 
       Teuchos::rcp(new NOX::Epetra::ModelEvaluatorInterface(sg_model));

    // Create NOX linear system object
    Teuchos::RCP<const Epetra_Vector> u = sg_model->get_x_init();
    Teuchos::RCP<Epetra_Operator> A = sg_model->create_W();
    Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = nox_interface;
    Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = nox_interface;
    Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linsys;
    Teuchos::RCP<Epetra_Operator> M = sg_model->create_WPrec()->PrecOp;
    Teuchos::RCP<NOX::Epetra::Interface::Preconditioner> iPrec = nox_interface;
    lsParams.set("Preconditioner", "User Defined");
    linsys = 
      Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
    							iJac, A, iPrec, M,
    							*u));
    // linsys = 
    //   Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams,
    // 							iReq, iJac, A, *u));

    // Build NOX group
    Teuchos::RCP<NOX::Epetra::Group> grp = 
      Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, *u, linsys));

    // Create the Solver convergence test
    Teuchos::RCP<NOX::StatusTest::Generic> statusTests =
      NOX::StatusTest::buildStatusTests(statusParams, utils);

    // Create the solver
    Teuchos::RCP<NOX::Solver::Generic> solver = 
      NOX::Solver::buildSolver(grp, statusTests, noxParams);

    // Solve the system
    NOX::StatusTest::StatusType status = solver->solve();

    // Get final solution
    const NOX::Epetra::Group& finalGroup = 
      dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup());
    const Epetra_Vector& finalSolution = 
      (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector();

    // Convert block Epetra_Vector to orthogonal polynomial of Epetra_Vector's
    Teuchos::RCP<Stokhos::EpetraVectorOrthogPoly> x_sg =
      sg_model->create_x_sg(View, &finalSolution);

    utils.out() << "Final Solution (block vector) = " << std::endl;
    std::cout << finalSolution << std::endl;
    utils.out() << "Final Solution (polynomial) = " << std::endl;
    std::cout << *x_sg << std::endl;

    if (status == NOX::StatusTest::Converged && MyPID == 0) 
      utils.out() << "Example Passed!" << std::endl;

  }
  
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }
  catch (string& s) {
    std::cout << s << std::endl;
  }
  catch (char *s) {
    std::cout << s << std::endl;
  }
  catch (...) {
    std::cout << "Caught unknown exception!" <<std:: endl;
  }

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

}
int main(int argc, char *argv[]) {
  using std::cout;
  using std::endl;
  int i;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  int MyPID = Comm.MyPID();

  // Number of dimension of the domain
  int space_dim = 2;

  // Size of each of the dimensions of the domain
  std::vector<double> brick_dim( space_dim );
  brick_dim[0] = 1.0;
  brick_dim[1] = 1.0;

  // Number of elements in each of the dimensions of the domain
  std::vector<int> elements( space_dim );
  elements[0] = 10;
  elements[1] = 10;

  // Create problem
  Teuchos::RCP<ModalProblem> testCase = Teuchos::rcp( new ModeLaplace2DQ2(Comm, brick_dim[0], elements[0], brick_dim[1], elements[1]) );

  // Get the stiffness and mass matrices
  Teuchos::RCP<Epetra_CrsMatrix> K = Teuchos::rcp( const_cast<Epetra_CrsMatrix *>(testCase->getStiffness()), false );
  Teuchos::RCP<Epetra_CrsMatrix> M = Teuchos::rcp( const_cast<Epetra_CrsMatrix *>(testCase->getMass()), false );

  //
  // ************Construct preconditioner*************
  //
  Teuchos::ParameterList ifpackList;

  // allocates an IFPACK factory. No data is associated
  // to this object (only method Create()).
  Ifpack Factory;

  // create the preconditioner. For valid PrecType values,
  // please check the documentation
  std::string PrecType = "ICT"; // incomplete Cholesky
  int OverlapLevel = 0; // must be >= 0. If Comm.NumProc() == 1,
                        // it is ignored.

  Teuchos::RCP<Ifpack_Preconditioner> Prec = Teuchos::rcp( Factory.Create(PrecType, &*K, OverlapLevel) );
  assert(Prec != Teuchos::null);

  // specify parameters for ICT
  ifpackList.set("fact: drop tolerance", 1e-4);
  ifpackList.set("fact: ict level-of-fill", 0.);
  // the combine mode is on the following:
  // "Add", "Zero", "Insert", "InsertAdd", "Average", "AbsMax"
  // Their meaning is as defined in file Epetra_CombineMode.h
  ifpackList.set("schwarz: combine mode", "Add");
  // sets the parameters
  IFPACK_CHK_ERR(Prec->SetParameters(ifpackList));

  // initialize the preconditioner. At this point the matrix must
  // have been FillComplete()'d, but actual values are ignored.
  IFPACK_CHK_ERR(Prec->Initialize());

  // Builds the preconditioners, by looking for the values of
  // the matrix.
  IFPACK_CHK_ERR(Prec->Compute());

  //
  //*******************************************************/
  // Set up Belos Block CG operator for inner iteration
  //*******************************************************/
  //
  int blockSize = 3; // block size used by linear solver and eigensolver [ not required to be the same ]
  int maxits = K->NumGlobalRows(); // maximum number of iterations to run
  //
  // Create the Belos::LinearProblem
  //
  Teuchos::RCP<Belos::LinearProblem<double,Epetra_MultiVector,Epetra_Operator> >
    My_LP = Teuchos::rcp( new Belos::LinearProblem<double,Epetra_MultiVector,Epetra_Operator>() );
  My_LP->setOperator( K );

  // Create the Belos preconditioned operator from the Ifpack preconditioner.
  // NOTE:  This is necessary because Belos expects an operator to apply the
  //        preconditioner with Apply() NOT ApplyInverse().
  Teuchos::RCP<Epetra_Operator> belosPrec = Teuchos::rcp( new Epetra_InvOperator( Prec.get() ) );
  My_LP->setLeftPrec( belosPrec );
  //
  // Create the ParameterList for the Belos Operator
  //
  Teuchos::RCP<Teuchos::ParameterList> My_List = Teuchos::rcp( new Teuchos::ParameterList() );
  My_List->set( "Solver", "BlockCG" );
  My_List->set( "Maximum Iterations", maxits );
  My_List->set( "Block Size", 1 );
  My_List->set( "Convergence Tolerance", 1e-12 );
  //
  // Create the Belos::EpetraOperator
  //
  Teuchos::RCP<Belos::EpetraOperator> BelosOp =
    Teuchos::rcp( new Belos::EpetraOperator( My_LP, My_List ));
  //
  // ************************************
  // Start the block Arnoldi iteration
  // ************************************
  //
  //  Variables used for the Block Arnoldi Method
  //
  double tol = 1.0e-8;
  int nev = 10;
  int numBlocks = 3*nev/blockSize;
  int maxRestarts = 5;
  //int step = 5;
  std::string which = "LM";
  int verbosity = Anasazi::Errors + Anasazi::Warnings + Anasazi::FinalSummary;
  //
  // Create parameter list to pass into solver
  //
  Teuchos::ParameterList MyPL;
  MyPL.set( "Verbosity", verbosity );
  MyPL.set( "Which", which );
  MyPL.set( "Block Size", blockSize );
  MyPL.set( "Num Blocks", numBlocks );
  MyPL.set( "Maximum Restarts", maxRestarts );
  MyPL.set( "Convergence Tolerance", tol );
  //MyPL.set( "Step Size", step );

  typedef Epetra_MultiVector MV;
  typedef Epetra_Operator OP;
  typedef Anasazi::MultiVecTraits<double, MV> MVT;
  typedef Anasazi::OperatorTraits<double, MV, OP> OPT;

  // Create an Epetra_MultiVector for an initial vector to start the solver.
  // Note:  This needs to have the same number of columns as the blocksize.
  Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(K->Map(), blockSize) );
  MVT::MvRandom( *ivec );

  // Call the ctor that calls the petra ctor for a matrix
  Teuchos::RCP<Anasazi::EpetraGenOp> Aop = Teuchos::rcp( new Anasazi::EpetraGenOp(BelosOp, M, false) );

  Teuchos::RCP<Anasazi::BasicEigenproblem<double,MV,OP> > MyProblem =
    Teuchos::rcp( new Anasazi::BasicEigenproblem<double,MV,OP>(Aop, M, ivec) );

  // Inform the eigenproblem that the matrix pencil (K,M) is symmetric
  MyProblem->setHermitian(true);

  // Set the number of eigenvalues requested
  MyProblem->setNEV( nev );

  // Inform the eigenproblem that you are finished passing it information
  bool boolret = MyProblem->setProblem();
  if (boolret != true) {
    if (MyPID == 0) {
      cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << endl;
    }
#ifdef HAVE_MPI
    MPI_Finalize() ;
#endif
    return -1;
  }

  // Initialize the Block Arnoldi solver
  Anasazi::BlockKrylovSchurSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL);

  // Solve the problem to the specified tolerances or length
  Anasazi::ReturnType returnCode = MySolverMgr.solve();
  if (returnCode != Anasazi::Converged && MyPID==0) {
    cout << "Anasazi::EigensolverMgr::solve() returned unconverged." << endl;
  }

  // Get the eigenvalues and eigenvectors from the eigenproblem
  Anasazi::Eigensolution<double,MV> sol = MyProblem->getSolution();
  std::vector<Anasazi::Value<double> > evals = sol.Evals;
  Teuchos::RCP<MV> evecs = sol.Evecs;
  int numev = sol.numVecs;

  if (numev > 0) {

    Teuchos::SerialDenseMatrix<int,double> dmatr(numev,numev);
    Epetra_MultiVector tempvec(K->Map(), MVT::GetNumberVecs( *evecs ));
    OPT::Apply( *K, *evecs, tempvec );
    MVT::MvTransMv( 1.0, tempvec, *evecs, dmatr );

    if (MyPID==0) {
      double compeval = 0.0;
      cout.setf(std::ios_base::right, std::ios_base::adjustfield);
      cout<<"Actual Eigenvalues (obtained by Rayleigh quotient) : "<<endl;
      cout<<"------------------------------------------------------"<<endl;
      cout<<std::setw(16)<<"Real Part"
        <<std::setw(16)<<"Rayleigh Error"<<endl;
      cout<<"------------------------------------------------------"<<endl;
      for (i=0; i<numev; i++) {
        compeval = dmatr(i,i);
        cout<<std::setw(16)<<compeval
          <<std::setw(16)<<Teuchos::ScalarTraits<double>::magnitude(compeval-1.0/evals[i].realpart)
          <<endl;
      }
      cout<<"------------------------------------------------------"<<endl;
    }

  }

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return 0;
}
int main(int argc, char *argv[]) {

  using Teuchos::RCP;

  Teuchos::GlobalMPISession mpiSession(&argc, &argv, NULL);
  RCP<const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();

  // Read the --linAlgebra option
  ::Xpetra::UnderlyingLib lib;
  {
    // Note: use --help to list available options.
    Teuchos::CommandLineProcessor clp(false);
    ::Xpetra::Parameters xpetraParameters(clp);

    switch (clp.parse(argc,argv)) {
    case Teuchos::CommandLineProcessor::PARSE_HELP_PRINTED:        return EXIT_SUCCESS; break;
    case Teuchos::CommandLineProcessor::PARSE_ERROR:
    case Teuchos::CommandLineProcessor::PARSE_UNRECOGNIZED_OPTION: return EXIT_FAILURE; break;
    case Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL:                               break;
    }
    if (comm->getRank() == 0) std::cout << xpetraParameters;

    lib = xpetraParameters.GetLib();
  }

  {
    // Creates an Xpetra::Map corresponding to a 2D Cartesian grid
    // on the unit square. For parallel runs, the nodes are divided into
    // strips, so that the total number of subdomains is comm->getSize() x 1.
    
    // Type of the object
    string mapType = "Cartesian2D";
    
    // Container for parameters
    Teuchos::ParameterList galeriList;
    galeriList.set("nx", (GO) 2 * comm->getSize()); 
    galeriList.set("ny", (GO) 2);
    galeriList.set("mx", (GO) comm->getSize());
    galeriList.set("my", (GO) 1);
    
    // Creation of the map
    RCP< ::Xpetra::Map<int, GO, KokkosClassic::DefaultNode::DefaultNodeType> > map = Galeri::Xpetra::CreateMap<int, GO, KokkosClassic::DefaultNode::DefaultNodeType>(lib, "Cartesian2D", comm, galeriList);

    // Print out the parameters
    cout << galeriList;
  
    // Print out the map
    RCP<Teuchos::FancyOStream> fos = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
    map->describe(*fos, Teuchos::VERB_EXTREME);
  }

  {
    // Creates an Xpetra::Map corresponding to a 3D Cartesian grid
    
    // Type of the object
    string mapType = "Cartesian3D";
    
    // Container for parameters
    Teuchos::ParameterList galeriList;
    galeriList.set("nx", (GO) 2 * comm->getSize()); 
    galeriList.set("ny", (GO) 2);
    galeriList.set("nz", (GO) 2);
    
    // Creation of the map
    RCP< ::Xpetra::Map<int, GO, KokkosClassic::DefaultNode::DefaultNodeType> > map = Galeri::Xpetra::CreateMap<int, GO, KokkosClassic::DefaultNode::DefaultNodeType>(lib, "Cartesian3D", comm, galeriList);

    // Print out the parameters
    cout << galeriList;
  
    // Print out the map
    RCP<Teuchos::FancyOStream> fos = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
    map->describe(*fos, Teuchos::VERB_EXTREME);
  }

  return EXIT_SUCCESS;
}
Exemple #27
0
int main(int argc, char *argv[]) {

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm (MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  // The problem is defined on a 2D grid, global size is nx * nx.
  int nx = 30;
  Teuchos::ParameterList GaleriList;
  GaleriList.set("nx", nx);
  GaleriList.set("ny", nx * Comm.NumProc());
  GaleriList.set("mx", 1);
  GaleriList.set("my", Comm.NumProc());
  Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap("Cartesian2D", Comm, GaleriList) );
  Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) );
  Teuchos::RefCountPtr<Epetra_MultiVector> LHS = Teuchos::rcp( new Epetra_MultiVector(*Map, 1) );
  Teuchos::RefCountPtr<Epetra_MultiVector> RHS = Teuchos::rcp( new Epetra_MultiVector(*Map, 1) );
  LHS->PutScalar(0.0); RHS->Random();

  // ========================================= //
  // Compare IC preconditioners to no precond. //
  // ----------------------------------------- //

  const double tol = 1e-5;
  const int maxIter = 500;

  // Baseline: No preconditioning
  // Compute number of iterations, to compare to IC later.

  // Here we create an AztecOO object
  LHS->PutScalar(0.0);

  AztecOO solver;
  solver.SetUserMatrix(&*A);
  solver.SetLHS(&*LHS);
  solver.SetRHS(&*RHS);
  solver.SetAztecOption(AZ_solver,AZ_cg);
  //solver.SetPrecOperator(&*PrecDiag);
  solver.SetAztecOption(AZ_output, 16); 
  solver.Iterate(maxIter, tol);

  int Iters = solver.NumIters();
  //cout << "No preconditioner iterations: " << Iters << endl;

#if 0 
  // Not sure how to use Ifpack_CrsRick - leave out for now.
  //
  // I wanna test funky values to be sure that they have the same
  // influence on the algorithms, both old and new
  int    LevelFill = 2;
  double DropTol = 0.3333;
  double Condest;
  
  Teuchos::RefCountPtr<Ifpack_CrsRick> IC;
  Ifpack_IlukGraph mygraph (A->Graph(), 0, 0);
  IC = Teuchos::rcp( new Ifpack_CrsRick(*A, mygraph) );
  IC->SetAbsoluteThreshold(0.00123);
  IC->SetRelativeThreshold(0.9876);
  // Init values from A
  IC->InitValues(*A);
  // compute the factors
  IC->Factor();
  // and now estimate the condition number
  IC->Condest(false,Condest);
  
  if( Comm.MyPID() == 0 ) {
    cout << "Condition number estimate (level-of-fill = "
	 << LevelFill <<  ") = " << Condest << endl;
  }

  // Define label for printing out during the solve phase
  std::string label = "Ifpack_CrsRick Preconditioner: LevelFill = " + toString(LevelFill) + 
                                                 " Overlap = 0"; 
  IC->SetLabel(label.c_str());
  
  // Here we create an AztecOO object
  LHS->PutScalar(0.0);

  AztecOO solver;
  solver.SetUserMatrix(&*A);
  solver.SetLHS(&*LHS);
  solver.SetRHS(&*RHS);
  solver.SetAztecOption(AZ_solver,AZ_cg);
  solver.SetPrecOperator(&*IC);
  solver.SetAztecOption(AZ_output, 16); 
  solver.Iterate(maxIter, tol);

  int RickIters = solver.NumIters();
  //cout << "Ifpack_Rick iterations: " << RickIters << endl;

  // Compare to no preconditioning
  if (RickIters > Iters/2)
    IFPACK_CHK_ERR(-1);

#endif

  //////////////////////////////////////////////////////
  // Same test with Ifpack_IC
  // This is Crout threshold Cholesky, so different than IC(0)

  Ifpack Factory;
  Teuchos::RefCountPtr<Ifpack_Preconditioner> PrecIC = Teuchos::rcp( Factory.Create("IC", &*A) );

  Teuchos::ParameterList List;
  //List.get("fact: ict level-of-fill", 2.);
  //List.get("fact: drop tolerance", 0.3333);
  //List.get("fact: absolute threshold", 0.00123);
  //List.get("fact: relative threshold", 0.9876);
  //List.get("fact: relaxation value", 0.0);

  IFPACK_CHK_ERR(PrecIC->SetParameters(List));
  IFPACK_CHK_ERR(PrecIC->Compute());

  // Here we create an AztecOO object
  LHS->PutScalar(0.0);

  //AztecOO solver;
  solver.SetUserMatrix(&*A);
  solver.SetLHS(&*LHS);
  solver.SetRHS(&*RHS);
  solver.SetAztecOption(AZ_solver,AZ_cg);
  solver.SetPrecOperator(&*PrecIC);
  solver.SetAztecOption(AZ_output, 16); 
  solver.Iterate(maxIter, tol);

  int ICIters = solver.NumIters();
  //cout << "Ifpack_IC iterations: " << ICIters << endl;

  // Compare to no preconditioning
  if (ICIters > Iters/2)
    IFPACK_CHK_ERR(-1);

#if 0
  //////////////////////////////////////////////////////
  // Same test with Ifpack_ICT 
  // This is another threshold Cholesky

  Teuchos::RefCountPtr<Ifpack_Preconditioner> PrecICT = Teuchos::rcp( Factory.Create("ICT", &*A) );

  //Teuchos::ParameterList List;
  //List.get("fact: level-of-fill", 2);
  //List.get("fact: drop tolerance", 0.3333);
  //List.get("fact: absolute threshold", 0.00123);
  //List.get("fact: relative threshold", 0.9876);
  //List.get("fact: relaxation value", 0.0);

  IFPACK_CHK_ERR(PrecICT->SetParameters(List));
  IFPACK_CHK_ERR(PrecICT->Compute());

  // Here we create an AztecOO object
  LHS->PutScalar(0.0);

  solver.SetUserMatrix(&*A);
  solver.SetLHS(&*LHS);
  solver.SetRHS(&*RHS);
  solver.SetAztecOption(AZ_solver,AZ_cg);
  solver.SetPrecOperator(&*PrecICT);
  solver.SetAztecOption(AZ_output, 16); 
  solver.Iterate(maxIter, tol);

  int ICTIters = solver.NumIters();
  //cout << "Ifpack_ICT iterations: " << ICTIters << endl;

  // Compare to no preconditioning
  if (ICTIters > Iters/2)
    IFPACK_CHK_ERR(-1);
#endif

#ifdef HAVE_MPI
  MPI_Finalize() ;
#endif

  return(EXIT_SUCCESS);
}
int main(int argc, char **argv)
{
  Kokkos::initialize();

  try {

    // Create random field
    int M = 10;
    Teuchos::ParameterList solverParams;
    solverParams.set("Number of KL Terms", M);
    solverParams.set("Mean", 1.0);
    solverParams.set("Standard Deviation", 0.1);
    int ndim = 3;
    Teuchos::Array<double> domain_upper(ndim), domain_lower(ndim),
      correlation_length(ndim);
    for (int i=0; i<ndim; i++) {
      domain_upper[i] = 1.0;
      domain_lower[i] = 0.0;
      correlation_length[i] = 10.0;
    }
    solverParams.set("Domain Upper Bounds", domain_upper);
    solverParams.set("Domain Lower Bounds", domain_lower);
    solverParams.set("Correlation Lengths", correlation_length);
    Stokhos::KL::ExponentialRandomField<double> rf(solverParams);
    rf.print(std::cout);

    // Evaluate random field at a point
    Teuchos::Array<double> x(ndim);
    for (int i=0; i<ndim; i++)
      x[i] = (domain_upper[i] + domain_lower[i])/2.0 +
        0.1*(domain_upper[i] - domain_lower[i])/2.0;
    Teuchos::Array<double> rvar(M);
    for (int i=0; i<M; i++)
      rvar[i] = 1.5;
    double result = rf.evaluate(x, rvar);
    std::cout << "result (host)  = " << result << std::endl;

    // Evaluate random field in a functor on device
    typedef Kokkos::View<double*> view_type;
    typedef view_type::HostMirror host_view_type;
    view_type x_view("x", ndim);
    host_view_type host_x = Kokkos::create_mirror_view(x_view);
    for (int i=0; i<ndim; i++)
      host_x(i) = x[i];
    Kokkos::deep_copy(x_view, host_x);
    view_type rvar_view("rvar", M);
    host_view_type host_rvar = Kokkos::create_mirror_view(rvar_view);
    for (int i=0; i<M; i++)
      host_rvar(i) = rvar[i];
    Kokkos::deep_copy(rvar_view, host_rvar);
    RF<double> rf_func(rf, x_view, rvar_view);
    host_view_type host_y = Kokkos::create_mirror_view(rf_func.y);
    Kokkos::deep_copy(host_y, rf_func.y);
    double result2 = host_y(0);
    std::cout << "result (device)= " << result2 << std::endl;
  }
  catch (std::exception& e) {
    std::cout << e.what() << std::endl;
  }

  Kokkos::finalize();
}
Exemple #29
0
// ======================================================================
bool TestContainer(string Type, const Teuchos::RefCountPtr<Epetra_RowMatrix>& A)
{
  int NumVectors = 3;
  int NumMyRows = A->NumMyRows();

  Epetra_MultiVector LHS_exact(A->RowMatrixRowMap(), NumVectors);
  Epetra_MultiVector LHS(A->RowMatrixRowMap(), NumVectors);
  Epetra_MultiVector RHS(A->RowMatrixRowMap(), NumVectors);
  LHS_exact.Random(); LHS.PutScalar(0.0); 
  A->Multiply(false, LHS_exact, RHS);

  Epetra_LinearProblem Problem(&*A, &LHS, &RHS);

  if (verbose) {
    cout << "Container type = " << Type << endl;
    cout << "NumMyRows = " << NumMyRows << ", NumVectors = " << NumVectors << endl;
  }
  LHS.PutScalar(0.0);
  
  Teuchos::RefCountPtr<Ifpack_Container> Container;

  if (Type == "dense")
    Container = Teuchos::rcp( new Ifpack_DenseContainer(A->NumMyRows(), NumVectors) );
  else
    Container = Teuchos::rcp( new Ifpack_SparseContainer<Ifpack_Amesos>(A->NumMyRows(), NumVectors) );

  assert (Container != Teuchos::null);

  IFPACK_CHK_ERR(Container->Initialize());
  // set as ID all the local rows of A
  for (int i = 0 ; i < A->NumMyRows() ; ++i)
    Container->ID(i) = i;

  // extract submatrix (in this case, the entire matrix)
  // and complete setup
  IFPACK_CHK_ERR(Container->Compute(*A));

  // set the RHS and LHS
  for (int i = 0 ; i < A->NumMyRows() ; ++i)
    for (int j = 0 ; j < NumVectors ; ++j) {
      Container->RHS(i,j) = RHS[j][i];
      Container->LHS(i,j) = LHS[j][i];
    }
  
  // set parameters (empty for dense containers)
  Teuchos::ParameterList List;
  List.set("amesos: solver type", Type);
  IFPACK_CHK_ERR(Container->SetParameters(List));

  // solve the linear system
  IFPACK_CHK_ERR(Container->ApplyInverse());

  // get the computed solution, store it in LHS
  for (int i = 0 ; i < A->NumMyRows() ; ++i)
    for (int j = 0 ; j < NumVectors ; ++j) {
       LHS[j][i] = Container->LHS(i,j);
    }

  double residual = Galeri::ComputeNorm(&LHS, &LHS_exact);

  if (A->Comm().MyPID() == 0 && verbose) {
    cout << "||x_exact - x||_2 = " << residual << endl;
    cout << *Container;
  }

  bool passed = false;
  if (residual < 1e-5)
    passed = true;

  return(passed);
}
Exemple #30
0
int main(int argc, char *argv[]) {
  using Teuchos::RCP;

  Teuchos::oblackholestream blackhole;
  Teuchos::GlobalMPISession mpiSession(&argc,&argv,&blackhole);

  RCP<const Teuchos::Comm<int> > comm = Teuchos::DefaultComm<int>::getComm();
  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
  out->setOutputToRootOnly(0);
  *out << MueLu::MemUtils::PrintMemoryUsage() << std::endl;

  // Timing
  Teuchos::Time myTime("global");
  Teuchos::TimeMonitor M(myTime);

#ifndef HAVE_TEUCHOS_LONG_LONG_INT
  *out << "Warning: scaling test was not compiled with long long int support" << std::endl;
#endif

  // custom parameters
  LO maxLevels = 10;
  LO its=40;
  std::string smooType="sgs";
  int sweeps=1;
  int maxCoarseSize=1;  //FIXME clp doesn't like long long int
  std::string aggOrdering = "natural";
  int minPerAgg=2;
  int maxNbrAlreadySelected=0;

  // read in problem
  Epetra_Map emap(10201,0,*Xpetra::toEpetra(comm));
  Epetra_CrsMatrix * ptrA = 0;
  Epetra_Vector * ptrf = 0;

  std::cout << "Reading matrix market file" << std::endl;
  EpetraExt::MatrixMarketFileToCrsMatrix("Condif2Mat.mat",emap,emap,emap,ptrA);
  EpetraExt::MatrixMarketFileToVector("Condif2Rhs.mat",emap,ptrf);
  RCP<Epetra_CrsMatrix> epA = Teuchos::rcp(ptrA);
  RCP<Epetra_Vector> epv = Teuchos::rcp(ptrf);

  // Epetra_CrsMatrix -> Xpetra::Matrix
  RCP<Xpetra::CrsMatrix<double, int, int> > exA = Teuchos::rcp(new Xpetra::EpetraCrsMatrix(epA));
  RCP<Xpetra::CrsMatrixWrap<double, int, int> > crsOp = Teuchos::rcp(new Xpetra::CrsMatrixWrap<double, int, int>(exA));
  RCP<Xpetra::Matrix<double, int, int> > Op = Teuchos::rcp_dynamic_cast<Xpetra::Matrix<double, int, int> >(crsOp);

  // Epetra_Vector -> Xpetra::Vector
  RCP<Xpetra::Vector<double,int,int> > xRhs = Teuchos::rcp(new Xpetra::EpetraVector(epv));

  // Epetra_Map -> Xpetra::Map
  const RCP< const Xpetra::Map<int, int> > map = Xpetra::toXpetra(emap);

  // build nullspace
  RCP<MultiVector> nullSpace = MultiVectorFactory::Build(map,1);
  nullSpace->putScalar( (SC) 1.0);
  /*for (size_t i=0; i<nullSpace->getLocalLength(); i++) {
    Teuchos::ArrayRCP< Scalar > data0 = nullSpace->getDataNonConst(0);
    Teuchos::ArrayRCP< Scalar > data1 = nullSpace->getDataNonConst(1);

    GlobalOrdinal gid = map->getGlobalElement(Teuchos::as<LocalOrdinal>(i));
    if(gid % 2 == 0) {
      data0[i] = 1.0; data1[i] = 0.0;
    }
    else {
      data0[i] = 0.0; data1[i] = 1.0;
    }
  }*/

  RCP<MueLu::Hierarchy<SC,LO,GO,NO,LMO> > H = rcp ( new Hierarchy() );
  H->setDefaultVerbLevel(Teuchos::VERB_HIGH);
  H->SetMaxCoarseSize((GO) maxCoarseSize);;

  // build finest Level
  RCP<MueLu::Level> Finest = H->GetLevel();
  Finest->setDefaultVerbLevel(Teuchos::VERB_HIGH);
  Finest->Set("A",Op);
  Finest->Set("Nullspace",nullSpace);

  RCP<CoupledAggregationFactory> CoupledAggFact = rcp(new CoupledAggregationFactory());
  *out << "========================= Aggregate option summary  =========================" << std::endl;
  *out << "min DOFs per aggregate :                " << minPerAgg << std::endl;
  *out << "min # of root nbrs already aggregated : " << maxNbrAlreadySelected << std::endl;
  CoupledAggFact->SetMinNodesPerAggregate(minPerAgg);  //TODO should increase if run anything other than 1D
  CoupledAggFact->SetMaxNeighAlreadySelected(maxNbrAlreadySelected);
  std::transform(aggOrdering.begin(), aggOrdering.end(), aggOrdering.begin(), ::tolower);
  if (aggOrdering == "natural") {
       *out << "aggregate ordering :                    NATURAL" << std::endl;
       CoupledAggFact->SetOrdering(MueLu::AggOptions::NATURAL);
  } else if (aggOrdering == "random") {
       *out << "aggregate ordering :                    RANDOM" << std::endl;
       CoupledAggFact->SetOrdering(MueLu::AggOptions::RANDOM);
  } else if (aggOrdering == "graph") {
       *out << "aggregate ordering :                    GRAPH" << std::endl;
       CoupledAggFact->SetOrdering(MueLu::AggOptions::GRAPH);
  } else {
    std::string msg = "main: bad aggregation option """ + aggOrdering + """.";
    throw(MueLu::Exceptions::RuntimeError(msg));
  }
  CoupledAggFact->SetPhase3AggCreation(0.5);
  *out << "=============================================================================" << std::endl;

  // build transfer operators
  RCP<TentativePFactory> TentPFact = rcp(new TentativePFactory(CoupledAggFact));

  *out << " afer TentativePFactory " << std::endl;
  //RCP<TentativePFactory> Pfact = rcp(new TentativePFactory(CoupledAggFact));
  //RCP<Factory>          Rfact = rcp( new TransPFactory(Pfact));
  //RCP<SaPFactory>       Pfact = rcp( new SaPFactory(TentPFact) );
  //RCP<Factory>         Rfact = rcp( new TransPFactory(Pfact));
  RCP<ThresholdAFilterFactory> Afiltered = rcp(new ThresholdAFilterFactory("A",NULL,0.0005));
  RCP<PgPFactory>       Pfact = rcp( new PgPFactory(TentPFact,Afiltered) );
  RCP<Factory>         Rfact = rcp( new GenericRFactory(Pfact));
  RCP<RAPFactory>       Acfact = rcp( new RAPFactory(Pfact, Rfact) );
  Acfact->setVerbLevel(Teuchos::VERB_HIGH);

  *out << " after ACFactory " << std::endl;

  // build level smoothers

  RCP<SmootherPrototype> smooProto;
  std::string ifpackType;
  Teuchos::ParameterList ifpackList;
  ifpackList.set("relaxation: sweeps", (LO) sweeps);
  ifpackList.set("relaxation: damping factor", (SC) 0.9); // 0.7
    ifpackType = "RELAXATION";
    ifpackList.set("relaxation: type", "Gauss-Seidel");


  smooProto = Teuchos::rcp( new TrilinosSmoother(Xpetra::UseEpetra, ifpackType, ifpackList) );
  RCP<SmootherFactory> SmooFact;
  if (maxLevels > 1)
    SmooFact = rcp( new SmootherFactory(smooProto) );

  Teuchos::ParameterList status;

#if 0  // both variants are equivalent
  // fill FactoryManager object by hand
  FactoryManager Manager;
  Manager.SetFactory("A",            Acfact);
  Manager.SetFactory("P",            Pfact);
  Manager.SetFactory("R",            Rfact);
  Manager.SetFactory("Smoother",     SmooFact);
  Manager.SetFactory("CoarseSolver", Teuchos::null);

  status = H->Setup(Manager);
#else
  // use FullPopulate (short, but outdated?)
  status = H->FullPopulate(*Pfact,*Rfact,*Acfact,*SmooFact,0,maxLevels);
#endif

  H->SetCoarsestSolver(*SmooFact,MueLu::PRE);


  *out  << "======================\n Multigrid statistics \n======================" << std::endl;
  status.print(*out,Teuchos::ParameterList::PrintOptions().indent(2));

  /**********************************************************************************/
  /* SOLVE PROBLEM                                                                  */
  /**********************************************************************************/

  RCP<MultiVector> x = MultiVectorFactory::Build(map,1);
  RCP<Xpetra::MultiVector<double,int,int> > rhs = Teuchos::rcp_dynamic_cast<Xpetra::MultiVector<double,int,int> >(xRhs);//(new Xpetra::EpetraVector(epv));

  // Use AMG directly as an iterative method
  {
    x->putScalar( (SC) 0.0);

    H->Iterate(*rhs,its,*x);

    //x->describe(*out,Teuchos::VERB_EXTREME);
  }

  RCP<Level> coarseLevel = H->GetLevel(1);
  coarseLevel->print(*out);
  RCP<Level> coarseLevel2 = H->GetLevel(1);
  coarseLevel2->print(*out);


  //M.summarize();

  return EXIT_SUCCESS;
}