TSFVectorImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
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 TSFVECTORIMPL_HPP
00030 #define TSFVECTORIMPL_HPP
00031 
00032 
00033 #include "TSFVectorDecl.hpp"
00034 #include "Thyra_SUNDIALS_Ops.hpp"
00035 #include "TSFIndexableVector.hpp"
00036 #include "Thyra_DefaultProductVectorSpace.hpp"
00037 #include "Thyra_DefaultProductVector.hpp"
00038 #include "Thyra_DefaultSpmdVector.hpp"
00039 #include "SundancePrintable.hpp"
00040 #include "SundanceOut.hpp"
00041 #include "SundanceTabs.hpp"
00042 
00043 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00044 #include "TSFVectorSpaceImpl.hpp"
00045 #include "TSFSequentialIteratorImpl.hpp"
00046 #endif
00047 
00048 
00049 
00050 
00051 namespace TSFExtended
00052 {
00053 using Sundance::Out;
00054 using Sundance::Tabs;
00055 using Sundance::Printable;
00056 
00057 //===========================================================================
00058 template <class Scalar> 
00059 void Vector<Scalar>::setBlock(int i, const Vector<Scalar>& v)
00060 {
00061   Thyra::DefaultProductVector<Scalar>* pv = 
00062     dynamic_cast<Thyra::DefaultProductVector<Scalar>* >(this->ptr().get());
00063   TEST_FOR_EXCEPTION(pv == 0, std::runtime_error,
00064     "vector is not a product vector");
00065   Thyra::assign(pv->getNonconstVectorBlock(i).ptr(), *(v.ptr().ptr()));
00066 }  
00067 
00068 
00069 
00070 //===========================================================================
00071 template <class Scalar> 
00072 Vector<Scalar> Vector<Scalar>::getBlock(int i) const
00073 {
00074   const Thyra::DefaultProductVector<Scalar>* pv = 
00075     dynamic_cast <const Thyra::DefaultProductVector<Scalar>* >(this->ptr().get());
00076   if (pv==0) 
00077   {
00078     TEST_FOR_EXCEPTION(i != 0, std::runtime_error,
00079       "Nonzero block index " << i << " into a vector that is not "
00080       "a product vector");
00081     return *this;
00082   }
00083   Teuchos::RCP<const Thyra::VectorBase<Scalar> > b = pv->getVectorBlock(i);
00084   Teuchos::RCP<Thyra::VectorBase<Scalar> > bb 
00085     = rcp_const_cast<Thyra::VectorBase<Scalar> >(b);
00086   return bb;
00087 }
00088 
00089 //===========================================================================
00090 
00091 template <class Scalar> 
00092 void Vector<Scalar>::print(std::ostream& os) const 
00093 {
00094 
00095   const Printable* p = 
00096     dynamic_cast<const Printable* >(this->ptr().get());
00097   if (p != 0)
00098   {
00099     p->print(os);
00100     return;
00101   }
00102   const Thyra::ProductMultiVectorBase<Scalar>* pv = 
00103     dynamic_cast <const Thyra::ProductMultiVectorBase<Scalar>* >(this->ptr().get());
00104   if (pv != 0)
00105   {
00106     os << "ProductVector[" << std::endl;
00107     for (int i=0; i<this->space().numBlocks(); i++)
00108     {
00109       os << "block=" << i << std::endl;
00110       this->getBlock(i).print(os);
00111       os << std::endl;
00112     }
00113     os << "]" << std::endl;
00114     return;
00115   }
00116   else
00117   {
00118     for (SequentialIterator<Scalar> i=this->space().begin(); i!=this->space().end(); i++)
00119     {
00120       os << i.globalIndex() << '\t' << (*this)[i] << std::endl;
00121     }
00122 
00123   }
00124 }
00125 
00126   
00127 
00128 
00129 //===========================================================================
00130 template <class Scalar> inline 
00131 const AccessibleVector<Scalar>* Vector<Scalar>::castToAccessible() const
00132 {
00133   const AccessibleVector<Scalar>* av 
00134     = dynamic_cast<const AccessibleVector<Scalar>*>(this->ptr().get());
00135   TEST_FOR_EXCEPTION(av==0, std::runtime_error,
00136     "Attempted to cast non-accessible vector "
00137     << this->description() << " to an AccessibleVector");
00138   return av;
00139 }
00140 
00141 //===========================================================================
00142 template <class Scalar> inline 
00143 LoadableVector<Scalar>* Vector<Scalar>::castToLoadable()
00144 {
00145   LoadableVector<Scalar>* lv 
00146     = dynamic_cast<LoadableVector<Scalar>*>(this->ptr().get());
00147   TEST_FOR_EXCEPTION(lv==0, std::runtime_error,
00148     "Attempted to cast non-loadable vector "
00149     << this->description() << " to a LoadableVector");
00150   return lv;
00151 }
00152 
00153 
00154 //===========================================================================
00155 template <class Scalar> inline 
00156 const RawDataAccessibleVector<Scalar>* Vector<Scalar>::castToRawDataAccessible() const
00157 {
00158   const RawDataAccessibleVector<Scalar>* av 
00159     = dynamic_cast<const RawDataAccessibleVector<Scalar>*>(this->ptr().get());
00160   TEST_FOR_EXCEPTION(av==0, std::runtime_error,
00161     "Attempted to cast non-accessible vector "
00162     << this->description() 
00163     << " to an RawDataAccessibleVector");
00164   return av;
00165 }
00166 
00167 //===========================================================================
00168 template <class Scalar> inline 
00169 RawDataAccessibleVector<Scalar>* Vector<Scalar>::castToRawDataAccessible() 
00170 {
00171   RawDataAccessibleVector<Scalar>* av 
00172     = dynamic_cast<RawDataAccessibleVector<Scalar>*>(this->ptr().get());
00173   TEST_FOR_EXCEPTION(av==0, std::runtime_error,
00174     "Attempted to cast non-accessible vector "
00175     << this->description() 
00176     << " to an RawDataAccessibleVector");
00177   return av;
00178 }
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 //===========================================================================
00187 template <class Scalar> inline 
00188 Vector<Scalar>& Vector<Scalar>::scale(const Scalar& alpha)
00189 {
00190   {
00191     TimeMonitor t(*opTimer());
00192     Thyra::Vt_S(this->ptr().ptr(), alpha);
00193   }
00194   return *this;
00195 }
00196 
00197 
00198 
00199 
00200 //===========================================================================
00201 template <class Scalar> inline 
00202 Vector<Scalar>& Vector<Scalar>::update(const Scalar& alpha, 
00203   const Vector<Scalar>& x)
00204 {
00205   Ptr<Thyra::VectorBase<Scalar> > p = this->ptr().ptr();
00206   p.assert_not_null();
00207   const Thyra::VectorBase<Scalar>* px = x.ptr().get();
00208   TEST_FOR_EXCEPT(px==0);
00209   {
00210     TimeMonitor t(*opTimer());
00211     Thyra::Vp_StV(p, alpha, *px);
00212   }
00213 
00214   return *this;
00215 }
00216 
00217 
00218 
00219 
00220 
00221 //===========================================================================
00222 template <class Scalar> inline 
00223 Vector<Scalar>& Vector<Scalar>::acceptCopyOf(const Vector<Scalar>& x)
00224 {
00225   TimeMonitor t(*opTimer());
00226   if (this->ptr().get()==0) 
00227   {
00228     Vector<Scalar> me = x.space().createMember();
00229     this->ptr() = me.ptr();
00230   }
00231   
00232   Thyra::assign(this->ptr().ptr(), *(x.ptr()));
00233 
00234   return *this;
00235 }
00236 
00237 template <class Scalar> inline 
00238 Vector<Scalar> Vector<Scalar>::copy() const 
00239 {
00240   Vector<Scalar> rtn = space().createMember();
00241   {
00242     TimeMonitor t(*opTimer());
00243     rtn.acceptCopyOf(*this);
00244   }
00245   return rtn;
00246 }
00247 
00248 
00249 
00250 //===========================================================================
00251 template <class Scalar> inline 
00252 Vector<Scalar> Vector<Scalar>::dotStar(const Vector<Scalar>& other) const 
00253 {
00254   Vector<Scalar> rtn = space().createMember();
00255   {
00256     TimeMonitor t(*opTimer());
00257 //    Thyra::ele_wise_prod(1.0, *(this->ptr()), *(other.ptr()), rtn.ptr().get());
00258     Thyra::ele_wise_prod(1.0, *(this->ptr()), *(other.ptr()), rtn.ptr().ptr());
00259   }
00260   return rtn;
00261 }
00262 
00263 
00264 
00265 //===========================================================================
00266 template <class Scalar> inline 
00267 void Vector<Scalar>::dotStarInto(
00268   const Vector<Scalar>& a, const Vector<Scalar>& b) const 
00269 {
00270   TimeMonitor t(*opTimer());
00271 //  Thyra::ele_wise_prod(1.0, *(a.ptr()), *(b.ptr()), this->ptr().get());
00272   Thyra::ele_wise_prod(1.0, *(a.ptr()), *(b.ptr()), this->ptr().ptr());
00273 }
00274 
00275 
00276 
00277 
00278 
00279 //===========================================================================
00280 template <class Scalar> inline 
00281 Vector<Scalar> Vector<Scalar>::dotSlash(const Vector<Scalar>& other) const 
00282 {
00283   Vector<Scalar> rtn = space().createMember();
00284   {
00285     TimeMonitor t(*opTimer());
00286     Thyra::ele_wise_divide(1.0, *(this->ptr)(), *(other.ptr()), rtn.ptr().ptr());
00287   }
00288   return rtn;
00289 }
00290 
00291 
00292 
00293 
00294 
00295 
00296 //===========================================================================
00297 template <class Scalar> inline 
00298 Vector<Scalar> Vector<Scalar>::abs() const 
00299 {
00300   Vector<Scalar> rtn = space().createMember();
00301   {
00302     TimeMonitor t(*opTimer());
00303     rtn.acceptCopyOf(*this);
00304     rtn.abs();
00305   }
00306   return rtn;
00307 }
00308 
00309 
00310 
00311 
00312 
00313 //===========================================================================
00314 template <class Scalar> inline 
00315 Vector<Scalar> Vector<Scalar>::reciprocal() const 
00316 {
00317   Vector<Scalar> rtn = space().createMember();
00318   {
00319     TimeMonitor t(*opTimer());
00320     rtn.acceptCopyOf(*this);
00321     rtn.reciprocal();
00322   }
00323   return rtn;
00324 }
00325 
00326 
00327 
00328 //===========================================================================
00329 template <class Scalar> inline 
00330 Vector<Scalar>& Vector<Scalar>::abs()
00331 {
00332   {
00333     TimeMonitor t(*opTimer());
00334     Thyra::abs(this->ptr().ptr(), *(this->ptr()));
00335   }
00336   return *this;
00337 }
00338   
00339 
00340 
00341 
00342 
00343 //===========================================================================
00344 template <class Scalar> inline 
00345 Vector<Scalar>& Vector<Scalar>::reciprocal()
00346 {
00347   TimeMonitor t(*opTimer());
00348   Thyra::reciprocal(this->ptr().ptr(), *(this->ptr()));
00349 
00350   return *this;
00351 }
00352 
00353   
00354 
00355 //===========================================================================
00356 template <class Scalar> inline
00357 Vector<Scalar>& Vector<Scalar>::update(const Scalar& alpha, 
00358   const Vector<Scalar>& x, 
00359   const Scalar& gamma)
00360 {
00361   TimeMonitor t(*opTimer());
00362 
00363   ArrayView<const Scalar> a(&alpha, 1);
00364   Teuchos::Ptr<const Thyra::VectorBase<Scalar> > px = x.ptr().ptr();
00365   ArrayView<const Teuchos::Ptr<const Thyra::VectorBase<Scalar> > > apx(&px,1);
00366   
00367   Thyra::linear_combination(a, apx, gamma, this->ptr().ptr());
00368 
00369   return *this;
00370 }
00371 
00372 
00373 
00374 
00375 //===========================================================================
00376 template <class Scalar> inline
00377 Vector<Scalar>& Vector<Scalar>::update(const Scalar& alpha, 
00378   const Vector<Scalar>& x, 
00379   const Scalar& beta, 
00380   const Vector<Scalar>& y, 
00381   const Scalar& gamma)
00382 {
00383   TimeMonitor t(*opTimer());
00384 
00385   Scalar a[2];
00386   a[0] = alpha;
00387   a[1] = beta;
00388   ArrayView<const Scalar> av(a,2);
00389 
00390   Ptr<const Thyra::VectorBase<Scalar> > vecs[2];
00391   vecs[0] = x.ptr().ptr().getConst();
00392   vecs[1] = y.ptr().ptr().getConst();
00393   ArrayView<const Ptr<const Thyra::VectorBase<Scalar> > > vv(vecs,2);
00394 
00395   Thyra::linear_combination(av, vv, gamma, this->ptr().ptr());
00396 
00397   return *this;
00398 }
00399 
00400 
00401 
00402 
00403 //===========================================================================
00404 template <class Scalar> inline 
00405 Scalar Vector<Scalar>::dot(const Vector<Scalar>& other) const 
00406 {
00407   TimeMonitor t(*opTimer());
00408     
00409   return Thyra::dot(*(this->ptr)(), *(other.ptr()));
00410 }
00411 
00412 
00413 //===========================================================================
00414 template <class Scalar> inline 
00415 Scalar Vector<Scalar>::operator*(const Vector<Scalar>& other) const 
00416 {
00417   return dot(other);
00418 }
00419 
00420 
00421 
00422 
00423 //===========================================================================
00424 template <class Scalar> inline 
00425 Scalar Vector<Scalar>::norm1() const 
00426 {
00427   TimeMonitor t(*opTimer());
00428     
00429   return Thyra::norm_1(*(this->ptr)());
00430 }
00431 
00432 
00433 
00434 
00435 //===========================================================================
00436 template <class Scalar> inline 
00437 Scalar Vector<Scalar>::norm2() const 
00438 {
00439   TimeMonitor t(*opTimer());
00440   return Thyra::norm_2(*(this->ptr)());
00441 }
00442 
00443 
00444 
00445 
00446 //===========================================================================
00447 template <class Scalar> inline 
00448 Scalar Vector<Scalar>::norm2(const Vector<Scalar>& weights) const 
00449 {
00450   TimeMonitor t(*opTimer());
00451     
00452   return Thyra::norm_2(*(weights.ptr()), *(this->ptr)());
00453 }
00454 
00455 
00456 
00457 
00458 
00459 //===========================================================================
00460 template <class Scalar> inline 
00461 Scalar Vector<Scalar>::normInf() const 
00462 {
00463   TimeMonitor t(*opTimer());
00464     
00465   return Thyra::norm_inf(*(this->ptr)());
00466 }
00467 
00468 
00469 
00470 
00471 //===========================================================================
00472 template <class Scalar> inline 
00473 void Vector<Scalar>::zero()
00474 {
00475   TimeMonitor t(*opTimer());
00476     
00477   Thyra::assign(this->ptr().ptr(), 0.0);
00478 }
00479 
00480 
00481 
00482 
00483 //===========================================================================
00484 template <class Scalar> inline 
00485 void Vector<Scalar>::setToConstant(const Scalar& alpha)
00486 {
00487   TimeMonitor t(*opTimer());
00488     
00489   Thyra::assign(this->ptr().ptr(), alpha);
00490 }
00491 
00492 
00493 
00494   
00495 
00496 //===========================================================================
00497 template <class Scalar> inline 
00498 Scalar Vector<Scalar>::max()const
00499 {
00500   TimeMonitor t(*opTimer());
00501   return Thyra::max(*(this->ptr)());
00502 }
00503 
00504 
00505 //===========================================================================
00506 template <class Scalar> inline 
00507 Scalar Vector<Scalar>::max(int& index)const
00508 {
00509   TimeMonitor t(*opTimer());
00510   Scalar maxEl;
00511   Ptr<Scalar> maxElP(&maxEl);
00512   OrdType loc_index = -1;
00513   Ptr<OrdType> pind(&loc_index);
00514   Thyra::max(*(this->ptr()), maxElP, pind); 
00515   index = loc_index;
00516   return maxEl;
00517 }
00518 
00519 
00520 //===========================================================================
00521 template <class Scalar> inline 
00522 Scalar Vector<Scalar>::max(const Scalar& bound, int& index)const
00523 {
00524   TimeMonitor t(*opTimer());
00525   Scalar maxEl;
00526   Ptr<Scalar> maxElP(&maxEl);
00527   OrdType loc_index = -1;
00528   Ptr<OrdType> pind(&loc_index);
00529   Thyra::maxLessThanBound(*(this->ptr()), bound, maxElP, pind); 
00530   index = loc_index;
00531   return maxEl;
00532 
00533 }
00534 
00535 
00536 //===========================================================================
00537 template <class Scalar> inline 
00538 Scalar Vector<Scalar>::min()const
00539 {
00540   TimeMonitor t(*opTimer());
00541   return Thyra::min(*(this->ptr()));
00542 }
00543 
00544 
00545 //===========================================================================
00546 template <class Scalar> inline 
00547 Scalar Vector<Scalar>::min(int& index)const
00548 {
00549   TimeMonitor t(*opTimer());
00550   Scalar minEl;
00551   Ptr<Scalar> minElP(&minEl);
00552   OrdType loc_index = -1;
00553   Ptr<OrdType> pind(&loc_index);
00554   Thyra::min(*(this->ptr()), minElP, pind); 
00555   index = loc_index;
00556   return minEl;
00557 }
00558 
00559 
00560 //===========================================================================
00561 template <class Scalar> inline 
00562 Scalar Vector<Scalar>::min(const Scalar& bound, int& index)const
00563 {
00564   TimeMonitor t(*opTimer());
00565   Scalar minEl;
00566   Ptr<Scalar> minElP(&minEl);
00567   OrdType loc_index = -1;
00568   Ptr<OrdType> pind(&loc_index);
00569 
00570   Thyra::minGreaterThanBound(*(this->ptr)(), bound, minElP, pind); 
00571   index = loc_index;
00572   return minEl;
00573 }
00574 
00575 
00576 
00577 
00578 //===========================================================================
00579 template <class Scalar> inline 
00580 Scalar Vector<Scalar>::getElement(OrdType globalIndex) const
00581 { 
00582   Thyra::ProductVectorBase<Scalar>* p 
00583     = dynamic_cast<Thyra::ProductVectorBase<Scalar>*>(&*this->ptr());
00584 
00585   if (p)
00586   {
00587     const Thyra::ProductVectorSpaceBase<Scalar>* pvs 
00588       = dynamic_cast<const Thyra::ProductVectorSpaceBase<Scalar>*>(space().ptr().get());
00589     TEST_FOR_EXCEPT(pvs == 0);
00590 
00591     const Thyra::DefaultProductVectorSpace<Scalar>* dpvs 
00592       = dynamic_cast<const Thyra::DefaultProductVectorSpace<Scalar>*>(pvs);
00593     if (dpvs)
00594     {
00595       int blockIndex=-1;
00596       OrdType globOffsetInBlock=-1;
00597       dpvs->getVecSpcPoss(globalIndex, &blockIndex, &globOffsetInBlock);
00598       RCP<Thyra::VectorBase<Scalar> > vec_i 
00599         = p->getNonconstVectorBlock(blockIndex);
00600       Vector<Scalar> vv(vec_i);
00601       return vv.getElement(globOffsetInBlock);
00602     }
00603     else
00604     {
00605       int k = 0;
00606       for (int i = 0; i < pvs->numBlocks(); i++)
00607       {
00608         RCP<Thyra::VectorBase<Scalar> > vec_i 
00609           = p->getNonconstVectorBlock(i);
00610         int len = vec_i->space()->dim();
00611         if (globalIndex < k + len )
00612         {
00613           Vector<Scalar> vv(vec_i);
00614           int globalIndexWithinBlock = globalIndex - k;
00615           return vv.getElement(globalIndexWithinBlock);
00616           break;
00617         }
00618         k += len;
00619       }
00620     }
00621     TEST_FOR_EXCEPT(true); // should never happen
00622     return 0.0; // -Wall
00623   }
00624   else
00625   {
00626     Thyra::DefaultSpmdVector<Scalar>* dsv
00627       = dynamic_cast<Thyra::DefaultSpmdVector<Scalar>*>(this->ptr().get());
00628       
00629     if (dsv)
00630     {
00631       OrdType stride = dsv->getStride();
00632       OrdType low = dsv->spmdSpace()->localOffset();
00633       OrdType subdim = dsv->spmdSpace()->localSubDim();
00634       TEST_FOR_EXCEPTION( globalIndex < low || globalIndex >= low+subdim, 
00635         std::runtime_error,
00636         "Bounds violation: " << globalIndex << "is out of range [low" 
00637         << ", " <<  low+subdim << "]");
00638       return dsv->getPtr()[stride*(globalIndex - low)];
00639     }
00640     else
00641     {
00642       return castToAccessible()->getElement(globalIndex);
00643     }
00644   }
00645 }
00646 
00647 //===========================================================================
00648 template <class Scalar> inline 
00649 void Vector<Scalar>::setElement(OrdType globalIndex, const Scalar& value)
00650 { 
00651   Thyra::ProductVectorBase<Scalar>* p 
00652     = dynamic_cast<Thyra::ProductVectorBase<Scalar>*>(&*this->ptr());
00653 
00654   if (p)
00655   {
00656     const Thyra::ProductVectorSpaceBase<Scalar>* pvs 
00657       = dynamic_cast<const Thyra::ProductVectorSpaceBase<Scalar>*>(space().ptr().get());
00658     TEST_FOR_EXCEPT(pvs == 0);
00659 
00660     const Thyra::DefaultProductVectorSpace<Scalar>* dpvs 
00661       = dynamic_cast<const Thyra::DefaultProductVectorSpace<Scalar>*>(pvs);
00662     if (dpvs)
00663     {
00664       int blockIndex=-1;
00665       OrdType globOffsetInBlock=-1;
00666       dpvs->getVecSpcPoss(globalIndex, &blockIndex, &globOffsetInBlock);
00667       RCP<Thyra::VectorBase<Scalar> > vec_i 
00668         = p->getNonconstVectorBlock(blockIndex);
00669       Vector<Scalar> vv(vec_i);
00670       vv.setElement(globOffsetInBlock, value);
00671     }
00672     else
00673     {
00674       int k = 0;
00675       for (int i = 0; i < pvs->numBlocks(); i++)
00676       {
00677         RCP<Thyra::VectorBase<Scalar> > vec_i 
00678           = p->getNonconstVectorBlock(i);
00679         int len = vec_i->space()->dim();
00680         if (globalIndex < k + len )
00681         {
00682           Vector<Scalar> vv(vec_i);
00683           int globalIndexWithinBlock = globalIndex - k;
00684           vv.setElement(globalIndexWithinBlock, value);
00685           break;
00686         }
00687         k += len;
00688       }
00689     }
00690 
00691   }
00692   else
00693   {
00694     Thyra::DefaultSpmdVector<Scalar>* dsv
00695       = dynamic_cast<Thyra::DefaultSpmdVector<Scalar>*>(this->ptr().get());
00696       
00697     if (dsv)
00698     {
00699       OrdType stride = dsv->getStride();
00700       OrdType low = dsv->spmdSpace()->localOffset();
00701       OrdType subdim = dsv->spmdSpace()->localSubDim();
00702       TEST_FOR_EXCEPTION( globalIndex < low || globalIndex >= low+subdim, 
00703         std::runtime_error,
00704         "Bounds violation: " << globalIndex << "is out of range [low" 
00705         << ", " <<  low+subdim << "]");
00706       dsv->getPtr()[stride*(globalIndex - low)] = value;
00707     }
00708     else
00709     {
00710       castToLoadable()->setElement(globalIndex, value);
00711     }
00712   }
00713 }
00714 
00715 
00716 //===========================================================================
00717 template <class Scalar> inline 
00718 Scalar& Vector<Scalar>::operator[](const SequentialIterator<Scalar>& iter)
00719 {
00720   const OrdType& blockIndex = iter.blockIndex();
00721   const OrdType& indexInBlock = iter.indexInBlock();
00722   
00723   return localElement(blockIndex, indexInBlock);
00724 } 
00725 
00726 
00727 
00728 //===========================================================================
00729 template <class Scalar> inline 
00730 const Scalar& Vector<Scalar>::operator[](const SequentialIterator<Scalar>& iter) const
00731 {
00732   const OrdType& blockIndex = iter.blockIndex();
00733   const OrdType& indexInBlock = iter.indexInBlock();
00734   
00735   return localElement(blockIndex, indexInBlock);
00736 } 
00737 
00738 
00739 //===========================================================================
00740 template <class Scalar> inline 
00741 const Scalar& Vector<Scalar>::localElement(const OrdType& blockIndex, const OrdType& indexInBlock) const
00742 {
00743   const Thyra::ProductVectorBase<Scalar>* p 
00744     = dynamic_cast<const Thyra::ProductVectorBase<Scalar>*>(&*this->ptr());
00745   RCP<const Thyra::VectorBase<Scalar> > vec;
00746   if (p)
00747   {
00748     vec = p->getVectorBlock(blockIndex);
00749   }
00750   else
00751   {
00752     vec = this->ptr();
00753   }
00754   const Thyra::DefaultSpmdVector<Scalar>* dsv 
00755     = dynamic_cast<const Thyra::DefaultSpmdVector<Scalar>*>(this->ptr().get());
00756   if (dsv != 0)
00757   {
00758     return dsv->getPtr()[indexInBlock*dsv->getStride()];
00759   }
00760   return castToRawDataAccessible()->dataPtr()[indexInBlock];
00761 } 
00762 
00763 
00764 
00765 //===========================================================================
00766 template <class Scalar> inline 
00767 Scalar& Vector<Scalar>::localElement(const OrdType& blockIndex, const OrdType& indexInBlock) 
00768 {
00769   Thyra::ProductVectorBase<Scalar>* p 
00770     = dynamic_cast<Thyra::ProductVectorBase<Scalar>*>(&*this->ptr());
00771   RCP<Thyra::VectorBase<Scalar> > vec;
00772   if (p)
00773   {
00774     vec = p->getNonconstVectorBlock(blockIndex);
00775   }
00776   else
00777   {
00778     vec = this->ptr();
00779   }
00780   
00781   Thyra::DefaultSpmdVector<Scalar>* dsv 
00782     = dynamic_cast<Thyra::DefaultSpmdVector<Scalar>*>(this->ptr().get());
00783   if (dsv != 0)
00784   {
00785     return dsv->getPtr()[indexInBlock*dsv->getStride()];
00786   }
00787   TSFExtended::RawDataAccessibleVector<Scalar>* d 
00788     = this->castToRawDataAccessible();
00789   return d->dataPtr()[indexInBlock];
00790 } 
00791 
00792 
00793 
00794 
00795 
00796 //#ifdef OBSOLETE_CODE
00797 
00798 
00799 //===========================================================================
00800 template <class Scalar> inline 
00801 void Vector<Scalar>::addToElement(OrdType globalIndex, const Scalar& value)
00802 {
00803   Thyra::ProductVectorBase<Scalar>* p 
00804     = dynamic_cast<Thyra::ProductVectorBase<Scalar>*>(&*this->ptr());
00805 
00806   if (p)
00807   {
00808     const Thyra::ProductVectorSpaceBase<Scalar>* pvs 
00809       = dynamic_cast<const Thyra::ProductVectorSpaceBase<Scalar>*>(space().ptr().get());
00810     TEST_FOR_EXCEPT(pvs == 0);
00811 
00812     const Thyra::DefaultProductVectorSpace<Scalar>* dpvs 
00813       = dynamic_cast<const Thyra::DefaultProductVectorSpace<Scalar>*>(pvs);
00814     if (dpvs)
00815     {
00816       int blockIndex=-1;
00817       OrdType globOffsetInBlock=-1;
00818       dpvs->getVecSpcPoss(globalIndex, &blockIndex, &globOffsetInBlock);
00819       RCP<Thyra::VectorBase<Scalar> > vec_i 
00820         = p->getNonconstVectorBlock(blockIndex);
00821       Vector<Scalar> vv(vec_i);
00822       vv.addToElement(globOffsetInBlock, value);
00823     }
00824     else
00825     {
00826       int k = 0;
00827       for (int i = 0; i < pvs->numBlocks(); i++)
00828       {
00829         RCP<Thyra::VectorBase<Scalar> > vec_i 
00830           = p->getNonconstVectorBlock(i);
00831         int len = vec_i->space()->dim();
00832         if (globalIndex < k + len )
00833         {
00834           Vector<Scalar> vv(vec_i);
00835           int globalIndexWithinBlock = globalIndex - k;
00836           vv.addToElement(globalIndexWithinBlock, value);
00837           break;
00838         }
00839         k += len;
00840       }
00841     }
00842 
00843   }
00844   else
00845   {
00846     Thyra::DefaultSpmdVector<Scalar>* dsv
00847       = dynamic_cast<Thyra::DefaultSpmdVector<Scalar>*>(this->ptr().get());
00848       
00849     LoadableVector<Scalar>* loadable = dynamic_cast<LoadableVector<Scalar>*>(this->ptr().get());
00850     if (loadable)
00851     {
00852       loadable->addToElement(globalIndex, value);
00853     }
00854     else if (dsv)
00855     {
00856       OrdType stride = dsv->getStride();
00857       OrdType low = dsv->spmdSpace()->localOffset();
00858       OrdType subdim = dsv->spmdSpace()->localSubDim();
00859       TEST_FOR_EXCEPTION( globalIndex < low || globalIndex >= low+subdim, 
00860         std::runtime_error,
00861         "Bounds violation: " << globalIndex << "is out of range [low" 
00862         << ", " <<  low+subdim << "]");
00863       dsv->getPtr()[stride*(globalIndex - low)] += value;
00864     }
00865     else
00866     {
00867       TEST_FOR_EXCEPT(true);
00868     }
00869   }
00870 }
00871 
00872 
00873 
00874 template <class Scalar> inline 
00875 void Vector<Scalar>::boundscheck(OrdType i, int dim) const
00876 {
00877   TEST_FOR_EXCEPTION( i < 0 || i >= dim, std::runtime_error,
00878     "Bounds violation: " << i << "is out of range [0" 
00879     << ", " << dim << "]");
00880 }
00881 
00882 
00883 }
00884 
00885 #endif

Site Contact