TSFEuclideanOpWithBackwardsCompatibleApply.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // **********************************************************************/
00027  /* @HEADER@ */
00028 
00029 #ifndef TSFEUCLIDEANOPWITHBACKWARDSCOMPATIBLEAPPLY_HPP
00030 #define TSFEUCLIDEANOPWITHBACKWARDSCOMPATIBLEAPPLY_HPP
00031 
00032 #include "Thyra_VectorBase.hpp"
00033 #include "Thyra_MultiVectorBase.hpp"
00034 #include "Thyra_LinearOpDefaultBase.hpp"
00035 #include "Thyra_DefaultColumnwiseMultiVector.hpp"
00036 #include "Teuchos_TestForException.hpp"
00037 
00038 namespace TSFExtended
00039 {
00040 using namespace Teuchos;
00041 using namespace Thyra;
00042 
00043 /** */
00044 template <class Scalar>
00045 class EuclideanOpWithBackwardsCompatibleApply :
00046     public virtual SingleScalarEuclideanLinearOpBase<Scalar>
00047 {
00048 public:
00049 
00050   /** */
00051   EuclideanOpWithBackwardsCompatibleApply(
00052     const RCP<const ScalarProdVectorSpaceBase<Scalar> >& domain,
00053     const RCP<const ScalarProdVectorSpaceBase<Scalar> >& range)
00054     : scalarProdDomain_(domain),
00055       scalarProdRange_(range)
00056     {}
00057     
00058   /** Implements Euclidean op interface */
00059   Teuchos::RCP< const ScalarProdVectorSpaceBase<Scalar > >  
00060   rangeScalarProdVecSpc () const {return scalarProdRange_;}
00061 
00062   /** Implements Euclidean op interface */
00063   Teuchos::RCP< const ScalarProdVectorSpaceBase<Scalar > >  
00064   domainScalarProdVecSpc () const {return scalarProdDomain_;}
00065 
00066   /** Thyra EuclideanOp apply method */
00067   void euclideanApply(
00068     const Thyra::EOpTransp                             transp,
00069     const Thyra::MultiVectorBase<Scalar>    &X,
00070     Thyra::MultiVectorBase<Scalar>           *Y,
00071     const Scalar alpha,
00072     const Scalar beta
00073     ) const 
00074     {
00075       const Thyra::VectorBase<Scalar>* xVec 
00076         = dynamic_cast<const Thyra::VectorBase<Scalar>*>(&X);
00077       
00078       Thyra::VectorBase<Scalar>* yVec 
00079         = dynamic_cast<Thyra::VectorBase<Scalar>*>(Y);
00080       
00081       if (xVec != 0 && yVec != 0)
00082       {
00083         generalApply(transp, *xVec, yVec, alpha, beta);
00084       }
00085       else if (xVec == 0 && yVec == 0)
00086       {
00087         generalApply(transp, X, Y, alpha, beta);
00088       }
00089       else if (X.domain()->dim()==1 && yVec != 0)
00090       {
00091         generalApply(transp, *(X.col(0)), yVec, alpha, beta);
00092       }
00093       else if (xVec != 0 && Y->domain()->dim()==1)
00094       {
00095         generalApply(transp, *xVec, Y->col(0).get(), alpha, beta);
00096       }
00097       else
00098       {
00099         std::cout << "nX=" << X.domain()->dim()
00100                   << ", nY=" << Y->domain()->dim() << std::endl;
00101         TEST_FOR_EXCEPTION(true, std::runtime_error,
00102           "mix of vectors and multivectors in "
00103           "OpWithBackwardsCompatibleApply::apply()");
00104       }
00105     }
00106 
00107   /** Thyra EuclideanOp apply transpose method */
00108   void euclideanApplyTranspose(
00109     const Thyra::EOpTransp                            transp,
00110     const Thyra::MultiVectorBase<Scalar>    &X,
00111     Thyra::MultiVectorBase<Scalar>         *Y,
00112     const Scalar                     alpha,
00113     const Scalar                     beta
00114     ) const 
00115     {
00116       const Thyra::VectorBase<Scalar>* xVec 
00117         = dynamic_cast<const Thyra::VectorBase<Scalar>*>(&X);
00118 
00119       Thyra::VectorBase<Scalar>* yVec 
00120         = dynamic_cast<Thyra::VectorBase<Scalar>*>(Y);
00121 
00122       if (xVec != 0 && yVec != 0)
00123       {
00124         generalApply(transp, *xVec, yVec, alpha, beta);
00125       }
00126       else if (xVec == 0 && yVec == 0)
00127       {
00128         generalApply(transp, X, Y, alpha, beta);
00129       }
00130       else if (X.domain()->dim()==1 && yVec != 0)
00131       {
00132         generalApply(transp, *(X.col(0)), yVec, alpha, beta);
00133       }
00134       else if (xVec != 0 && Y->domain()->dim()==1)
00135       {
00136         generalApply(transp, *xVec, Y->col(0).get(), 
00137           alpha, beta);
00138       }
00139       else
00140       {
00141         std::cout << "nX=" << X.domain()->dim()
00142                   << ", nY=" << Y->domain()->dim() << std::endl;
00143         TEST_FOR_EXCEPTION(true, std::runtime_error,
00144           "mix of vectors and multivectors in "
00145           "OpWithBackwardsCompatibleApply::applyTranspose()");
00146       }
00147     }
00148 
00149   /** 
00150    * 
00151    */
00152   bool opSupported(Thyra::EOpTransp tr) const 
00153     {
00154       return true;
00155     }
00156 
00157 
00158   /**
00159    * generalApply() applies either the operator or the transpose
00160    * according to the value of the transpose flag. This method is
00161    * backwards compatible with TSFCore-based code.
00162    */
00163   virtual void generalApply(const Thyra::EOpTransp M_trans,
00164     const Thyra::MultiVectorBase<Scalar>    &x,
00165     Thyra::MultiVectorBase<Scalar>          *y,
00166     const Scalar            alpha,
00167     const Scalar            beta) const 
00168     {
00169       const Thyra::DefaultColumnwiseMultiVector<Scalar>* xVec 
00170         = dynamic_cast<const Thyra::DefaultColumnwiseMultiVector<Scalar>*>(&x);
00171       
00172       Thyra::DefaultColumnwiseMultiVector<Scalar>* yVec 
00173         = dynamic_cast<Thyra::DefaultColumnwiseMultiVector<Scalar>*>(y);
00174       
00175       TEST_FOR_EXCEPTION(xVec==0, std::runtime_error, 
00176         "default implementation of "
00177         "OpWithBackwardsCompatibleApply::generalApply() requires a "
00178         "DefaultColumnwiseMultiVector");
00179       
00180       TEST_FOR_EXCEPTION(yVec==0, std::runtime_error, 
00181         "default implementation of "
00182         "OpWithBackwardsCompatibleApply::generalApply() requires a "
00183         "DefaultColumnwiseMultiVector");
00184       
00185       int nXCols = x.domain()->dim();
00186       int nYCols = y->domain()->dim();
00187       
00188       TEST_FOR_EXCEPTION(nXCols != nYCols, std::runtime_error, 
00189         "mismatched multivector sizes nX=" << nXCols 
00190         << " and nY=" << nYCols);
00191       
00192       for (int i=0; i<nXCols; i++)
00193       {
00194         generalApply(M_trans, *(xVec->col(i).get()), 
00195           (yVec->col(i).get()), alpha, beta);
00196       }
00197     }
00198 
00199 
00200   
00201 
00202   /**
00203    *
00204    */
00205   virtual void generalApply(const Thyra::EOpTransp M_trans,
00206     const Thyra::VectorBase<Scalar>    &x,
00207     Thyra::VectorBase<Scalar>* y,
00208     const Scalar alpha = Teuchos::ScalarTraits<Scalar>::one(),
00209     const Scalar beta  = Teuchos::ScalarTraits<Scalar>::zero()) const = 0 ;
00210   
00211 
00212 private:
00213   RCP<const ScalarProdVectorSpaceBase<Scalar> > scalarProdDomain_;
00214   RCP<const ScalarProdVectorSpaceBase<Scalar> > scalarProdRange_;
00215 };
00216 
00217 }
00218 
00219 #endif

Site Contact