Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef TSFVECTORSPACEIMPL_HPP
00030 #define TSFVECTORSPACEIMPL_HPP
00031
00032
00033 #include "Thyra_ProductVectorSpaceBase.hpp"
00034 #include "TSFVectorSpaceDecl.hpp"
00035 #include "TSFVectorDecl.hpp"
00036 #include "Thyra_SpmdVectorSpaceBase.hpp"
00037 #include "Teuchos_Describable.hpp"
00038 #include "Teuchos_Time.hpp"
00039 #include "Teuchos_TimeMonitor.hpp"
00040
00041 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00042 #include "TSFSequentialIteratorImpl.hpp"
00043 #endif
00044
00045 using namespace TSFExtended;
00046 using namespace Teuchos;
00047
00048
00049 static inline Time& createVecTimer()
00050 {
00051 static RCP<Time> rtn
00052 = TimeMonitor::getNewTimer("vector allocation");
00053 return *rtn;
00054 }
00055
00056
00057
00058 template <class Scalar>
00059 bool VectorSpace<Scalar>::operator==(const VectorSpace<Scalar>& other) const
00060 {
00061 return isCompatible(other);
00062 }
00063
00064
00065
00066 template <class Scalar>
00067 bool VectorSpace<Scalar>::operator!=(const VectorSpace<Scalar>& other) const
00068 {
00069 return !(operator==(other));
00070 }
00071
00072
00073
00074
00075 template <class Scalar>
00076 Vector<Scalar> VectorSpace<Scalar>::createMember() const
00077 {
00078 TimeMonitor timer(createVecTimer());
00079 Vector<Scalar> rtn = Thyra::createMember(this->ptr());
00080 rtn.setToConstant(0.0);
00081 return rtn;
00082 }
00083
00084
00085
00086
00087 template <class Scalar>
00088 int VectorSpace<Scalar>::lowestLocallyOwnedIndex() const
00089 {
00090 const Thyra::SpmdVectorSpaceBase<Scalar>* mpiSpace
00091 = dynamic_cast<const Thyra::SpmdVectorSpaceBase<Scalar>*>(this->ptr().get());
00092 if (mpiSpace != 0)
00093 {
00094 return mpiSpace->localOffset();
00095 }
00096 const Thyra::SpmdVectorSpaceBase<Scalar>* serialSpace
00097 = dynamic_cast<const Thyra::SpmdVectorSpaceBase<Scalar>*>(this->ptr().get());
00098 if (serialSpace != 0)
00099 {
00100 return 0;
00101 }
00102 TEST_FOR_EXCEPTION(mpiSpace == 0 && serialSpace==0, std::runtime_error,
00103 "don't know how to compute lowest local index for "
00104 "a vector space that is neither MPI nor serial");
00105 return 0;
00106 }
00107
00108
00109 template <class Scalar>
00110 int VectorSpace<Scalar>::numLocalElements() const
00111 {
00112 if (numBlocks() > 1)
00113 {
00114 int rtn = 0;
00115 for (int b=0; b<numBlocks(); b++)
00116 {
00117 rtn += getBlock(b).numLocalElements();
00118 }
00119 return rtn;
00120 }
00121
00122 const Thyra::SpmdVectorSpaceBase<Scalar>* mpiSpace
00123 = dynamic_cast<const Thyra::SpmdVectorSpaceBase<Scalar>*>(this->ptr().get());
00124 if (mpiSpace != 0)
00125 {
00126 return mpiSpace->localSubDim();
00127 }
00128 const Thyra::SpmdVectorSpaceBase<Scalar>* serialSpace
00129 = dynamic_cast<const Thyra::SpmdVectorSpaceBase<Scalar>*>(this->ptr().get());
00130 if (serialSpace != 0)
00131 {
00132 return dim();
00133 }
00134 TEST_FOR_EXCEPTION(mpiSpace == 0 && serialSpace==0, std::runtime_error,
00135 "don't know how to compute number of local elements for "
00136 "a vector space that is neither MPI nor serial");
00137 return 0;
00138 }
00139
00140
00141
00142
00143
00144 template <class Scalar>
00145 bool VectorSpace<Scalar>::isCompatible(const VectorSpace<Scalar>& vecSpc) const
00146 {
00147 TEST_FOR_EXCEPTION(vecSpc.ptr().get() == 0, std::runtime_error,
00148 "null argument in VectorSpace<Scalar>::isCompatible()");
00149 return this->ptr().get()->isCompatible(*(vecSpc.ptr().get()));
00150 }
00151
00152
00153
00154
00155
00156
00157 template <class Scalar>
00158 bool VectorSpace<Scalar>::contains(const Vector<Scalar> &vec) const
00159 {
00160 return (operator==(vec.space()));
00161 }
00162
00163
00164
00165 template <class Scalar>
00166 int VectorSpace<Scalar>::numBlocks() const
00167 {
00168 const Thyra::ProductVectorSpaceBase<Scalar>* pvs =
00169 dynamic_cast<const Thyra::ProductVectorSpaceBase<Scalar>* > (this->ptr().get());
00170 if (pvs != 0)
00171 {
00172 return pvs->numBlocks();
00173 }
00174 return 1;
00175 }
00176
00177
00178
00179
00180 template <class Scalar>
00181 VectorSpace<Scalar> VectorSpace<Scalar>::getBlock(const int i) const
00182 {
00183 const Thyra::ProductVectorSpaceBase<Scalar>* pvs =
00184 dynamic_cast<const Thyra::ProductVectorSpaceBase<Scalar>* > (this->ptr().get());
00185 TEST_FOR_EXCEPTION(pvs == 0 && numBlocks()!=1, std::runtime_error,
00186 "Space not a ProductVectorSpace" << std::endl);
00187 if (pvs != 0)
00188 {
00189 return pvs->getBlock(i);
00190 }
00191 return *this;
00192 }
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 template <class Scalar> inline
00214 SequentialIterator<Scalar> VectorSpace<Scalar>::begin() const
00215 {
00216 OrdType blockIndex = -1;
00217 OrdType indexInCurrentBlock = -1;
00218 OrdType globalIndex = -1;
00219
00220
00221
00222 bool dataRemains = advanceIndex(blockIndex, indexInCurrentBlock, globalIndex);
00223
00224 if (dataRemains)
00225 {
00226 return SequentialIterator<Scalar>(*this, blockIndex, indexInCurrentBlock, globalIndex);
00227 }
00228 else
00229 {
00230 return end();
00231 }
00232 }
00233
00234
00235
00236 template <class Scalar> inline
00237 SequentialIterator<Scalar> VectorSpace<Scalar>::end() const
00238 {
00239 return SequentialIterator<Scalar>(*this);
00240 }
00241
00242
00243
00244
00245
00246 template <class Scalar> inline
00247 bool VectorSpace<Scalar>::advanceIndex(
00248 OrdType& blockIndex,
00249 OrdType& indexInCurrentBlock,
00250 OrdType& globalIndex) const
00251 {
00252
00253 if (blockIndex < 0)
00254 {
00255
00256 for (int i=0; i<numBlocks(); i++)
00257 {
00258 if (getBlock(i).dim()==0) continue;
00259 blockIndex = i;
00260 indexInCurrentBlock = 0;
00261 globalIndex = lowestLocallyOwnedIndex();
00262 return true;
00263 }
00264
00265
00266 return false;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 bool isProductSpace = (0 !=
00277 dynamic_cast<const Thyra::ProductVectorSpaceBase<Scalar>* > (this->ptr().get()));
00278 if (!isProductSpace)
00279 {
00280 indexInCurrentBlock++;
00281 globalIndex++;
00282 if (indexInCurrentBlock >= numLocalElements())
00283 {
00284 return false;
00285 }
00286 return true;
00287 }
00288 else
00289 {
00290
00291
00292 OrdType subBlock = 0;
00293 if (getBlock(blockIndex).advanceIndex(subBlock, indexInCurrentBlock, globalIndex))
00294 {
00295
00296 return true;
00297 }
00298 else
00299 {
00300
00301
00302
00303 for (int i=blockIndex+1; i<numBlocks(); i++)
00304 {
00305 if (getBlock(i).dim()==0) continue;
00306 indexInCurrentBlock = 0;
00307 globalIndex++;
00308 blockIndex = i;
00309 return true;
00310 }
00311
00312 return false;
00313 }
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323 #endif