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 
00041 namespace Thyra {
00042 
00043 // Constructors/Intializers/Accessors
00044 
00045 template<class Scalar>
00046 DefaultClusteredSpmdProductVectorSpace<Scalar>::DefaultClusteredSpmdProductVectorSpace()
00047   :isEuclidean_(false),globalDim_(0),clusterSubDim_(-1),clusterOffset_(-1)
00048 {}
00049 
00050 template<class Scalar>
00051 DefaultClusteredSpmdProductVectorSpace<Scalar>::DefaultClusteredSpmdProductVectorSpace(
00052   const Teuchos::RCP<const Teuchos::Comm<Index> >          &intraClusterComm
00053   ,const int                                                       clusterRootRank
00054   ,const Teuchos::RCP<const Teuchos::Comm<Index> >         &interClusterComm
00055   ,const int                                                       numBlocks
00056   ,const Teuchos::RCP<const VectorSpaceBase<Scalar> >      vecSpaces[]
00057   )
00058 {
00059   initialize(intraClusterComm,clusterRootRank,interClusterComm,numBlocks,vecSpaces);
00060 }
00061 
00062 template<class Scalar>
00063 void DefaultClusteredSpmdProductVectorSpace<Scalar>::initialize(
00064   const Teuchos::RCP<const Teuchos::Comm<Index> >          &intraClusterComm
00065   ,const int                                                       clusterRootRank
00066   ,const Teuchos::RCP<const Teuchos::Comm<Index> >         &interClusterComm
00067   ,const int                                                       numBlocks
00068   ,const Teuchos::RCP<const VectorSpaceBase<Scalar> >      vecSpaces[]
00069   )
00070 {
00071   // Set state
00072   intraClusterComm_ = intraClusterComm.assert_not_null();
00073   clusterRootRank_ = clusterRootRank;
00074   interClusterComm_ = interClusterComm; // This can be NULL!
00075   vecSpaces_.resize(numBlocks);
00076   isEuclidean_ = true;
00077   Index clusterSubDim = 0;
00078   for( int k = 0; k < numBlocks; ++k ) {
00079     clusterSubDim += vecSpaces[k]->dim();
00080     if(!vecSpaces[k]->isEuclidean())
00081       isEuclidean_ = false;
00082     vecSpaces_[k] = vecSpaces[k];
00083   }
00084   // We must compute the offsets between clusters and the global dimension by
00085   // only involving the root process in each cluster.
00086   if(interClusterComm_.get()) {
00087     clusterOffset_ = SpmdVectorSpaceUtilities::computeLocalOffset(
00088       *interClusterComm_,clusterSubDim
00089       );
00090     globalDim_ = SpmdVectorSpaceUtilities::computeGlobalDim(
00091       *interClusterComm_,clusterSubDim
00092     );
00093   }
00094   // Here must then broadcast the values to all processes within each cluster.
00095   {
00096     const Index num = 2;
00097     Index buff[num] = { clusterOffset_, globalDim_ };
00098     broadcast(*intraClusterComm_,clusterRootRank_,num,&buff[0]);
00099     clusterOffset_ = buff[0];
00100     globalDim_     = buff[1];
00101   }
00102   //
00103   clusterSubDim_ = clusterSubDim;
00104   // ToDo: Do a global communication across all clusters to see if all vector
00105   // spaces are all Euclidean.  It is unlikely to be the case where all of the
00106   // clusters do not have the same vector spaces so I do not think this will
00107   // even come up.  But just in case, we should keep this in mind!
00108 }
00109 
00110 // Overridden form Teuchos::Describable
00111 
00112 template<class Scalar>
00113 std::string DefaultClusteredSpmdProductVectorSpace<Scalar>::description() const
00114 {
00115   std::ostringstream oss;
00116   oss << "DefaultClusteredSpmdProductVectorSpace{";
00117   oss << "numBlocks="<<vecSpaces_.size();
00118   oss << ",globalDim="<<globalDim_;
00119   oss << ",clusterOffset="<<clusterOffset_;
00120   oss << "}";
00121   return oss.str();
00122 }
00123 
00124 // Public overridden from VectorSpaceBase
00125 
00126 template<class Scalar>
00127 Index DefaultClusteredSpmdProductVectorSpace<Scalar>::dim() const
00128 {
00129   return globalDim_;
00130 }
00131 
00132 template<class Scalar>
00133 bool DefaultClusteredSpmdProductVectorSpace<Scalar>::isCompatible(
00134   const VectorSpaceBase<Scalar>& vecSpc
00135   ) const
00136 {
00137   if( &vecSpc == this )
00138     return true;
00139   // For now, I will just do the dynamic cast but in the future, we could get
00140   // more sophisticated.
00141   TEST_FOR_EXCEPT(true);
00142   return false;
00143 }
00144 
00145 template<class Scalar>
00146 Teuchos::RCP< const VectorSpaceFactoryBase<Scalar> >
00147 DefaultClusteredSpmdProductVectorSpace<Scalar>::smallVecSpcFcty() const
00148 {
00149   if(!vecSpaces_.size())
00150     return Teuchos::null;
00151   return vecSpaces_[0]->smallVecSpcFcty();
00152 }
00153 
00154 template<class Scalar>
00155 Scalar DefaultClusteredSpmdProductVectorSpace<Scalar>::scalarProd(
00156   const VectorBase<Scalar>& x, const VectorBase<Scalar>& y
00157   ) const
00158 {
00159   Scalar scalarProds[1];
00160   this->scalarProds(x,y,&scalarProds[0]);
00161   return scalarProds[0];
00162 }
00163 
00164 template<class Scalar>
00165 void DefaultClusteredSpmdProductVectorSpace<Scalar>::scalarProds(
00166   const MultiVectorBase<Scalar>& X, const MultiVectorBase<Scalar>& Y
00167   ,Scalar scalar_prods[]
00168   ) 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,scalar_prods);
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 Tue Oct 20 12:46:58 2009 for Thyra Operator/Vector Support by doxygen 1.4.7