예제 #1
0
NOX::Abstract::Group::ReturnType 
NOX::Thyra::Group::applyRightPreconditioning(bool useTranspose,
					     Teuchos::ParameterList& params,
					     const NOX::Abstract::Vector& input, 
					     NOX::Abstract::Vector& result) const
{
  NOX_ASSERT(nonnull(prec_));
  
  // A nonnull prec_factory_ means we are using Jacobian for M and use
  // the prec_factory_ to produce M^{-1}.  Otherwise, we assume that
  // M^{-1} is provided directly by the user from the model evaluator.
  // Finally if the model evauator does not support a prec then just
  // use the operator the user supplied prec_ object and assume they
  // know when to update it externally.

  if (nonnull(prec_factory_)) {
    NOX_ASSERT(nonnull(losb_));

    if (!this->isJacobian())
      const_cast<NOX::Thyra::Group*>(this)->computeJacobian();
    
    this->scaleResidualAndJacobian();
    prec_factory_->initializePrec(losb_, prec_.get());
  }
  else if (out_args_.supports( ::Thyra::ModelEvaluatorBase::OUT_ARG_W_prec)) {
    in_args_.set_x(x_vec_->getThyraRCPVector().assert_not_null());
    out_args_.set_W_prec(prec_);
    model_->evalModel(in_args_, out_args_);
    in_args_.set_x(Teuchos::null);
    out_args_.set_W_prec(Teuchos::null);
  }

  const NOX::Thyra::Vector* inputThyraVectorPtr = dynamic_cast<const NOX::Thyra::Vector*>(&input);
  NOX_ASSERT(inputThyraVectorPtr != NULL);
  NOX::Thyra::Vector* resultThyraVectorPtr = dynamic_cast<NOX::Thyra::Vector*>(&result);
  NOX_ASSERT(resultThyraVectorPtr != NULL);

  // Could be left, right or unspecified
  Teuchos::RCP<const ::Thyra::LinearOpBase<double> > tmp_prec_ = prec_->getRightPrecOp();
  if (is_null(tmp_prec_))
    tmp_prec_ = prec_->getUnspecifiedPrecOp();
  NOX_ASSERT(nonnull(tmp_prec_));

  ::Thyra::apply(*tmp_prec_,
		 ::Thyra::NOTRANS,
		 *inputThyraVectorPtr->getThyraRCPVector(),
		 outArg(*resultThyraVectorPtr->getThyraRCPVector().ptr()));

  if (nonnull(prec_factory_)) 
    this->unscaleResidualAndJacobian();

  return NOX::Abstract::Group::Ok;
}
예제 #2
0
NOX::Abstract::Group::ReturnType 
NOX::Thyra::Group::applyJacobianTranspose(const NOX::Thyra::Vector& input,
					  NOX::Thyra::Vector& result) const
{
  if ( !(this->isJacobian()) ) {
    TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, 
		       "NOX Error - Jacobian is not valid.  " <<
		       "Call computeJacobian before calling applyJacobian!");
  }

  if ( ::Thyra::opSupported(*lop_, ::Thyra::TRANS) ) {
    ::Thyra::apply(*shared_jacobian_->getObject(), ::Thyra::TRANS,
		   input.getThyraVector(), result.getThyraRCPVector().ptr());
    return NOX::Abstract::Group::Ok;
  }
  return NOX::Abstract::Group::Failed;
}