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

Generated on Thu Sep 18 12:32:31 2008 for Thyra Operator/Vector Support by doxygen 1.3.9.1