Thyra_DefaultClusteredSpmdProductVectorSpace.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_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
00030 #define THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP
00031 
00032 #include "Thyra_DefaultClusteredSpmdProductVectorSpaceDecl.hpp"
00033 #include "Thyra_SpmdVectorSpaceBase.hpp"
00034 #include "Thyra_DefaultClusteredSpmdProductVector.hpp"
00035 #include "Thyra_VectorSpaceDefaultBase.hpp"
00036 #include "Thyra_VectorStdOps.hpp"
00037 #include "Thyra_MultiVectorStdOps.hpp"
00038 #include "Thyra_SpmdVectorSpaceUtilities.hpp"
00039 #include "Teuchos_implicit_cast.hpp"
00040 #include "Teuchos_CommHelpers.hpp"
00041 
00042 namespace Thyra {
00043 
00044 // Constructors/Intializers/Accessors
00045 
00046 template<class Scalar>
00047 DefaultClusteredSpmdProductVectorSpace<Scalar>::DefaultClusteredSpmdProductVectorSpace()
00048   :isEuclidean_(false),globalDim_(0),clusterSubDim_(-1),clusterOffset_(-1)
00049 {}
00050 
00051 template<class Scalar>
00052 DefaultClusteredSpmdProductVectorSpace<Scalar>::DefaultClusteredSpmdProductVectorSpace(
00053   const Teuchos::RCP<const Teuchos::Comm<Index> >          &intraClusterComm
00054   ,const int                                                       clusterRootRank
00055   ,const Teuchos::RCP<const Teuchos::Comm<Index> >         &interClusterComm
00056   ,const int                                                       numBlocks
00057   ,const Teuchos::RCP<const VectorSpaceBase<Scalar> >      vecSpaces[]
00058   )
00059 {
00060   initialize(intraClusterComm,clusterRootRank,interClusterComm,numBlocks,vecSpaces);
00061 }
00062 
00063 template<class Scalar>
00064 void DefaultClusteredSpmdProductVectorSpace<Scalar>::initialize(
00065   const Teuchos::RCP<const Teuchos::Comm<Index> >          &intraClusterComm
00066   ,const int                                                       clusterRootRank
00067   ,const Teuchos::RCP<const Teuchos::Comm<Index> >         &interClusterComm
00068   ,const int                                                       numBlocks
00069   ,const Teuchos::RCP<const VectorSpaceBase<Scalar> >      vecSpaces[]
00070   )
00071 {
00072   // Set state
00073   intraClusterComm_ = intraClusterComm.assert_not_null();
00074   clusterRootRank_ = clusterRootRank;
00075   interClusterComm_ = interClusterComm; // This can be NULL!
00076   vecSpaces_.resize(numBlocks);
00077   isEuclidean_ = true;
00078   Index clusterSubDim = 0;
00079   for( int k = 0; k < numBlocks; ++k ) {
00080     clusterSubDim += vecSpaces[k]->dim();
00081     if(!vecSpaces[k]->isEuclidean())
00082       isEuclidean_ = false;
00083     vecSpaces_[k] = vecSpaces[k];
00084   }
00085   // We must compute the offsets between clusters and the global dimension by
00086   // only involving the root process in each cluster.
00087   if(interClusterComm_.get()) {
00088     clusterOffset_ = SpmdVectorSpaceUtilities::computeLocalOffset(
00089       *interClusterComm_,clusterSubDim
00090       );
00091     globalDim_ = SpmdVectorSpaceUtilities::computeGlobalDim(
00092       *interClusterComm_,clusterSubDim
00093     );
00094   }
00095   // Here must then broadcast the values to all processes within each cluster.
00096   {
00097     const Index num = 2;
00098     Index buff[num] = { clusterOffset_, globalDim_ };
00099     Teuchos::broadcast<Index>(*intraClusterComm_, clusterRootRank_, num, &buff[0]);
00100     clusterOffset_ = buff[0];
00101     globalDim_     = buff[1];
00102   }
00103   //
00104   clusterSubDim_ = clusterSubDim;
00105   // ToDo: Do a global communication across all clusters to see if all vector
00106   // spaces are all Euclidean.  It is unlikely to be the case where all of the
00107   // clusters do not have the same vector spaces so I do not think this will
00108   // even come up.  But just in case, we should keep this in mind!
00109 }
00110 
00111 // Overridden form Teuchos::Describable
00112 
00113 template<class Scalar>
00114 std::string DefaultClusteredSpmdProductVectorSpace<Scalar>::description() const
00115 {
00116   std::ostringstream oss;
00117   oss << "DefaultClusteredSpmdProductVectorSpace{";
00118   oss << "numBlocks="<<vecSpaces_.size();
00119   oss << ",globalDim="<<globalDim_;
00120   oss << ",clusterOffset="<<clusterOffset_;
00121   oss << "}";
00122   return oss.str();
00123 }
00124 
00125 // Public overridden from VectorSpaceBase
00126 
00127 template<class Scalar>
00128 Index DefaultClusteredSpmdProductVectorSpace<Scalar>::dim() const
00129 {
00130   return globalDim_;
00131 }
00132 
00133 template<class Scalar>
00134 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::isCompatible(
00135   const VectorSpaceBase<Scalar>& vecSpc
00136   ) const
00137 {
00138   if( &vecSpc == this )
00139     return true;
00140   // For now, I will just do the dynamic cast but in the future, we could get
00141   // more sophisticated.
00142   TEST_FOR_EXCEPT(true);
00143   return false;
00144 }
00145 
00146 template<class Scalar>
00147 Teuchos::RCP< const VectorSpaceFactoryBase<Scalar> >
00148 DefaultClusteredSpmdProductVectorSpace<Scalar>::smallVecSpcFcty() const
00149 {
00150   if(!vecSpaces_.size())
00151     return Teuchos::null;
00152   return vecSpaces_[0]->smallVecSpcFcty();
00153 }
00154 
00155 template<class Scalar>
00156 Scalar DefaultClusteredSpmdProductVectorSpace<Scalar>::scalarProd(
00157   const VectorBase<Scalar>& x, const VectorBase<Scalar>& y
00158   ) const
00159 {
00160   Scalar scalarProds[1];
00161   this->scalarProds(x,y,&scalarProds[0]);
00162   return scalarProds[0];
00163 }
00164 
00165 template<class Scalar>
00166 void DefaultClusteredSpmdProductVectorSpace<Scalar>::scalarProdsImpl(
00167   const MultiVectorBase<Scalar>& X, const MultiVectorBase<Scalar>& Y,
00168   const ArrayView<Scalar> &scalarProds_out ) const
00169 {
00170   TEST_FOR_EXCEPTION(
00171     !isEuclidean_, std::logic_error
00172     ,"Error, have not implemented support for none Euclidean scalar products yet!"
00173     );
00174   return dots(X, Y, scalarProds_out);
00175   // ToDo:
00176   // * Create DefaultClusteredSpmdProductMultiVector subclass
00177   // * Cast X and Y this type
00178   // * Accumulate the scalar products across all of the blocks in this cluster
00179   // * Accumulate the full scalar products across all of the clusters
00180   //   using *interClusterComm
00181   // * Broadcast the final scalar products to all of the processes in
00182   //   a cluster using *intraClusterComm
00183 }
00184 
00185 template<class Scalar>
00186 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::isEuclidean() const
00187 {
00188   return isEuclidean_;
00189 }
00190 
00191 template<class Scalar>
00192 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::hasInCoreView(
00193   const Range1D& rng, const EViewType viewType, const EStrideType strideType
00194   ) const
00195 {
00196   return false; // ToDo: Figure this out for real!
00197 }
00198 
00199 template<class Scalar>
00200 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00201 DefaultClusteredSpmdProductVectorSpace<Scalar>::clone() const
00202 {
00203   return Teuchos::rcp(new DefaultClusteredSpmdProductVectorSpace<Scalar>(*this));
00204 }
00205 
00206 // Protected overridden from ProductVectorSpaceBase
00207 
00208 template<class Scalar>
00209 int DefaultClusteredSpmdProductVectorSpace<Scalar>::numBlocks() const
00210 {
00211   return vecSpaces_.size();
00212 }
00213 
00214 template<class Scalar>
00215 Teuchos::RCP<const VectorSpaceBase<Scalar> >
00216 DefaultClusteredSpmdProductVectorSpace<Scalar>::getBlock(const int k) const
00217 {
00218   using Teuchos::implicit_cast;
00219   TEST_FOR_EXCEPT( !( 0 <= k && k < implicit_cast<int>(vecSpaces_.size()) ) );
00220   return vecSpaces_[k];
00221 } 
00222 
00223 // Protected overridden from VectorSpaceBase
00224 
00225 template<class Scalar>
00226 Teuchos::RCP<VectorBase<Scalar> >
00227 DefaultClusteredSpmdProductVectorSpace<Scalar>::createMember() const
00228 {
00229   using Teuchos::rcp;
00230   return rcp(new DefaultClusteredSpmdProductVector<Scalar>(rcp(this,false),NULL));
00231 }
00232 
00233 template<class Scalar>
00234 Teuchos::RCP<MultiVectorBase<Scalar> >
00235 DefaultClusteredSpmdProductVectorSpace<Scalar>::createMembers(int numMembers) const
00236 {
00237   return VectorSpaceDefaultBase<Scalar>::createMembers(numMembers);
00238   // ToDo: Provide an optimized multi-vector implementation when needed!
00239 }
00240 
00241 } // end namespace Thyra
00242 
00243 #endif // THYRA_DEFAULT_CLUSTERED_SPMD_PRODUCT_VECTOR_SPACE_HPP

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