Thyra_DefaultColumnwiseMultiVector.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
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 THYRA_MULTI_VECTOR_COLS_HPP
00030 #define THYRA_MULTI_VECTOR_COLS_HPP
00031 
00032 #include "Thyra_DefaultColumnwiseMultiVectorDecl.hpp"
00033 #include "Thyra_MultiVectorDefaultBase.hpp"
00034 #include "Thyra_VectorSpaceBase.hpp"
00035 #include "Thyra_VectorBase.hpp"
00036 #include "Thyra_SingleRhsLinearOpBase.hpp"
00037 #include "Thyra_MultiVectorBase.hpp"
00038 #include "Thyra_VectorSpaceFactoryBase.hpp"
00039 #include "Teuchos_TestForException.hpp"
00040 #include "Teuchos_as.hpp"
00041 
00042 namespace Thyra {
00043 
00044 
00045 // Constructors/Initializers
00046 
00047 
00048 template<class Scalar>
00049 DefaultColumnwiseMultiVector<Scalar>::DefaultColumnwiseMultiVector()
00050 {}
00051 
00052 
00053 template<class Scalar>
00054 DefaultColumnwiseMultiVector<Scalar>::DefaultColumnwiseMultiVector(
00055   const RCP<VectorBase<Scalar> > &col_vec
00056   )
00057 {
00058   this->initialize(col_vec);
00059 }
00060 
00061 
00062 template<class Scalar>
00063 DefaultColumnwiseMultiVector<Scalar>::DefaultColumnwiseMultiVector(
00064   const RCP<const VectorSpaceBase<Scalar> > &range_in,
00065   const RCP<const VectorSpaceBase<Scalar> > &domain_in,
00066   const ArrayView<const RCP<VectorBase<Scalar> > > &col_vecs_in
00067   )
00068 {
00069   this->initialize(range_in, domain_in, col_vecs_in);
00070 }
00071 
00072 
00073 template<class Scalar>
00074 void DefaultColumnwiseMultiVector<Scalar>::initialize(
00075   const RCP<VectorBase<Scalar> > &col_vec
00076   )
00077 {
00078 #ifdef TEUCHOS_DEBUG
00079   const std::string err_msg =
00080     "DefaultColumnwiseMultiVector<Scalar>::initialize(...): Error!";
00081   TEST_FOR_EXCEPT_MSG( is_null(col_vec), err_msg ); 
00082   TEST_FOR_EXCEPT_MSG( is_null(col_vec->space()), err_msg ); 
00083 #endif
00084   range_  = col_vec->space();
00085   domain_ = range_->smallVecSpcFcty()->createVecSpc(1);
00086   col_vecs_.resize(1);
00087   col_vecs_[0] = col_vec;
00088 }
00089 
00090   
00091 template<class Scalar>
00092 void DefaultColumnwiseMultiVector<Scalar>::initialize(
00093   const RCP<const VectorSpaceBase<Scalar> > &range_in,
00094   const RCP<const VectorSpaceBase<Scalar> > &domain_in,
00095   const ArrayView<const RCP<VectorBase<Scalar> > > &col_vecs
00096   )
00097 {
00098 #ifdef TEUCHOS_DEBUG
00099   const std::string err_msg =
00100     "DefaultColumnwiseMultiVector<Scalar>::initialize(...): Error!";
00101   TEST_FOR_EXCEPT_MSG( is_null(range_in), err_msg ); 
00102   TEST_FOR_EXCEPT_MSG( is_null(domain_in), err_msg ); 
00103   TEST_FOR_EXCEPT_MSG( range_in->dim()  == 0, err_msg ); 
00104   TEST_FOR_EXCEPT_MSG( domain_in->dim() == 0, err_msg );
00105   // ToDo: Check the compatibility of the vectors in col_vecs!
00106 #endif
00107   const int domainDim = domain_in->dim();
00108   range_ = range_in;
00109   domain_ = domain_in;
00110   col_vecs_.clear();
00111   col_vecs_.reserve(domainDim);
00112   if (col_vecs.size()) {
00113     for( Index j = 0; j < domainDim; ++j )
00114       col_vecs_.push_back(col_vecs[j]);
00115   }
00116   else {
00117     for( Index j = 0; j < domainDim; ++j )
00118       col_vecs_.push_back(createMember(range_));
00119   }
00120 }
00121 
00122 
00123 template<class Scalar>
00124 void DefaultColumnwiseMultiVector<Scalar>::set_uninitialized()
00125 {
00126   col_vecs_.resize(0);
00127   range_ = Teuchos::null;
00128   domain_ = Teuchos::null;
00129 }
00130 
00131 
00132 // Overridden from OpBase
00133 
00134 
00135 template<class Scalar>
00136 RCP<const VectorSpaceBase<Scalar> >
00137 DefaultColumnwiseMultiVector<Scalar>::range() const
00138 {
00139   return range_;
00140 }
00141 
00142 
00143 template<class Scalar>
00144 RCP<const VectorSpaceBase<Scalar> >
00145 DefaultColumnwiseMultiVector<Scalar>::domain() const
00146 {
00147   return domain_;
00148 }
00149 
00150 
00151 // Overridden from SingleRhsLinearOpBase
00152 
00153 
00154 template<class Scalar>
00155 bool DefaultColumnwiseMultiVector<Scalar>::opSupported(EOpTransp M_trans) const
00156 {
00157   typedef Teuchos::ScalarTraits<Scalar> ST;
00158   return ( ST::isComplex ? ( M_trans==NOTRANS || M_trans==CONJTRANS ) : true );
00159 }
00160 
00161 
00162 template<class Scalar>
00163 void DefaultColumnwiseMultiVector<Scalar>::apply(
00164   const EOpTransp                M_trans
00165   ,const VectorBase<Scalar>    &x
00166   ,VectorBase<Scalar>          *y
00167   ,const Scalar                alpha
00168   ,const Scalar                beta
00169   ) const
00170 {
00171 #ifdef TEUCHOS_DEBUG
00172   THYRA_ASSERT_LINEAR_OP_VEC_APPLY_SPACES(
00173     "MultiVectorBase<Scalar>::apply()",*this,M_trans,x,y);
00174 #endif
00175   const Index nc = this->domain()->dim();
00176   // y *= beta
00177   Vt_S(y,beta);
00178   // y += alpha*op(M)*x
00179   if(M_trans == NOTRANS) {
00180     //
00181     // y += alpha*M*x = alpha*M.col(0)*x(0) + ... + alpha*M.col(nc-1)*x(nc-1)
00182     //
00183     // Extract an explicit view of x
00184     RTOpPack::ConstSubVectorView<Scalar> x_sub_vec;               
00185     x.acquireDetachedView(Range1D(),&x_sub_vec);
00186     // Loop through and add the multiple of each column
00187     for(Index j = 0; j < nc; ++j )
00188       Vp_StV( y, Scalar(alpha*x_sub_vec(j)), *this->col(j) );
00189     // Release the view of x
00190     x.releaseDetachedView(&x_sub_vec);
00191   }
00192   else {
00193     //
00194     //                    [ alpha*dot(M.col(0),x)    ]
00195     // y += alpha*M^T*x = [ alpha*dot(M.col(1),x)    ]
00196     //                    [ ...                      ]
00197     //                    [ alpha*dot(M.col(nc-1),x) ]
00198     //
00199     // Extract an explicit view of y
00200     RTOpPack::SubVectorView<Scalar> y_sub_vec;               
00201     y->acquireDetachedView(Range1D(),&y_sub_vec);
00202     // Loop through and add to each element in y
00203     for(Index j = 0; j < nc; ++j )
00204       y_sub_vec(j) += alpha*dot(*this->col(j),x);
00205     // Commit explicit view of y
00206     y->commitDetachedView(&y_sub_vec);
00207   }
00208 }
00209 
00210 
00211 // Overridden from MultiVectorBase
00212 
00213 
00214 template<class Scalar>
00215 RCP<VectorBase<Scalar> >
00216 DefaultColumnwiseMultiVector<Scalar>::nonconstColImpl(Index j)
00217 {
00218   using Teuchos::as;
00219   const int num_cols = col_vecs_.size();
00220   TEST_FOR_EXCEPTION(
00221     !(  0 <= j  && j < num_cols ), std::logic_error
00222     ,"Error, j = " << j << " does not fall in the range [0,"<<(num_cols-1)<< "]!"
00223     );
00224   return col_vecs_[j];
00225 }
00226 
00227 
00228 template<class Scalar>
00229 RCP<MultiVectorBase<Scalar> >
00230 DefaultColumnwiseMultiVector<Scalar>::nonconstContigSubViewImpl(
00231   const Range1D& col_rng_in
00232   )
00233 {
00234   const Index numCols = domain_->dim();
00235   const Range1D col_rng = Teuchos::full_range(col_rng_in,0,numCols-1);
00236 #ifdef TEUCHOS_DEBUG
00237   TEST_FOR_EXCEPTION(
00238     !( col_rng.ubound() < numCols ), std::logic_error
00239     ,"DefaultColumnwiseMultiVector<Scalar>::subView(col_rng):"
00240     "Error, the input range col_rng = ["<<col_rng.lbound()
00241     <<","<<col_rng.ubound()<<"] "
00242     "is not in the range [0,"<<(numCols-1)<<"]!"
00243     );
00244 #endif
00245   return Teuchos::rcp(
00246     new DefaultColumnwiseMultiVector<Scalar>(
00247       range_,
00248       domain_->smallVecSpcFcty()->createVecSpc(col_rng.size()),
00249       col_vecs_(col_rng.lbound(),col_rng.size())
00250       )
00251     );
00252 }
00253 
00254   
00255 } // end namespace Thyra
00256 
00257 
00258 #endif // THYRA_MULTI_VECTOR_COLS_HPP

Generated on Wed May 12 21:26:53 2010 for Thyra Operator/Vector Support by  doxygen 1.4.7