Beispiel #1
0
std::ostream& operator<<( std::ostream& o, const dump_vec_spaces_t<Scalar>& d )
{

  using Teuchos::OSTab;
  const Teuchos::EVerbosityLevel verbLevel = Teuchos::VERB_MEDIUM;
  o << "Error, the following vector spaces are not compatible:\n\n";
  OSTab(o).o()
    << d.vec_space1_name << " : "
    << Teuchos::describe(d.vec_space1,verbLevel);
  o << "\n";
  OSTab(o).o()
    << d.vec_space2_name << " : "
    << Teuchos::describe(d.vec_space2,verbLevel);
  return o;
}
void MLPreconditionerFactory::initializePrec(
  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
  PreconditionerBase<double> *prec,
  const ESupportSolveUse supportSolveUse
  ) const
{
  using Teuchos::outArg;
  using Teuchos::OSTab;
  using Teuchos::dyn_cast;
  using Teuchos::RCP;
  using Teuchos::null;
  using Teuchos::rcp;
  using Teuchos::rcp_dynamic_cast;
  using Teuchos::rcp_const_cast;
  using Teuchos::set_extra_data;
  using Teuchos::get_optional_extra_data;
  using Teuchos::implicit_cast;
  Teuchos::Time totalTimer(""), timer("");
  totalTimer.start(true);
  const RCP<Teuchos::FancyOStream> out = this->getOStream();
  const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
  Teuchos::OSTab tab(out);
  if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nEntering Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";

  Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
#ifdef _DEBUG
  TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
#endif
  //
  // Unwrap and get the forward Epetra_Operator object
  //
  Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
  EOpTransp epetraFwdOpTransp;
  EApplyEpetraOpAs epetraFwdOpApplyAs;
  EAdjointEpetraOp epetraFwdOpAdjointSupport;
  double epetraFwdOpScalar;
  epetraFwdOpViewExtractor_->getEpetraOpView(
    fwdOp,outArg(epetraFwdOp),outArg(epetraFwdOpTransp),outArg(epetraFwdOpApplyAs),
    outArg(epetraFwdOpAdjointSupport),outArg(epetraFwdOpScalar)
                                             );
  // Validate what we get is what we need
  RCP<const Epetra_RowMatrix>
    epetraFwdRowMat = rcp_dynamic_cast<const Epetra_RowMatrix>(epetraFwdOp,true);
  TEUCHOS_TEST_FOR_EXCEPTION(
    epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
    ,"Error, incorrect apply mode for an Epetra_RowMatrix"
    );

  //
  // Get the concrete preconditioner object
  //
  DefaultPreconditioner<double>
    *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
  //
  // Get the EpetraLinearOp object that is used to implement the preconditoner linear op
  //
  RCP<EpetraLinearOp>
    epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),true);
  //
  // Get the embedded ML_Epetra::MultiLevelPreconditioner object if it exists
  //
  Teuchos::RCP<ML_Epetra::MultiLevelPreconditioner> ml_precOp;
  if(epetra_precOp.get())
    ml_precOp = rcp_dynamic_cast<ML_Epetra::MultiLevelPreconditioner>(epetra_precOp->epetra_op(),true);
  //
  // Get the attached forward operator if it exists and make sure that it matches
  //
  if(ml_precOp!=Teuchos::null) {
    // Get the forward operator and make sure that it matches what is
    // already being used!
    const Epetra_RowMatrix & rm = ml_precOp->RowMatrix();
   
    TEUCHOS_TEST_FOR_EXCEPTION(
       &rm!=&*epetraFwdRowMat, std::logic_error
       ,"ML requires Epetra_RowMatrix to be the same for each initialization of the preconditioner"
       );
  }
  //
  // Perform initialization if needed
  //
  const bool startingOver = (ml_precOp.get() == NULL);
  if(startingOver) 
  {
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      *out << "\nCreating the initial ML_Epetra::MultiLevelPreconditioner object...\n";
    timer.start(true);
    // Create the initial preconditioner: DO NOT compute it yet
    ml_precOp = rcp(
      new ML_Epetra::MultiLevelPreconditioner(
        *epetraFwdRowMat, paramList_->sublist(MLSettings_name),false
        )
      );
    
    timer.stop();
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      OSTab(out).o() <<"> Creation time = "<<timer.totalElapsedTime()<<" sec\n";
    // RAB: Above, I am just passing a string to ML::Create(...) in order
    // get this code written.  However, in the future, it would be good to
    // copy the contents of what is in ML::Create(...) into a local
    // function and then use switch(...) to create the initial
    // ML_Epetra::MultiLevelPreconditioner object.  This would result in better validation
    // and faster code.
    // Set parameters if the list exists
    if(paramList_.get())
      TEUCHOS_TEST_FOR_EXCEPT(
        0!=ml_precOp->SetParameterList(paramList_->sublist(MLSettings_name))
        );
    // Initialize the structure for the preconditioner
    //        TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->Initialize());
  }
  //
  // Attach the epetraFwdOp to the ml_precOp to guarantee that it will not go away
  //
  set_extra_data(epetraFwdOp, "IFPF::epetraFwdOp", Teuchos::inOutArg(ml_precOp),
    Teuchos::POST_DESTROY, false);
  //
  // Update the factorization
  //
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nComputing the preconditioner ...\n";
  timer.start(true);
  if (startingOver) {
    TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ComputePreconditioner());
  }
  else {
    TEUCHOS_TEST_FOR_EXCEPT(0!=ml_precOp->ReComputePreconditioner(paramList_->get<bool>(ReuseFineLevelSmoother_name)));
  }
  timer.stop();
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    OSTab(out).o() <<"=> Setup time = "<<timer.totalElapsedTime()<<" sec\n";
  //
  // Compute the conditioner number estimate if asked
  //

  // ToDo: Implement

  //
  // Attach fwdOp to the ml_precOp
  //
  set_extra_data(fwdOp, "IFPF::fwdOp", Teuchos::inOutArg(ml_precOp),
    Teuchos::POST_DESTROY, false);
  //
  // Initialize the output EpetraLinearOp
  //
  if(startingOver) {
    epetra_precOp = rcp(new EpetraLinearOp);
  }
  epetra_precOp->initialize(
    ml_precOp
    ,epetraFwdOpTransp
    ,EPETRA_OP_APPLY_APPLY_INVERSE
    ,EPETRA_OP_ADJOINT_UNSUPPORTED  // ToDo: Look into adjoints again.
    );
  //
  // Initialize the preconditioner
  //
  defaultPrec->initializeUnspecified(
    Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
    );
  totalTimer.stop();
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nTotal time in MLPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<" sec\n";
  if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nLeaving Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
}
void IfpackPreconditionerFactory::initializePrec(
  const Teuchos::RCP<const LinearOpSourceBase<double> >    &fwdOpSrc
  ,PreconditionerBase<double>                                      *prec
  ,const ESupportSolveUse                                           supportSolveUse
  ) const
{
  using Teuchos::outArg;
  using Teuchos::OSTab;
  using Teuchos::dyn_cast;
  using Teuchos::RCP;
  using Teuchos::null;
  using Teuchos::rcp;
  using Teuchos::rcp_dynamic_cast;
  using Teuchos::rcp_const_cast;
  using Teuchos::set_extra_data;
  using Teuchos::get_optional_extra_data;
  using Teuchos::implicit_cast;
  Teuchos::Time totalTimer(""), timer("");
  totalTimer.start(true);
  Teuchos::TimeMonitor overallTimeMonitor(*overallTimer);
  const Teuchos::RCP<Teuchos::FancyOStream> out       = this->getOStream();
  const Teuchos::EVerbosityLevel                    verbLevel = this->getVerbLevel();
  Teuchos::OSTab tab(out);
  if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nEntering Thyra::IfpackPreconditionerFactory::initializePrec(...) ...\n";
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT(fwdOpSrc.get()==NULL);
  TEST_FOR_EXCEPT(prec==NULL);
#endif
  Teuchos::RCP<const LinearOpBase<double> >
    fwdOp = fwdOpSrc->getOp();
#ifdef TEUCHOS_DEBUG
  TEST_FOR_EXCEPT(fwdOp.get()==NULL);
#endif
  //
  // Unwrap and get the forward Epetra_Operator object
  //
  Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
  EOpTransp epetraFwdOpTransp;
  EApplyEpetraOpAs epetraFwdOpApplyAs;
  EAdjointEpetraOp epetraFwdOpAdjointSupport;
  double epetraFwdOpScalar;
  epetraFwdOpViewExtractor_->getEpetraOpView(
    fwdOp,
    outArg(epetraFwdOp), outArg(epetraFwdOpTransp),
    outArg(epetraFwdOpApplyAs), outArg(epetraFwdOpAdjointSupport),
    outArg(epetraFwdOpScalar)
    );
  // Validate what we get is what we need
  RCP<const Epetra_RowMatrix>
    epetraFwdRowMat = rcp_dynamic_cast<const Epetra_RowMatrix>(epetraFwdOp,true);
  TEST_FOR_EXCEPTION(
    epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
    ,"Error, incorrect apply mode for an Epetra_RowMatrix"
    );
  //
  // Get the concrete precondtioner object
  //
  DefaultPreconditioner<double>
    *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);
  //
  // Get the EpetraLinearOp object that is used to implement the preconditoner linear op
  //
  RCP<EpetraLinearOp>
    epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),true);
  //
  // Get the embedded Ifpack_Preconditioner object if it exists
  //
  Teuchos::RCP<Ifpack_Preconditioner>
    ifpack_precOp;
  if(epetra_precOp.get())
    ifpack_precOp = rcp_dynamic_cast<Ifpack_Preconditioner>(epetra_precOp->epetra_op(),true);
  //
  // Get the attached forward operator if it exists and make sure that it matches
  //
  if(ifpack_precOp.get()) {
    // ToDo: Get the forward operator and make sure that it matches what is
    // already being used!
  }
  //
  // Permform initialization if needed
  //
  //const bool startingOver = (ifpack_precOp.get() == NULL);
  const bool startingOver = true;
  // ToDo: Comment back in the above original version of startingOver to allow
  // for resuse.  Rob H. just pointed out to me that a memory leak is being
  // created when you just call Ifpack_ILU::Compute() over and over again.
  // Rob H. said that he will check in a fix the the development branch when
  // he can.
  if(startingOver) {
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      *out << "\nCreating the initial Ifpack_Preconditioner object of type \'"<<Ifpack::toString(precType_)<<"\' ...\n";
    timer.start(true);
    Teuchos::TimeMonitor creationTimeMonitor(*creationTimer);
    // Create the initial preconditioner
    ifpack_precOp = rcp(
      ::Ifpack::Create(
        precType_
        ,const_cast<Epetra_RowMatrix*>(&*epetraFwdRowMat)
        ,overlap_
        )
      );
    timer.stop();
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      OSTab(out).o() <<"=> Creation time = "<<timer.totalElapsedTime()<<" sec\n";
    // Set parameters if the list exists
    if(paramList_.get()) {
      Teuchos::ParameterList
        &ifpackSettingsPL = paramList_->sublist(IfpackSettings_name);
      // Above will create new sublist if it does not exist!
      TEST_FOR_EXCEPT(0!=ifpack_precOp->SetParameters(ifpackSettingsPL));
      // Above, I have not idea how any error messages for a mistake will be
      // reported back to the user!
    }
    // Initailize the structure for the preconditioner
    TEST_FOR_EXCEPT(0!=ifpack_precOp->Initialize());
  }
  //
  // Attach the epetraFwdOp to the ifpack_precOp to guarantee that it will not go away
  //
  set_extra_data(epetraFwdOp, "IFPF::epetraFwdOp", Teuchos::inOutArg(ifpack_precOp),
    Teuchos::POST_DESTROY, false);
  //
  // Update the factorization
  //
  {
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      *out << "\nComputing the factorization of the preconditioner ...\n";
    Teuchos::TimeMonitor factorizationTimeMonitor(*factorizationTimer);
    timer.start(true);
    TEST_FOR_EXCEPT(0!=ifpack_precOp->Compute());
    timer.stop();
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      OSTab(out).o() <<"=> Factorization time = "<<timer.totalElapsedTime()<<" sec\n";
  }
  //
  // Compute the conditioner number estimate if asked
  //

  // ToDo: Implement

  //
  // Attach fwdOp to the ifpack_precOp
  //
  set_extra_data(fwdOpSrc, "IFPF::fwdOpSrc", Teuchos::inOutArg(ifpack_precOp),
    Teuchos::POST_DESTROY, false);
  //
  // Initialize the output EpetraLinearOp
  //
  if(startingOver) {
    epetra_precOp = rcp(new EpetraLinearOp);
  }
  epetra_precOp->initialize(
    ifpack_precOp
    ,epetraFwdOpTransp
    ,EPETRA_OP_APPLY_APPLY_INVERSE
    ,EPETRA_OP_ADJOINT_SUPPORTED
    );
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_MEDIUM)) {
    *out << "\nDescription of created preconditioner:\n";
    OSTab tab(out);
    ifpack_precOp->Print(*out);
  }

  //
  // Initialize the preconditioner
  //
  defaultPrec->initializeUnspecified(
    Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
    );
  totalTimer.stop();
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nTotal time in IfpackPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<" sec\n";
  if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nLeaving Thyra::IfpackPreconditionerFactory::initializePrec(...) ...\n";
}
void MueLuPreconditionerFactory::initializePrec(
  const Teuchos::RCP<const LinearOpSourceBase<double> > &fwdOpSrc,
  PreconditionerBase<double> *prec,
  const ESupportSolveUse supportSolveUse
  ) const
{
  using Teuchos::outArg;
  using Teuchos::OSTab;
  using Teuchos::dyn_cast;
  using Teuchos::RCP;
  using Teuchos::null;
  using Teuchos::rcp;
  using Teuchos::rcp_dynamic_cast;
  using Teuchos::rcp_const_cast;
  using Teuchos::set_extra_data;
  using Teuchos::get_optional_extra_data;
  using Teuchos::implicit_cast;

  typedef KokkosClassic::DefaultNode::DefaultNodeType NO;
  typedef KokkosClassic::DefaultKernels<double,int,NO>::SparseOps LMO;

  Teuchos::Time totalTimer(""), timer("");
  totalTimer.start(true);

  const RCP<Teuchos::FancyOStream> out = this->getOStream();
  const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
  Teuchos::OSTab tab(out);
  if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nEntering Thyra::MueLuPreconditionerFactory::initializePrec(...) ...\n";

  Teuchos::RCP<const LinearOpBase<double> > fwdOp = fwdOpSrc->getOp();
#ifdef _DEBUG
  TEUCHOS_TEST_FOR_EXCEPT(fwdOp.get()==NULL);
  TEUCHOS_TEST_FOR_EXCEPT(prec==NULL);
#endif

  //
  // Unwrap and get the forward Epetra_Operator object
  //

  Teuchos::RCP<const Epetra_Operator> epetraFwdOp;
  EOpTransp epetraFwdOpTransp;
  EApplyEpetraOpAs epetraFwdOpApplyAs;
  EAdjointEpetraOp epetraFwdOpAdjointSupport;
  double epetraFwdOpScalar;
  epetraFwdOpViewExtractor_->getEpetraOpView(
    fwdOp,outArg(epetraFwdOp),outArg(epetraFwdOpTransp),outArg(epetraFwdOpApplyAs),
    outArg(epetraFwdOpAdjointSupport),outArg(epetraFwdOpScalar)
                                             );
  // Validate what we get is what we need

  RCP<const Epetra_CrsMatrix>
    epetraFwdCrsMat = rcp_dynamic_cast<const Epetra_CrsMatrix>(epetraFwdOp,true);
  TEUCHOS_TEST_FOR_EXCEPTION(
    epetraFwdOpApplyAs != EPETRA_OP_APPLY_APPLY, std::logic_error
    ,"Error, incorrect apply mode for an Epetra_CrsMatrix"
    );

  //
  // Get the concrete preconditioner object
  //

  DefaultPreconditioner<double>
    *defaultPrec = &Teuchos::dyn_cast<DefaultPreconditioner<double> >(*prec);

  //
  // Get the EpetraLinearOp object that is used to implement the preconditoner linear op
  //

  RCP<EpetraLinearOp>
    epetra_precOp = rcp_dynamic_cast<EpetraLinearOp>(defaultPrec->getNonconstUnspecifiedPrecOp(),true);

  //
  // Get the embedded MueLu::EpetraOperator object if it exists
  //

  Teuchos::RCP<MueLu::EpetraOperator> muelu_precOp;
  if(epetra_precOp.get())
    muelu_precOp = rcp_dynamic_cast<MueLu::EpetraOperator>(epetra_precOp->epetra_op(),true);
  //
  // Get the attached forward operator if it exists and make sure that it matches
  //
  if(muelu_precOp!=Teuchos::null) {
    // TODO
//     // Get the forward operator and make sure that it matches what is
//     // already being used!
//     const Epetra_CrsMatrix & rm = muelu_precOp->CrsMatrix();

//     TEUCHOS_TEST_FOR_EXCEPTION(
//        &rm!=&*epetraFwdRowMat, std::logic_error
//        ,"MueLu requires Epetra_RowMatrix to be the same for each initialization of the preconditioner"
//        );
  }

  MueLu::ParameterListInterpreter<double, int, int, NO, LMO> mueluFactory(*paramList_);

  //
  // Perform initialization if needed
  //
  const bool startingOver = (muelu_precOp.get() == NULL);
  if(startingOver)
  {
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      *out << "\nCreating the initial MueLu::EpetraOperator object...\n";
    timer.start(true);
    // Create the initial preconditioner: DO NOT compute it yet

    // Turns a Epetra_CrsMatrix into a Xpetra::Matrix
    RCP<Epetra_CrsMatrix> epetraFwdCrsMatNonConst = rcp_const_cast<Epetra_CrsMatrix>(epetraFwdCrsMat); // !! TODO: MueLu interface should accept const matrix as input.

    RCP<Xpetra::CrsMatrix<double, int, int, NO, LMO> > mueluAcrs = rcp(new Xpetra::EpetraCrsMatrix(epetraFwdCrsMatNonConst)); //TODO: should not be needed
    RCP<Xpetra::Matrix <double, int, int, NO, LMO> >   mueluA    = rcp(new Xpetra::CrsMatrixWrap<double, int, int, NO, LMO>(mueluAcrs));

    const RCP<MueLu::Hierarchy<double,int, int, NO, LMO > > muelu_hierarchy = mueluFactory.CreateHierarchy();
    muelu_hierarchy->GetLevel(0)->Set("A", mueluA);
    muelu_precOp = rcp(new MueLu::EpetraOperator(muelu_hierarchy));

    timer.stop();
    if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
      OSTab(out).o() <<"> Creation time = "<<timer.totalElapsedTime()<<" sec\n";

    //     if(paramList_.get())
    //       TEUCHOS_TEST_FOR_EXCEPT(
    //         0!=muelu_precOp->SetParameterList(paramList_->sublist(MueLuSettings_name))
    //         );
  }

  //
  // Attach the epetraFwdOp to the muelu_precOp to guarantee that it will not go away
  //
  set_extra_data(epetraFwdOp, "IFPF::epetraFwdOp", Teuchos::inOutArg(muelu_precOp),
    Teuchos::POST_DESTROY, false);

  //
  // Update the factorization
  //
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nComputing the preconditioner ...\n";
  timer.start(true);

  mueluFactory.SetupHierarchy(*muelu_precOp->GetHierarchy());

  timer.stop();
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    OSTab(out).o() <<"=> Setup time = "<<timer.totalElapsedTime()<<" sec\n";
  //
  // Compute the conditioner number estimate if asked
  //

  // ToDo: Implement

  //
  // Attach fwdOp to the muelu_precOp
  //
  set_extra_data(fwdOp, "IFPF::fwdOp", Teuchos::inOutArg(muelu_precOp),
    Teuchos::POST_DESTROY, false);
  //
  // Initialize the output EpetraLinearOp
  //
  if(startingOver) {
    epetra_precOp = rcp(new EpetraLinearOp);
  }
  epetra_precOp->initialize(
    muelu_precOp
    ,epetraFwdOpTransp
    ,EPETRA_OP_APPLY_APPLY_INVERSE
    ,EPETRA_OP_ADJOINT_UNSUPPORTED  // ToDo: Look into adjoints again.
    );
  //
  // Initialize the preconditioner
  //
  defaultPrec->initializeUnspecified(
    Teuchos::rcp_implicit_cast<LinearOpBase<double> >(epetra_precOp)
    );
  totalTimer.stop();
  if(out.get() && implicit_cast<int>(verbLevel) >= implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nTotal time in MLPreconditionerFactory = "<<totalTimer.totalElapsedTime()<<" sec\n";
  if(out.get() && implicit_cast<int>(verbLevel) > implicit_cast<int>(Teuchos::VERB_LOW))
    *out << "\nLeaving Thyra::MLPreconditionerFactory::initializePrec(...) ...\n";
}
Beispiel #5
0
int main(int argc, char* argv[])
{

  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
  
  using Teuchos::CommandLineProcessor;
  using Teuchos::OSTab;

  bool result, success = true;
  bool verbose = true;


  Teuchos::RCP<Teuchos::FancyOStream>
    out = Teuchos::VerboseObjectBase::getDefaultOStream();

  try {

    //
    // Read options from command-line
    //
    
    std::string    matrixDir              = ".";
    bool           testTranspose          = true;
    int            numRandomVectors       = 1;
    bool           showAllTests           = false;
    bool           showAllTestsDetails    = false;
    bool           dumpAll                = false;

    CommandLineProcessor  clp;
    clp.throwExceptions(false);
    clp.addOutputSetupOptions(true);
    clp.setOption( "matrix-dir", &matrixDir, "Base directory for the test matrices" );
    clp.setOption( "test-transpose", "no-test-transpose", &testTranspose, "Test the transpose solve or not." );
    clp.setOption( "num-random-vectors", &numRandomVectors, "Number of times a test is performed with different random vectors." );
    clp.setOption( "verbose", "quiet", &verbose, "Set if output is printed or not." );
    clp.setOption( "show-all-tests", "no-show-all-tests", &showAllTests, "Set if all the tests are shown or not." );
    clp.setOption( "show-all-tests-details", "no-show-all-tests-details", &showAllTestsDetails, "Set if all the details of the tests are shown or not." );
    clp.setOption( "dump-all", "no-dump-all", &dumpAll, "Determines if vectors are printed or not." );
    CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
    if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) return parse_return;

    TEUCHOS_TEST_FOR_EXCEPT( matrixDir == "" );

    //
    // Define the test matrices
    //

    const int numTestMatrices = 9;

    typedef MatrixTestPacket MTP;

    // Set up the matices and the tolerances.
    // Note, we may need to adjust these for bad platforms ...
    const MTP testMatrices[numTestMatrices] =
      {
        MTP("bcsstk01.mtx",false,1e-12,1e-12,1e-12)
        ,MTP("bcsstk02.mtx",false,1e-12,1e-12,1e-12)
        ,MTP("bcsstk04.mtx",false,1e-12,1e-10,1e-12)
        ,MTP("Diagonal.mtx",false,1e-12,1e-12,1e-12)
        ,MTP("FourByFour.mtx",true,1e-12,1e-12,1e-12)
        ,MTP("KheadK.mtx",false,1e-12,1e-12,1e-12)
        ,MTP("KheadSorted.mtx",false,1e-12,1e-12,1e-12)
        ,MTP("nos1.mtx",false,1e-11,1e-10,1e-12)
        ,MTP("nos5.mtx",false,1e-12,1e-12,1e-12)
      };
    //
    // Loop through all of the test matrices
    //
    for( int matrix_i = 0; matrix_i < numTestMatrices; ++matrix_i ) {
      const MatrixTestPacket
        mtp = testMatrices[matrix_i];
      //
      // Loop through all of the solvers
      //
      for( int solver_i = 0; solver_i < Thyra::Amesos::numSolverTypes; ++solver_i ) {
        const Thyra::Amesos::ESolverType
          solverType = Thyra::Amesos::solverTypeValues[solver_i];

        //  bug 1902 - Amesos_Superlu fails on bcsstk01.mtx
        //  bug 1903 - Amesos_Superlu fails on four matrices,
        //             when called from the thyra test
        //
        bool BadMatrixForSuperlu = 
          mtp.matrixFile == "bcsstk01.mtx" // bug 1902 
          || mtp.matrixFile == "bcsstk04.mtx" // bug 1903 
          || mtp.matrixFile == "KheadK.mtx" // bug 1903 
          || mtp.matrixFile == "KheadSorted.mtx" // bug 1903 
          || mtp.matrixFile == "nos1.mtx" ; // bug 1903 
        //
        // Toggle the refactorization options
        //
        for( int factorizationPolicy_i = 0; factorizationPolicy_i < Thyra::Amesos::numRefactorizationPolices;  ++factorizationPolicy_i ) {
          const Thyra::Amesos::ERefactorizationPolicy
            refactorizationPolicy = Thyra::Amesos::refactorizationPolicyValues[factorizationPolicy_i];
          if(verbose)
            *out
              << std::endl<<matrix_i<<"."<<solver_i<<"."<<factorizationPolicy_i<<": "
              << "Testing, matrixFile=\'"<<mtp.matrixFile<<"\', solverType=\'"<<toString(solverType)<<"\', refactorizationPolicy=\'"<<toString(refactorizationPolicy)<<"\' ..."; 
          if( mtp.unsymmetric && !Thyra::Amesos::supportsUnsymmetric[solver_i] ) {
            *out << " : Skipping since unsymmetric and not supported!\n";
          }
          else {
            //  bug 1902 and bug 1903  
            string StrSolverType = toString(solverType) ; 
            string StrSuperlu = "Superlu";
            if ( StrSolverType==StrSuperlu && BadMatrixForSuperlu ) {
              *out << " : Skipping since Superlu fails on this matrix!\n";
            }
            else {
              std::ostringstream ossStore;
              Teuchos::RCP<Teuchos::FancyOStream>
                oss = Teuchos::rcp(new Teuchos::FancyOStream(Teuchos::rcp(&ossStore,false)));
              Teuchos::ParameterList amesosLOWSFPL;
              amesosLOWSFPL.set("Solver Type",toString(solverType));
              amesosLOWSFPL.set("Refactorization Policy",toString(refactorizationPolicy));
              result =
                Thyra::test_single_amesos_thyra_solver(
                  matrixDir+"/"+mtp.matrixFile,&amesosLOWSFPL,testTranspose,numRandomVectors
                  ,mtp.maxFwdError,mtp.maxError,mtp.maxResid,showAllTestsDetails,dumpAll,OSTab(oss).get()
                  );
              if(!result) success = false;
              if(verbose) {
                if(result) {
                  if(showAllTests)
                    *out << std::endl << ossStore.str();
                  else
                    *out << " : passed!\n";
                }
                else {
                  if(showAllTests)
                    *out << std::endl << ossStore.str();
                  else
                    *out << " : failed!\n";
                }
              }
            }
          }
        }
      }
    }
    
  }
  catch( const std::exception &excpt ) {
    std::cerr << "*** Caught standard exception : " << excpt.what() << std::endl;
    success = false;
  }
  catch( ... ) {
    std::cerr << "*** Caught an unknown exception\n";
    success = false;
  }
  
  if (verbose) {
    if(success)  *out << "\nCongratulations! All of the tests checked out!\n";
    else         *out << "\nOh no! At least one of the tests failed!\n";
  }

  return ( success ? 0 : 1 );
}
bool Thyra::test_single_belos_thyra_solver(
  const std::string                       matrixFile
  ,const bool                             testTranspose
  ,const bool                             usePreconditioner
  ,const int                              numRhs
  ,const int                              numRandomVectors
  ,const double                           maxFwdError
  ,const double                           maxResid
  ,const double                           maxSolutionError
  ,const bool                             showAllTests
  ,const bool                             dumpAll
  ,Teuchos::ParameterList                 *belosLOWSFPL
  ,Teuchos::ParameterList                 *precPL
  ,Teuchos::FancyOStream                  *out_arg
  )
{
  using Teuchos::rcp;
  using Teuchos::OSTab;
  bool result, success = true;

  Teuchos::RCP<Teuchos::FancyOStream> out = Teuchos::rcp(out_arg,false);

  try {

#ifndef SUN_CXX

    if(out.get()) {
      *out << "\n***"
           << "\n*** Testing Thyra::BelosLinearOpWithSolveFactory (and Thyra::BelosLinearOpWithSolve)"
           << "\n***\n"
           << "\nEchoing input options:"
           << "\n  matrixFile             = " << matrixFile
           << "\n  testTranspose          = " << testTranspose
           << "\n  usePreconditioner      = " << usePreconditioner
           << "\n  numRhs                 = " << numRhs
           << "\n  numRandomVectors       = " << numRandomVectors
           << "\n  maxFwdError            = " << maxFwdError
           << "\n  maxResid               = " << maxResid
           << "\n  showAllTests           = " << showAllTests
           << "\n  dumpAll                = " << dumpAll
           << std::endl;
    }

    if(out.get()) *out << "\nA) Reading in an epetra matrix A from the file \'"<<matrixFile<<"\' ...\n";
  
    Epetra_SerialComm comm;
    Teuchos::RCP<Epetra_CrsMatrix> epetra_A;
    EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A );

    Teuchos::RCP<const LinearOpBase<double> > A = epetraLinearOp(epetra_A);

    if(out.get() && dumpAll) *out << "\ndescribe(A) =\n" << describe(*A,Teuchos::VERB_EXTREME);

    if(out.get()) *out << "\nB) Creating a BelosLinearOpWithSolveFactory object opFactory ...\n";

    Teuchos::RCP<LinearOpWithSolveFactoryBase<double> >
      lowsFactory;
    {
      Teuchos::RCP<BelosLinearOpWithSolveFactory<double> >
        belosLowsFactory = Teuchos::rcp(new BelosLinearOpWithSolveFactory<double>());
      lowsFactory = belosLowsFactory;
    }

    if(out.get()) {
      *out << "\nlowsFactory.getValidParameters() before setting preconditioner factory:\n";
      lowsFactory->getValidParameters()->print(OSTab(out).o(),0,true,false);
    }

    if(usePreconditioner) {
#ifdef HAVE_BELOS_IFPACK
      if(out.get()) {
        *out << "\nSetting an Ifpack preconditioner factory ...\n";
      }
      RCP<PreconditionerFactoryBase<double> >
        precFactory = Teuchos::rcp(new IfpackPreconditionerFactory());
      if (precPL)
        precFactory->setParameterList(rcp(precPL,false));
      lowsFactory->setPreconditionerFactory(precFactory,"Ifpack");
#else
      TEUCHOS_TEST_FOR_EXCEPT(usePreconditioner);
#endif
    }
    
    if(out.get()) {
      *out << "\nlowsFactory.getValidParameters() after setting preconditioner factory:\n";
      lowsFactory->getValidParameters()->print(OSTab(out).o(),0,true,false);
      *out << "\nbelosLOWSFPL before setting parameters:\n";
      belosLOWSFPL->print(OSTab(out).o(),0,true);
    }

    lowsFactory->setParameterList(Teuchos::rcp(belosLOWSFPL,false));

    if(out.get()) {
      *out << "\nbelosLOWSFPL after setting parameters:\n";
      belosLOWSFPL->print(OSTab(out).o(),0,true);
    }

    if(out.get()) *out << "\nC) Creating a BelosLinearOpWithSolve object nsA from A ...\n";

    Teuchos::RCP<LinearOpWithSolveBase<double> > nsA = lowsFactory->createOp();
    Thyra::initializeOp<double>(*lowsFactory,  A, nsA.ptr());

    if(out.get()) *out << "\nD) Testing the LinearOpBase interface of nsA ...\n";

    LinearOpTester<double> linearOpTester;
    linearOpTester.check_adjoint(testTranspose);
    linearOpTester.num_rhs(numRhs);
    linearOpTester.num_random_vectors(numRandomVectors);
    linearOpTester.set_all_error_tol(maxFwdError);
    linearOpTester.set_all_warning_tol(1e-2*maxFwdError);
    linearOpTester.show_all_tests(showAllTests);
    linearOpTester.dump_all(dumpAll);
    Thyra::seed_randomize<double>(0);
    result = linearOpTester.check(*nsA,Teuchos::Ptr<Teuchos::FancyOStream>(out.get()));
    if(!result) success = false;

    if(out.get()) *out << "\nE) Testing the LinearOpWithSolveBase interface of nsA ...\n";
    
    LinearOpWithSolveTester<double> linearOpWithSolveTester;
    linearOpWithSolveTester.num_rhs(numRhs);
    linearOpWithSolveTester.turn_off_all_tests();
    linearOpWithSolveTester.check_forward_default(true);
    linearOpWithSolveTester.check_forward_residual(true);
    if(testTranspose) {
      linearOpWithSolveTester.check_adjoint_default(true);
      linearOpWithSolveTester.check_adjoint_residual(true);
    }
    else {
      linearOpWithSolveTester.check_adjoint_default(false);
      linearOpWithSolveTester.check_adjoint_residual(false);
    }
    linearOpWithSolveTester.set_all_solve_tol(maxResid);
    linearOpWithSolveTester.set_all_slack_error_tol(maxResid);
    linearOpWithSolveTester.set_all_slack_warning_tol(1e+1*maxResid);
    linearOpWithSolveTester.forward_default_residual_error_tol(2*maxResid);
    linearOpWithSolveTester.forward_default_solution_error_error_tol(maxSolutionError);
    linearOpWithSolveTester.adjoint_default_residual_error_tol(2*maxResid);
    linearOpWithSolveTester.adjoint_default_solution_error_error_tol(maxSolutionError);
    linearOpWithSolveTester.show_all_tests(showAllTests);
    linearOpWithSolveTester.dump_all(dumpAll);
    Thyra::seed_randomize<double>(0);
    result = linearOpWithSolveTester.check(*nsA,out.get());
    if(!result) success = false;

    if(out.get()) {
      *out << "\nbelosLOWSFPL after solving:\n";
      belosLOWSFPL->print(OSTab(out).o(),0,true);
    }
    
#else // SUN_CXX
    
    if(out.get()) *out << "\nTest failed since is was not even compiled since SUN_CXX was defined!\n";
    success = false;

#endif // SUN_CXX

  }
  catch( const std::exception &excpt ) {
    if(out.get()) *out << std::flush;
    std::cerr << "*** Caught standard exception : " << excpt.what() << std::endl;
    success = false;
  }
   
  return success;
    
}
Beispiel #7
0
bool Thyra::test_single_aztecoo_thyra_solver(
    const std::string                       matrixFile
    ,const bool                             testTranspose
    ,const int                              numRandomVectors
    ,const double                           maxFwdError
    ,const double                           maxResid
    ,const double                           maxSolutionError
    ,const bool                             showAllTests
    ,const bool                             dumpAll
    ,Teuchos::ParameterList                 *aztecooLOWSFPL
    ,Teuchos::FancyOStream                  *out_arg
)
{
    using Teuchos::rcp;
    using Teuchos::RCP;
    using Teuchos::OSTab;
    typedef Teuchos::ParameterList::PrintOptions PLPrintOptions;
    bool result, success = true;

    RCP<Teuchos::FancyOStream>
    out = Teuchos::rcp(out_arg,false);

    try {

#ifndef SUN_CXX

        if(out.get()) {
            *out
                    << "\n***"
                    << "\n*** Testing Thyra::AztecOOLinearOpWithSolveFactory (and Thyra::AztecOOLinearOpWithSolve)"
                    << "\n***\n"
                    << "\nEchoing input options:"
                    << "\n  matrixFile             = " << matrixFile
                    << "\n  testTranspose          = " << testTranspose
                    << "\n  numRandomVectors       = " << numRandomVectors
                    << "\n  maxFwdError            = " << maxFwdError
                    << "\n  maxResid               = " << maxResid
                    << "\n  showAllTests           = " << showAllTests
                    << "\n  dumpAll                = " << dumpAll
                    << std::endl;
        }

        const bool useAztecPrec = (
                                      aztecooLOWSFPL
                                      &&
                                      aztecooLOWSFPL->sublist("Forward Solve")
                                      .sublist("AztecOO Settings")
                                      .get("Aztec Preconditioner","none")!="none"
                                  );

        if(out.get()) {
            if(useAztecPrec)
                *out << "\nUsing aztec preconditioning so we will not test adjoint solves using internal preconditioning ...\n";
        }

        if(out.get()) *out << "\nA) Reading in an epetra matrix A from the file \'"<<matrixFile<<"\' ...\n";

#ifdef HAVE_MPI
        Epetra_MpiComm comm(MPI_COMM_WORLD);
#else
        Epetra_SerialComm comm;
#endif
        RCP<Epetra_CrsMatrix> epetra_A;
        EpetraExt::readEpetraLinearSystem( matrixFile, comm, &epetra_A );

        RCP<const LinearOpBase<double> > A = Thyra::epetraLinearOp(epetra_A);

        if(out.get() && dumpAll) *out << "\ndescribe(A) =\n" << describe(*A,Teuchos::VERB_EXTREME);

        if(out.get()) *out << "\nB) Creating a AztecOOLinearOpWithSolveFactory object opFactory ...\n";

        RCP<LinearOpWithSolveFactoryBase<double> >
        lowsFactory = Teuchos::rcp(new AztecOOLinearOpWithSolveFactory());
        if(out.get()) {
            *out << "\nlowsFactory.getValidParameters() initially:\n";
            lowsFactory->getValidParameters()->print(OSTab(out).o(),PLPrintOptions().showTypes(true).showDoc(true));
        }
        aztecooLOWSFPL->sublist("Forward Solve").set("Tolerance",maxResid);
        aztecooLOWSFPL->sublist("Adjoint Solve").set("Tolerance",maxResid);
        if(showAllTests) {
            aztecooLOWSFPL->set("Output Every RHS",bool(true));
        }
        if(out.get()) {
            *out << "\naztecooLOWSFPL before setting parameters:\n";
            aztecooLOWSFPL->print(OSTab(out).o(),0,true);
        }
        if(aztecooLOWSFPL) lowsFactory->setParameterList(Teuchos::rcp(aztecooLOWSFPL,false));

        if(out.get()) *out << "\nC) Creating a AztecOOLinearOpWithSolve object nsA from A ...\n";

        RCP<LinearOpWithSolveBase<double> >
        nsA = lowsFactory->createOp();

        Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());

        if(out.get()) *out << "\nD) Testing the LinearOpBase interface of nsA ...\n";

        LinearOpTester<double> linearOpTester;
        linearOpTester.check_adjoint(testTranspose);
        linearOpTester.num_random_vectors(numRandomVectors);
        linearOpTester.set_all_error_tol(maxFwdError);
        linearOpTester.set_all_warning_tol(1e-2*maxFwdError);
        linearOpTester.show_all_tests(showAllTests);
        linearOpTester.dump_all(dumpAll);
        Thyra::seed_randomize<double>(0);
        result = linearOpTester.check(*nsA,out());
        if(!result) success = false;

        if(out.get()) *out << "\nE) Testing the LinearOpWithSolveBase interface of nsA ...\n";

        LinearOpWithSolveTester<double> linearOpWithSolveTester;
        linearOpWithSolveTester.turn_off_all_tests();
        linearOpWithSolveTester.check_forward_default(true);
        linearOpWithSolveTester.check_forward_residual(true);
        if(testTranspose && useAztecPrec) {
            linearOpWithSolveTester.check_adjoint_default(true);
            linearOpWithSolveTester.check_adjoint_residual(true);
        }
        else {
            linearOpWithSolveTester.check_adjoint_default(false);
            linearOpWithSolveTester.check_adjoint_residual(false);
        }
        linearOpWithSolveTester.set_all_solve_tol(maxResid);
        linearOpWithSolveTester.set_all_slack_error_tol(maxResid);
        linearOpWithSolveTester.set_all_slack_warning_tol(10.0*maxResid);
        linearOpWithSolveTester.forward_default_residual_error_tol(2.5*maxResid);
        linearOpWithSolveTester.forward_default_solution_error_error_tol(maxSolutionError);
        linearOpWithSolveTester.adjoint_default_residual_error_tol(2.5*maxResid);
        linearOpWithSolveTester.adjoint_default_solution_error_error_tol(maxSolutionError);
        linearOpWithSolveTester.show_all_tests(showAllTests);
        linearOpWithSolveTester.dump_all(dumpAll);
        Thyra::seed_randomize<double>(0);
        result = linearOpWithSolveTester.check(*nsA,out.get());
        if(!result) success = false;

        if(out.get()) *out << "\nF) Uninitialize nsA, create preconditioner for diagonal scaled by 0.99 and then reinitialize nsA reusing the old preconditioner ...\n";

        // Scale the diagonal of the matrix and then create the preconditioner for it
        Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
        // Above is not required but a good idea since we are changing the matrix
        {
            Epetra_Vector diag(epetra_A->RowMap());
            epetra_A->ExtractDiagonalCopy(diag);
            diag.Scale(0.5);
            epetra_A->ReplaceDiagonalValues(diag);
        }
        Thyra::initializeOp<double>(*lowsFactory, A, nsA.ptr());

        // Scale the matrix back again and then reuse the preconditioner
        Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
        // Above is not required but a good idea since we are changing the matrix
        {
            Epetra_Vector diag(epetra_A->RowMap());
            epetra_A->ExtractDiagonalCopy(diag);
            diag.Scale(1.0/0.5);
            epetra_A->ReplaceDiagonalValues(diag);
        }
        initializeAndReuseOp<double>(*lowsFactory, A, nsA.ptr());

        if(out.get()) *out << "\nG) Testing the LinearOpWithSolveBase interface of nsA ...\n";

        Thyra::seed_randomize<double>(0);
        result = linearOpWithSolveTester.check(*nsA,out.get());
        if(!result) success = false;

        if(useAztecPrec) {

            if(out.get()) *out << "\nH) Reinitialize (A,A,PRECONDITIONER_INPUT_TYPE_AS_MATRIX) => nsA ...\n";

            initializeApproxPreconditionedOp<double>(*lowsFactory, A, A, nsA.ptr());

            if(out.get()) *out << "\nI) Testing the LinearOpWithSolveBase interface of nsA ...\n";

            Thyra::seed_randomize<double>(0);
            result = linearOpWithSolveTester.check(*nsA,out.get());
            if(!result) success = false;

            if(testTranspose && useAztecPrec) {
                linearOpWithSolveTester.check_adjoint_default(true);
                linearOpWithSolveTester.check_adjoint_residual(true);
            }
            else {
                linearOpWithSolveTester.check_adjoint_default(false);
                linearOpWithSolveTester.check_adjoint_residual(false);
            }

        }
        else {

            if(out.get()) *out << "\nSkipping testing steps H and I since we are not using aztec preconditioning and therefore will not test with an external preconditioner matrix!\n";

        }


        RCP<PreconditionerFactoryBase<double> >
        precFactory;

#ifdef HAVE_AZTECOO_IFPACK

        if(useAztecPrec) {

            if(testTranspose) {
                linearOpWithSolveTester.check_adjoint_default(true);
                linearOpWithSolveTester.check_adjoint_residual(true);
            }

            if(out.get()) *out << "\nJ) Create an ifpack preconditioner precA for A ...\n";

            precFactory = Teuchos::rcp(new IfpackPreconditionerFactory());

            if(out.get()) {
                *out << "\nprecFactory.description() = " << precFactory->description() << std::endl;
                *out << "\nprecFactory.getValidParameters() =\n";
                precFactory->getValidParameters()->print(OSTab(out).o(),0,true,false);
            }

            RCP<Teuchos::ParameterList>
            ifpackPFPL = Teuchos::rcp(new Teuchos::ParameterList("IfpackPreconditionerFactory"));
            ifpackPFPL->set("Prec Type","ILUT");
            ifpackPFPL->set("Overlap",int(1));
            if(out.get()) {
                *out << "\nifpackPFPL before setting parameters =\n";
                ifpackPFPL->print(OSTab(out).o(),0,true);
            }

            precFactory->setParameterList(ifpackPFPL);

            RCP<PreconditionerBase<double> >
            precA = precFactory->createPrec();
            Thyra::initializePrec<double>(*precFactory,A,&*precA);

            if(out.get()) {
                *out << "\nifpackPFPL after setting parameters =\n";
                ifpackPFPL->print(OSTab(out).o(),0,true);
                *out << "\nprecFactory.description() = " << precFactory->description() << std::endl;
            }

            if(out.get()) *out << "\nprecA.description() = " << precA->description() << std::endl;
            if(out.get() && dumpAll) *out << "\ndescribe(precA) =\n" << describe(*precA,Teuchos::VERB_EXTREME);

            if(out.get()) *out << "\nK) Reinitialize (A,precA->getUnspecifiedPrecOp(),PRECONDITIONER_INPUT_TYPE_AS_OPERATOR) => nsA ...\n";

            Thyra::initializePreconditionedOp<double>(*lowsFactory,A,precA,&*nsA);

            if(out.get()) *out << "\nL) Testing the LinearOpWithSolveBase interface of nsA ...\n";

            Thyra::seed_randomize<double>(0);
            result = linearOpWithSolveTester.check(*nsA,out.get());
            if(!result) success = false;

            if(testTranspose && useAztecPrec) {
                linearOpWithSolveTester.check_adjoint_default(true);
                linearOpWithSolveTester.check_adjoint_residual(true);
            }
            else {
                linearOpWithSolveTester.check_adjoint_default(false);
                linearOpWithSolveTester.check_adjoint_residual(false);
            }

        }
        else {

            if(out.get()) *out << "\nSkipping testing steps J, K, and L since we are not using aztec preconditioning and therefore will not test with an ifpack preconditioner!\n";

        }

#else // HAVE_AZTECOO_IFPACK

        if(out.get()) *out << "\nSkipping testing steps J, K, and L since they require ifpack and ifpack has not been enabled!\n";

#endif // HAVE_AZTECOO_IFPACK


        if(out.get()) *out << "\nM) Scale the epetra_A object by 2.5, and then reinitialize nsA with epetra_A ...\n";

        Thyra::uninitializeOp<double>(*lowsFactory, nsA.ptr());
        // Not required but a good idea since we are changing the matrix
        epetra_A->Scale(2.5);
        initializeOp<double>(*lowsFactory, A, nsA.ptr());

        if(out.get()) *out << "\nN) Testing the LinearOpWithSolveBase interface of nsA ...\n";

        Thyra::seed_randomize<double>(0);
        result = linearOpWithSolveTester.check(*nsA,out.get());
        if(!result) success = false;

        if(out.get()) *out << "\nO) Create a scaled (by 2.5) copy epetra_A2 of epetra_A, and then reinitialize nsA with epetra_A2 ...\n";

        RCP<Epetra_CrsMatrix>
        epetra_A2 = Teuchos::rcp(new Epetra_CrsMatrix(*epetra_A));
        epetra_A2->Scale(2.5);
        RCP<const LinearOpBase<double> >
        A2 = Thyra::epetraLinearOp(epetra_A2);
        initializeOp<double>(*lowsFactory, A2, nsA.ptr());
        // Note that it was okay not to uninitialize nsA first here since A, which
        // was used to initialize nsA last, was not changed and therefore the
        // state of nsA was fine throughout

        if(out.get()) *out << "\nP) Testing the LinearOpWithSolveBase interface of nsA ...\n";

        Thyra::seed_randomize<double>(0);
        result = linearOpWithSolveTester.check(*nsA,out.get());
        if(!result) success = false;

        if(!useAztecPrec) {

            if(out.get()) *out << "\nQ) Create an implicitly scaled (by 2.5) and transposed matrix A3 = scale(2.5,transpose(A)) and initialize nsA2 ...\n";

            RCP<const LinearOpBase<double> >
            A3 = scale<double>(2.5,transpose<double>(A));
            RCP<LinearOpWithSolveBase<double> >
            nsA2 = linearOpWithSolve(*lowsFactory,A3);

            if(out.get()) *out << "\nR) Testing the LinearOpWithSolveBase interface of nsA2 ...\n";

            Thyra::seed_randomize<double>(0);
            result = linearOpWithSolveTester.check(*nsA2,out.get());
            if(!result) success = false;

            if(out.get()) *out << "\nS) Testing that LinearOpBase interfaces of transpose(nsA) == nsA2 ...\n";

            result = linearOpTester.compare(
                         *transpose(Teuchos::rcp_implicit_cast<const LinearOpBase<double> >(nsA)),*nsA2
                         ,out()
                     );
            if(!result) success = false;

        }
        else {

            if(out.get()) *out << "\nSkipping testing steps Q, R, and S because we are using internal AztecOO preconditioners!\n";

        }

        if(out.get()) *out << "\nT) Running example use cases ...\n";

        nonExternallyPreconditionedLinearSolveUseCases(
            *A,*lowsFactory,testTranspose,*out
        );

        if(precFactory.get()) {
            externallyPreconditionedLinearSolveUseCases(
                *A,*lowsFactory,*precFactory,false,true,*out
            );
        }

#else // SUN_CXX

        if(out.get()) *out << "\nTest failed since is was not even compiled since SUN_CXX was defined!\n";
        success = false;

#endif // SUN_CXX

    }
    catch( const std::exception &excpt ) {
        std::cerr << "\n*** Caught standard exception : " << excpt.what() << std::endl;
        success = false;
    }

    return success;

}
void DefaultModelEvaluatorWithSolveFactory<Scalar>::evalModelImpl(
  const ModelEvaluatorBase::InArgs<Scalar> &inArgs,
  const ModelEvaluatorBase::OutArgs<Scalar> &outArgs
  ) const
{
  typedef ModelEvaluatorBase MEB;
  using Teuchos::rcp;
  using Teuchos::rcp_const_cast;
  using Teuchos::rcp_dynamic_cast;
  using Teuchos::OSTab;

  THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_BEGIN(
    "Thyra::DefaultModelEvaluatorWithSolveFactory",inArgs,outArgs
    );

  Teuchos::Time timer("");

  typedef Teuchos::VerboseObjectTempState<LinearOpWithSolveFactoryBase<Scalar> >
    VOTSLOWSF;
  VOTSLOWSF W_factory_outputTempState(W_factory_,out,verbLevel);

  // InArgs

  MEB::InArgs<Scalar> wrappedInArgs = thyraModel->createInArgs();

  wrappedInArgs.setArgs(inArgs,true);

  // OutArgs

  MEB::OutArgs<Scalar> wrappedOutArgs = thyraModel->createOutArgs();

  wrappedOutArgs.setArgs(outArgs,true);

  RCP<LinearOpWithSolveBase<Scalar> > W;
  RCP<const LinearOpBase<Scalar> > fwdW;
  if( outArgs.supports(MEB::OUT_ARG_W) && (W = outArgs.get_W()).get() ) {
    Thyra::uninitializeOp<Scalar>(*W_factory_, W.ptr(), outArg(fwdW));

    {
      // Handle this case later if we need to!
      const bool both_W_and_W_op_requested = nonnull(outArgs.get_W_op());
      TEUCHOS_TEST_FOR_EXCEPT(both_W_and_W_op_requested);
    }

    RCP<LinearOpBase<Scalar> > nonconst_fwdW;
    if(fwdW.get()) {
      nonconst_fwdW = rcp_const_cast<LinearOpBase<Scalar> >(fwdW);
    }
    else {
      nonconst_fwdW = thyraModel->create_W_op();
      fwdW = nonconst_fwdW;
    }

    wrappedOutArgs.set_W_op(nonconst_fwdW);
  }

  // Do the evaluation

  if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
    *out << "\nEvaluating the output functions on model \'"
         << thyraModel->description() << "\' ...\n";
  timer.start(true);

  thyraModel->evalModel(wrappedInArgs,wrappedOutArgs);

  timer.stop();
  if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
    OSTab(out).o() << "\nTime to evaluate underlying model = "
                   << timer.totalElapsedTime()<<" sec\n";

  // Postprocess arguments

  if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
    *out << "\nPost processing the output objects ...\n";
  timer.start(true);

  if( W.get() ) {
    Thyra::initializeOp<Scalar>(*W_factory_, fwdW, W.ptr());
    W->setVerbLevel(this->getVerbLevel());
    W->setOStream(this->getOStream());
  }

  timer.stop();
  if(out.get() && includesVerbLevel(verbLevel,Teuchos::VERB_LOW))
    OSTab(out).o() << "\nTime to process output objects = "
                   << timer.totalElapsedTime()<<" sec\n";

  THYRA_MODEL_EVALUATOR_DECORATOR_EVAL_MODEL_END();

}
Beispiel #9
0
  //
  // Test for TimeMonitor's enableTimer and disableTimer methods.
  //
  TEUCHOS_UNIT_TEST( TimeMonitor, enableTimer )
  {
    using Teuchos::Array;
    using Teuchos::OSTab;
    using Teuchos::ParameterList;
    using Teuchos::parameterList;
    using Teuchos::RCP;
    using Teuchos::rcpFromRef;
    using Teuchos::Time;
    using Teuchos::TimeMonitor;
    using std::endl;
    typedef Teuchos::Array<RCP<Time> >::size_type size_type;

    out << "Testing TimeMonitor's disableTimer() and enableTimer() methods"
        << endl;
    OSTab (rcpFromRef (out));

    out << "Creating timers" << endl;
    const int numTrials = 5;
    const int numTimers = 3;
    Array<RCP<Time> > timers (numTimers);
    for (size_type i = 0; i < numTimers; ++i) {
      std::ostringstream os; // construct timer name
      os << "Timer " << i;
      timers[i] = TimeMonitor::getNewTimer (os.str ());
    }

    out << "Running all timers without disabling any" << endl;
    // The actual number of operations in slowloop is proportional to
    // the cube of the loop length.  Adjust loopLength as necessary to
    // ensure the timer reports a nonzero elapsed time for each of the
    // invocations.
    const size_t loopLength = 25;
    for (int k = 0; k < numTrials; ++k) {
      for (size_type i = 0; i < numTimers; ++i) {
        TimeMonitor timeMon (* timers[i]);
        slowLoop (loopLength);
      }
    }
    for (size_type i = 0; i < numTimers; ++i) {
      TEST_EQUALITY( timers[i]->numCalls(), numTrials );
    }

    out << "Disabling one timer and trying again" << endl;
    // Disable timers[0] only, and repeat the above loops.
    TEST_NOTHROW( TimeMonitor::disableTimer ("Timer 0") );
    for (int k = 0; k < numTrials; ++k) {
      for (size_type i = 0; i < numTimers; ++i) {
        TimeMonitor timeMon (* timers[i]);
        slowLoop (loopLength);
      }
    }
    TEST_EQUALITY( timers[0]->numCalls(), numTrials );
    for (size_type i = 1; i < numTimers; ++i) {
      TEST_EQUALITY( timers[i]->numCalls(), 2*numTrials );
    }

    out << "Reenabling the timer and trying again" << endl;
    // Enable timers[0] and repeat the above loops.
    TEST_NOTHROW( TimeMonitor::enableTimer ("Timer 0") );
    for (int k = 0; k < numTrials; ++k) {
      for (size_type i = 0; i < numTimers; ++i) {
        TimeMonitor timeMon (* timers[i]);
        slowLoop (loopLength);
      }
    }
    TEST_EQUALITY( timers[0]->numCalls(), 2*numTrials );
    for (size_type i = 1; i < numTimers; ++i) {
      TEST_EQUALITY( timers[i]->numCalls(), 3*numTrials );
    }

    out << "Test that summarize() reports enabled and disabled timers" << endl;
    // Make sure that summarize() reports all timers.  Disabling a
    // timer must _not_ exclude it from the list of timers printed by
    // summarize().  Disable a different timer this time just for fun.
    TEST_NOTHROW( TimeMonitor::disableTimer ("Timer 1") );
    {
      std::ostringstream oss;
      TimeMonitor::summarize (oss);

      // Echo summarize() output to the FancyOStream out (which is a
      // standard unit test argument).  Output should only appear in
      // show-all-test-details mode.
      out << oss.str () << std::endl;

      // Make sure that each timer's name shows up in the output.
      for (size_type i = 0; i < numTimers; ++i) {
        const std::string name = timers[i]->name ();
        const size_t substr_i = oss.str ().find (name);
        TEST_INEQUALITY(substr_i, std::string::npos);
      }
    }

    // This sets up for the next unit test.
    TimeMonitor::clearCounters ();
  }
Beispiel #10
0
bool run_std_ops_tests(
  const int                                                       n
  ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType    max_rel_err
  ,const bool                                                     dumpAll
  ,Teuchos::FancyOStream                                          *out_arg
  )
{

  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::OSTab;
  typedef Teuchos::ScalarTraits<Scalar> ST;
  typedef typename ST::magnitudeType ScalarMag;
  typedef Thyra::Ordinal Index;

  RCP<Teuchos::FancyOStream>
    out = rcp(new Teuchos::FancyOStream(rcp(out_arg,false)));

  VectorStdOpsTester<Scalar> vectorStdOpsTester;
  vectorStdOpsTester.warning_tol(ScalarMag(0.1)*max_rel_err);
  vectorStdOpsTester.error_tol(max_rel_err);
  MultiVectorStdOpsTester<Scalar> multiVectorStdOpsTester;
  multiVectorStdOpsTester.warning_tol(ScalarMag(0.1)*max_rel_err);
  multiVectorStdOpsTester.error_tol(max_rel_err);

  if(out.get()) *out << "\n*** Entering run_std_ops_tests<"<<ST::name()<<">(...) ...\n";

  bool success = true;

  if(out.get()) *out << "\nCreating a serial vector space svs with n="<<n<<" vector elements ...\n";

  const RCP<const Teuchos::Comm<Ordinal> >
    comm = Teuchos::DefaultComm<Ordinal>::getComm();

  const RCP<Thyra::VectorSpaceBase<Scalar> > svs =
    Thyra::defaultSpmdVectorSpace<Scalar>(comm,n,-1);

  if(out.get()) *out << "\nTesting standard vector ops with svs ...\n";
  if(!vectorStdOpsTester.checkStdOps(*svs, OSTab(out).get(), dumpAll)) success = false;

  if(out.get()) *out << "\nTesting standard multi-vector ops with svs ...\n";
  if(!multiVectorStdOpsTester.checkStdOps(*svs, OSTab(out).get(), dumpAll)) success = false;

  const int numBlocks = 3;

  if(out.get()) *out << "\nCreating a product space pvs with numBlocks="<<numBlocks<<" and n="<<n<<"vector elements per block ...\n";

  Teuchos::Array<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > >
    vecSpaces(numBlocks);
  Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
    spaceBlock = Thyra::defaultSpmdVectorSpace<Scalar>(comm,n,-1);
  for( int i = 0; i < numBlocks; ++i )
    vecSpaces[i] = spaceBlock;

  RCP<Thyra::DefaultProductVectorSpace<Scalar> > pvs =
    rcp(new Thyra::DefaultProductVectorSpace<Scalar>(numBlocks,&vecSpaces[0]));

  if(out.get()) *out << "\nTesting standard vector ops with pvs ...\n";
  if(!vectorStdOpsTester.checkStdOps(*pvs, OSTab(out).get(), dumpAll)) success = false;

  if(out.get()) *out << "\nTesting standard multi-vector ops with pvs ...\n";
  if(!multiVectorStdOpsTester.checkStdOps(*pvs, OSTab(out).get(), dumpAll)) success = false;

  if(out.get()) *out << "\nCreating a nested product space ppvs with numBlocks="<<numBlocks<<" product spaces as components ...\n";

  Teuchos::Array<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > >
    blockVecSpaces(numBlocks);
  for( int i = 0; i < numBlocks; ++i )
    blockVecSpaces[i] = pvs;

  RCP<Thyra::DefaultProductVectorSpace<Scalar> > ppvs = 
    rcp(new Thyra::DefaultProductVectorSpace<Scalar>(numBlocks, &blockVecSpaces[0]));

  if(out.get()) *out << "\nTesting standard vector ops with ppvs ...\n";
  if(!vectorStdOpsTester.checkStdOps(*ppvs, OSTab(out).get(), dumpAll)) success = false;

  if(out.get()) *out << "\nTesting standard multi-vector ops with ppvs ...\n";
  if(!multiVectorStdOpsTester.checkStdOps(*ppvs, OSTab(out).get(), dumpAll)) success = false;

  return success;

}