Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_SpmdVectorSpaceDefaultBase_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_SPMD_VECTOR_SPACE_BASE_DEF_HPP
11 #define THYRA_SPMD_VECTOR_SPACE_BASE_DEF_HPP
12 
13 #include "Thyra_SpmdVectorSpaceDefaultBase_decl.hpp"
14 #include "Thyra_ScalarProdVectorSpaceBase.hpp"
15 #include "Thyra_DefaultSpmdVectorSpaceFactory.hpp"
16 #include "Thyra_SpmdVectorSpaceUtilities.hpp"
17 #include "Thyra_ProductVectorSpaceBase.hpp"
18 
19 
20 namespace Thyra {
21 
22 
23 template<class Scalar>
25  :mapCode_(-1), defaultLocalOffset_(-1), defaultGlobalDim_(-1),
26  localSubDim_(-1), isLocallyReplicated_(false)
27 {}
28 
29 
30 // Virtual methods with default implementations
31 
32 
33 template<class Scalar>
35 {
36  return defaultLocalOffset_;
37 }
38 
39 
40 template<class Scalar>
42 {
43  return mapCode_;
44 }
45 
46 
47 template<class Scalar>
49 {
50  return isLocallyReplicated_;
51 }
52 
53 
54 template<class Scalar>
56 {
57  using Teuchos::RCP; using Teuchos::Comm; using Teuchos::null;
58  std::ostringstream ostr;
59  ostr << Teuchos::typeName(*this) << "{";
60  ostr << "globalDim="<<this->dim();
61  ostr << ",localSubDim="<<this->localSubDim();
62  ostr << ",localOffset="<<this->localOffset();
63  ostr << ",comm=";
65  if ( (comm=this->getComm())!=null ) {
66  ostr << comm->description();
67  }
68  else {
69  ostr << "NULL";
70  }
71  ostr << "}";
72  return ostr.str();
73 }
74 
75 
76 // Overridden from VectorSpaceBase
77 
78 
79 template<class Scalar>
81 {
82  return defaultGlobalDim_;
83 }
84 
85 
86 template<class Scalar>
89 {
90  return smallVecSpcFcty_;
91 }
92 
93 
94 template<class Scalar>
96  const VectorSpaceBase<Scalar>& vecSpc
97  ) const
98 {
99 
100  using Teuchos::ptrFromRef;
101  using Teuchos::ptr_dynamic_cast;
102 
103  // Check for exact match of vector space
105  spmdVecSpc = ptr_dynamic_cast<const SpmdVectorSpaceBase<Scalar> >(ptrFromRef(vecSpc));
106  if (nonnull(spmdVecSpc)) {
107  return mapCode() == spmdVecSpc->mapCode();
108  }
109 
110  // Check for product vector interface
112  ptr_dynamic_cast<const ProductVectorSpaceBase<Scalar> >(ptrFromRef(vecSpc));
113 
114  if (nonnull(pvsb)) {
115  if (pvsb->numBlocks() == 1 ) {
116  return pvsb->getBlock(0)->isCompatible(*this);
117  }
118  else {
119  return false;
120  }
121  }
122 
123  // If we get here, we are not compatible!
124  return false;
125 
126 }
127 
128 
129 // protected
130 
131 
132 template<class Scalar>
134  const bool isLocallyReplicated_in)
135 {
136  namespace SVSU = SpmdVectorSpaceUtilities;
137 
138  //
139  // A) Get the comm, comm info, and local subdim
140  //
141 
142  localSubDim_ = this->localSubDim();
143 
145  comm = this->getComm();
146 
147  int numProcs = 1;
148  if (nonnull(comm)) {
149  numProcs = comm->getSize();
150  }
151 
152  //
153  // B) Determine the type of vector space
154  //
155 
156  Ordinal sumLocalSubDims = localSubDim_;
157 
158  bool isSerialOrLocallyReplicated = false;
159  bool isEmpty = false;
160  bool isDistributed = false;
161 
162  if (isLocallyReplicated_in) {
163  // Avoid communication when we know this is locally replicated
164  isSerialOrLocallyReplicated = true;
165  if (sumLocalSubDims == 0) {
166  isEmpty = true;
167  }
168  TEUCHOS_ASSERT_EQUALITY(localSubDim_, globalDim);
169  }
170  else {
171  if (numProcs > 1) {
172  sumLocalSubDims = SVSU::computeGlobalDim(*comm, localSubDim_);
173  }
174  if (sumLocalSubDims == 0) {
175  // This is an uninitialized space (zero on every process)
176  isEmpty = true;
177  }
178  else if (
179  numProcs == 1
180  ||
181  (
182  sumLocalSubDims / numProcs == globalDim
183  &&
184  sumLocalSubDims % numProcs == 0
185  )
186  )
187  {
188  // This is a serial or a locally-replicated parallel
189  // vector space.
190  isSerialOrLocallyReplicated = true;
191  //TEUCHOS_TEST_FOR_EXCEPTION(numProcs > 1, std::logic_error,
192  // "Error, you are creating a locally replicated vector space implicitly which"
193  // " is very inefficient. Please pass in isLocallyReplicated=true to avoid"
194  // " unnecessary global communication!");
195  // ToDo: Add runtime option to assert that an implicit VS is not being
196  // created which is a performance problem.
197  }
198  else {
199  // This is a regular distributed vector space
200  isDistributed = true;
201  }
202  }
203 
204  //
205  // C) Set the state of the vector space for the given type
206  //
207 
208  if (isEmpty) {
209  mapCode_ = 0;
210  defaultLocalOffset_ = 0;
211  defaultGlobalDim_ = 0;
212  }
213  else if (isSerialOrLocallyReplicated) {
214  isLocallyReplicated_ = true;
215  mapCode_ = localSubDim_;
216  defaultLocalOffset_ = 0;
217  defaultGlobalDim_ = localSubDim_;
218  }
219  else {
220  TEUCHOS_ASSERT(isDistributed);
221  defaultGlobalDim_ = sumLocalSubDims;
222  mapCode_ = SVSU::computeMapCode(*comm, localSubDim_);
223  defaultLocalOffset_ = SVSU::computeLocalOffset(*comm, localSubDim_);
224  }
225 
226  smallVecSpcFcty_ = defaultSpmdVectorSpaceFactory<Scalar>(comm);
227 
228 }
229 
230 
231 } // end namespace Thyra
232 
233 
234 #endif // THYRA_SPMD_VECTOR_SPACE_BASE_DEF_HPP
Teuchos::RCP< const VectorSpaceFactoryBase< Scalar > > smallVecSpcFcty() const
Returns a DefaultSpmdVectorSpaceFactory object that has been given getComm().
bool isCompatible(const VectorSpaceBase< Scalar > &vecSpc) const
Checks the general compatibility of parallel (or serial on one process) Spmd-based vector spaces...
Abstract interface for objects that represent a space for vectors.
bool isLocallyReplicated() const
Returns true if vector space is locally replicated space.
virtual void updateState(const Ordinal globalDim, const bool isLocallyReplicated=false)
This function must be called whenever the state of this changes and some internal state must be updat...
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
bool nonnull(const boost::shared_ptr< T > &p)
Ordinal dim() const
Returns the sum of the local number of elements on every process.
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
std::string typeName(const T &t)