Rythmos_InterpolationBuffer.hpp

00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Rythmos Package
00005 //                 Copyright (2006) 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 Todd S. Coffey (tscoffe@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 //@HEADER
00028 
00029 #ifndef Rythmos_INTERPOLATION_BUFFER_H
00030 #define Rythmos_INTERPOLATION_BUFFER_H
00031 
00032 #include "Rythmos_InterpolationBufferBase.hpp"
00033 #include "Rythmos_InterpolatorBase.hpp"
00034 #include "Rythmos_LinearInterpolator.hpp"
00035 #include "Rythmos_DataStore.hpp"
00036 
00037 #include "Thyra_VectorBase.hpp"
00038 #include "Thyra_VectorStdOps.hpp"
00039 
00040 namespace Rythmos {
00041 
00042 
00044 template<class Scalar> 
00045 class InterpolationBuffer : virtual public InterpolationBufferBase<Scalar>
00046 {
00047 public:
00048 
00049   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00050 
00052 
00053   RCP<const Thyra::VectorSpaceBase<Scalar> > get_x_space() const;
00054     
00056   InterpolationBuffer();
00057   InterpolationBuffer( const RCP<InterpolatorBase<Scalar> >& interpolator_, int storage_ );
00058 
00060   void initialize( const RCP<InterpolatorBase<Scalar> >& interpolator_, int storage_ );
00061 
00063   void setInterpolator(const RCP<InterpolatorBase<Scalar> >& interpolator_);
00064     
00066   RCP<InterpolatorBase<Scalar> >& unSetInterpolator();
00067 
00069   void setStorage( int storage );
00070     
00072   int getStorage() const;
00073         
00075   ~InterpolationBuffer() {};
00076 
00078   void addPoints(
00079     const Array<Scalar>& time_vec
00080     ,const Array<RCP<const Thyra::VectorBase<Scalar> > >& x_vec
00081     ,const Array<RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec);
00082 
00084   void getPoints(
00085     const Array<Scalar>& time_vec
00086     ,Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec
00087     ,Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec
00088     ,Array<ScalarMag>* accuracy_vec
00089     ) const;
00090 
00092   TimeRange<Scalar> getTimeRange() const;
00093 
00095   void getNodes(Array<Scalar>* time_vec) const;
00096 
00098   int getOrder() const;
00099     
00101   void removeNodes(Array<Scalar>& time_vec);
00102 
00104 
00105   std::string description() const;
00106 
00108   void describe(
00109     Teuchos::FancyOStream       &out
00110     ,const Teuchos::EVerbosityLevel      verbLevel
00111     ) const;
00112 
00114 
00115   void setParameterList(RCP<Teuchos::ParameterList> const& paramList);
00116 
00118   RCP<Teuchos::ParameterList> getNonconstParameterList();
00119 
00121   RCP<Teuchos::ParameterList> unsetParameterList();
00122 
00123   enum IBPolicy {
00124     BUFFER_STATIC = 0
00125     ,BUFFER_KEEP_NEWEST = 1
00126   };
00127     
00128 private:
00129 
00130   RCP<InterpolatorBase<Scalar> > interpolator_;
00131   int storage_limit_;
00132   typename DataStore<Scalar>::DataStoreVector_t data_vec_;
00133 
00134   RCP<Teuchos::ParameterList> parameterList_;
00135 
00136   IBPolicy policy_;
00137 
00138 };
00139 
00140 
00141 // ////////////////////////////
00142 // Defintions
00143 
00144 
00145 template<class Scalar>
00146 InterpolationBuffer<Scalar>::InterpolationBuffer()
00147 {
00148   initialize(Teuchos::null,0);
00149 }
00150 
00151 
00152 template<class Scalar>
00153 InterpolationBuffer<Scalar>::InterpolationBuffer( 
00154   const RCP<InterpolatorBase<Scalar> >& interpolator_
00155   ,int storage_ 
00156   )
00157 {
00158   initialize(interpolator_,storage_);
00159 }
00160 
00161 
00162 template<class Scalar>
00163 RCP<const Thyra::VectorSpaceBase<Scalar> >
00164 InterpolationBuffer<Scalar>::get_x_space() const
00165 {
00166   if (data_vec_.size() == 0) {
00167     RCP<const Thyra::VectorSpaceBase<Scalar> > space;
00168     return(space);
00169   } else {
00170     return(data_vec_[0].x->space());
00171   }
00172 }
00173 
00174 
00175 template<class Scalar>
00176 void InterpolationBuffer<Scalar>::initialize( 
00177   const RCP<InterpolatorBase<Scalar> >& interpolator_
00178   ,int storage_
00179   )
00180 {
00181   RCP<Teuchos::FancyOStream> out = this->getOStream();
00182   Teuchos::OSTab ostab(out,1,"IB::initialize");
00183   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00184     *out << "Initializing InterpolationBuffer" << std::endl;
00185     *out << "Calling setInterpolator..." << std::endl;
00186   }
00187   setInterpolator(interpolator_);
00188   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00189     *out << "Calling setStorage..." << std::endl;
00190   }
00191   setStorage(storage_);
00192   policy_ = BUFFER_KEEP_NEWEST;
00193 }
00194 
00195 template<class Scalar>
00196 void InterpolationBuffer<Scalar>::setStorage( int storage )
00197 {
00198   int storage_limit = std::max(2,storage); // Minimum of two points so interpolation is possible
00199   TEST_FOR_EXCEPTION(
00200     Teuchos::as<int>(data_vec_.size()) > storage_limit,
00201     std::logic_error,
00202     "Error, specified storage = " << storage_limit
00203     << " is below current number of vectors stored = " << data_vec_.size() << "!\n"
00204     );
00205   storage_limit_ = storage_limit;
00206   RCP<Teuchos::FancyOStream> out = this->getOStream();
00207   Teuchos::OSTab ostab(out,1,"IB::setStorage");
00208   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00209     *out << "storage_limit = " << storage_limit_ << std::endl;
00210   }
00211 }
00212 
00213 
00214 template<class Scalar>
00215 int InterpolationBuffer<Scalar>::getStorage() const
00216 {
00217   return(storage_limit_);
00218 }
00219 
00220 
00221 template<class Scalar>
00222 void InterpolationBuffer<Scalar>::setInterpolator(
00223   const RCP<InterpolatorBase<Scalar> >& interpolator
00224   )
00225 {
00226   if (interpolator_ == Teuchos::null) {
00227     interpolator_ = Teuchos::rcp(new LinearInterpolator<Scalar>);
00228   } else {
00229     interpolator_ = interpolator;
00230   }
00231   RCP<Teuchos::FancyOStream> out = this->getOStream();
00232   Teuchos::OSTab ostab(out,1,"IB::setInterpolator");
00233   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00234     *out << "interpolator = " << interpolator_->description() << std::endl;
00235   }
00236 }
00237 
00238 
00239 template<class Scalar>
00240 void InterpolationBuffer<Scalar>::addPoints( 
00241   const Array<Scalar>& time_vec
00242   ,const Array<RCP<const Thyra::VectorBase<Scalar> > >& x_vec
00243   ,const Array<RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec 
00244   )
00245 {
00246 #ifdef TEUCHOS_DEBUG
00247   // Check preconditions
00248   assertTimePointsAreSorted(time_vec);
00249   int tsize = time_vec.size();
00250   TEST_FOR_EXCEPTION(
00251     tsize == 0, std::logic_error,
00252     "Error, time_vec is empty!"
00253     );
00254   TEST_FOR_EXCEPTION(
00255     Teuchos::as<int>(x_vec.size()) == tsize, std::logic_error,
00256     "Error, size of x_vec = " << x_vec.size() << " != " << tsize << " = size of time_vec!\n"
00257     );
00258   TEST_FOR_EXCEPTION(
00259     Teuchos::as<int>(xdot_vec.size()) == tsize, std::logic_error,
00260     "Error, size of xdot_vec = " << x_vec.size() << " != " << tsize << " = size of time_vec!\n"
00261     );
00262   for (int i=0; i<tsize ; ++i) {
00263     TEST_FOR_EXCEPTION(
00264       x_vec[i] == Teuchos::null, std::logic_error,
00265       "Error, x_vec[" << i << "] == null!\n"
00266       );
00267     TEST_FOR_EXCEPTION(
00268       xdot_vec[i] == Teuchos::null, std::logic_error,
00269       "Error, xdot_vec[" << i << "] == null!\n"
00270       );
00271   }
00272   assertNoTimePointsInsideCurrentTimeRange(*this,time_vec);
00273 #endif // TEUCHOS_DEBUG
00274   RCP<Teuchos::FancyOStream> out = this->getOStream();
00275   Teuchos::OSTab ostab(out,1,"IB::setPoints");
00276   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00277     *out << "time_vec = " << std::endl;
00278     for (unsigned int i=0 ; i<time_vec.size() ; ++i) {
00279       *out << "time_vec[" << i << "] = " << time_vec[i] << std::endl;
00280     }
00281     *out << "x_vec = " << std::endl;
00282     for (unsigned int i=0 ; i<x_vec.size() ; ++i) {
00283       *out << "x_vec[" << i << "] = " << std::endl;
00284       x_vec[i]->describe(*out,Teuchos::VERB_EXTREME);
00285     }
00286     *out << "xdot_vec = " << std::endl;
00287     for (unsigned int i=0 ; i<xdot_vec.size() ; ++i) {
00288       *out << "xdot_vec[" << i << "] = " << std::endl;
00289       xdot_vec[i]->describe(*out,Teuchos::VERB_EXTREME);
00290     }
00291   }
00292   typename DataStore<Scalar>::DataStoreList_t input_data_list;
00293   vectorToDataStoreList<Scalar>(time_vec,x_vec,xdot_vec,&input_data_list);
00294   // Check that we're not going to exceed our storage limit:
00295   if ((data_vec_.size()+input_data_list.size()) > Teuchos::as<unsigned int>(storage_limit_)) { 
00296     if (policy_ == BUFFER_STATIC) {
00297       TEST_FOR_EXCEPTION(
00298         true, std::logic_error,
00299         "Error, buffer is full and buffer policy is BUFFER_STATIC, no points can be added\n"
00300         );
00301     } else if (policy_ == BUFFER_KEEP_NEWEST) {
00302       if (input_data_list.front() > data_vec_.back()) {
00303         // Case:  all of new points are past end of existing points
00304         // Remove points from the beginning of data_vec, then add new points
00305         int num_extra_points = input_data_list.size();
00306         typename DataStore<Scalar>::DataStoreVector_t::iterator 
00307           data_it = data_vec_.begin();
00308         for (int i=0 ; i < num_extra_points ; ++i) {
00309           data_it++;
00310         }
00311         if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00312           *out << "Removing " << num_extra_points 
00313                << " from beginning of data_vec to make room for new points." << std::endl;
00314         }
00315         data_vec_.erase(data_vec_.begin(),data_it);
00316       } else if (input_data_list.back() < data_vec_.front()) {
00317         // Case:  all of new points are before beginning of existing points
00318         // Remove points from end of data_vec, then add new points
00319         int num_extra_points = input_data_list.size();
00320         typename DataStore<Scalar>::DataStoreVector_t::iterator 
00321           data_it = data_vec_.end();
00322         for (int i=0 ; i < num_extra_points ; ++i) {
00323           data_it--;
00324         }
00325         if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00326           *out << "Removing " << num_extra_points 
00327                << " from end of data_vec to make room for new points." << std::endl;
00328         }
00329         data_vec_.erase(data_it,data_vec_.end());
00330       } else {
00331         // Case:  Some points are before beginning of data_vec and some points are after end of data_vec
00332         TEST_FOR_EXCEPTION(
00333           true, std::logic_error,
00334           "Error, incoming points are on both sides of TimeRange, this feature not implemented yet.\n"
00335           );
00336       }
00337     } else {
00338       // Unknown Buffer policy:
00339       TEST_FOR_EXCEPTION(
00340         true, std::logic_error,
00341         "Error, unknown buffer policy.\n"
00342         );
00343     }
00344   }
00345   // Now add all the remaining points to data_vec
00346   data_vec_.insert(data_vec_.end(),input_data_list.begin(),input_data_list.end());
00347   // And sort data_vec:
00348   std::sort(data_vec_.begin(),data_vec_.end());
00349   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00350     *out << "data_vec at end of setPoints:" << std::endl;
00351     for (unsigned int i=0 ; i<data_vec_.size() ; ++i) {
00352       *out << "data_vec[" << i << "] = " << std::endl;
00353       data_vec_[i].describe(*out,Teuchos::VERB_EXTREME);
00354     }
00355   }
00356 }
00357 
00358 
00359 template<class Scalar>
00360 void InterpolationBuffer<Scalar>::getPoints(
00361   const Array<Scalar>& time_vec
00362   ,Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec
00363   ,Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec
00364   ,Array<ScalarMag>* accuracy_vec
00365   ) const
00366 {
00367   RCP<Teuchos::FancyOStream> out = this->getOStream();
00368   Teuchos::OSTab ostab(out,1,"IB::getPoints");
00369   typename DataStore<Scalar>::DataStoreVector_t data_out;
00370   interpolator_->interpolate(data_vec_, time_vec, &data_out);
00371   Array<Scalar> time_out_vec;
00372   dataStoreVectorToVector<Scalar>(data_out, &time_out_vec, x_vec, xdot_vec, accuracy_vec);
00373   TEST_FOR_EXCEPTION(
00374     (time_vec.size() != time_out_vec.size()), std::logic_error,
00375     "Error, number of time points returned from interpolator = " <<
00376     time_out_vec.size() << " != " << time_vec.size() << 
00377     " = number of time points requested\n"
00378     );
00379   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00380     *out << "Conversion of DataStoreVector to Vector successful" << std::endl;
00381   }
00382 }
00383 
00384 
00385 template<class Scalar>
00386 TimeRange<Scalar> InterpolationBuffer<Scalar>::getTimeRange() const
00387 {
00388   TimeRange<Scalar> timerange;
00389   if (data_vec_.size() > 0) {
00390     timerange = TimeRange<Scalar>(data_vec_.front().time,data_vec_.back().time);
00391   }
00392   return(timerange);
00393 }
00394 
00395 
00396 template<class Scalar>
00397 void InterpolationBuffer<Scalar>::getNodes( Array<Scalar>* time_vec ) const
00398 {
00399   int N = data_vec_.size();
00400   time_vec->clear();
00401   time_vec->reserve(N);
00402   for (int i=0 ; i<N ; ++i) {
00403     time_vec->push_back(data_vec_[i].time);
00404   }
00405   RCP<Teuchos::FancyOStream> out = this->getOStream();
00406   Teuchos::OSTab ostab(out,1,"IB::getNodes");
00407   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00408     *out << this->description() << std::endl;
00409     for (unsigned int i=0 ; i<time_vec->size() ; ++i) {
00410       *out << "time_vec[" << i << "] = " << (*time_vec)[i] << std::endl;
00411     }
00412   }
00413 }
00414 
00415 
00416 template<class Scalar>
00417 void InterpolationBuffer<Scalar>::removeNodes( Array<Scalar>& time_vec ) 
00418 {
00419   typedef Teuchos::ScalarTraits<Scalar> ST;
00420   int N = time_vec.size();
00421 #ifdef TEUCHOS_DEBUG
00422   // Check preconditions:
00423   TimeRange<Scalar> range = this->getTimeRange();
00424   for (int i=0; i<N ; ++i) {
00425     TEST_FOR_EXCEPTION(
00426       ~(range.lower() <= time_vec[i]) && (time_vec[i] <= range.upper()),
00427       std::logic_error,
00428       "Error, time_vec[" << i << "] = " << time_vec[i] << 
00429       "is not in range of this interpolation buffer = [" << 
00430       range.lower() << "," << range.upper() << "]!\n"
00431       );
00432   }
00433 #endif // TEUCHOS_DEBUG
00434   RCP<Thyra::VectorBase<Scalar> > vec_temp;
00435   ScalarMag z = ST::zero();
00436   for (int i=0; i<N ; ++i) {
00437     DataStore<Scalar> ds_temp(time_vec[i],vec_temp,vec_temp,z);
00438     typename DataStore<Scalar>::DataStoreVector_t::iterator 
00439       data_it = std::find(data_vec_.begin(),data_vec_.end(),ds_temp);
00440     TEST_FOR_EXCEPTION(
00441       data_it == data_vec_.end(), std::logic_error,
00442       "Error, time_vec[" << i << "] = " << time_vec[i] << "is not a node in the interpolation buffer!\n"
00443       );
00444     data_vec_.erase(data_it);
00445   }
00446 }
00447 
00448 
00449 template<class Scalar>
00450 int InterpolationBuffer<Scalar>::getOrder() const
00451 {
00452   return(interpolator_->order());
00453 }
00454 
00455 
00456 template<class Scalar>
00457 std::string InterpolationBuffer<Scalar>::description() const
00458 {
00459   std::string name = "Rythmos::InterpolationBuffer";
00460   return(name);
00461 }
00462 
00463 
00464 template<class Scalar>
00465 void InterpolationBuffer<Scalar>::describe(
00466   Teuchos::FancyOStream                &out
00467   ,const Teuchos::EVerbosityLevel      verbLevel
00468   ) const
00469 {
00470   if ( (Teuchos::as<int>(verbLevel) == Teuchos::as<int>(Teuchos::VERB_DEFAULT) ) ||
00471     (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW)     )
00472     ) {
00473     out << description() << "::describe" << std::endl;
00474     out << "interpolator = " << interpolator_->description() << std::endl;
00475     out << "storage_limit = " << storage_limit_ << std::endl;
00476   } else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW)) {
00477   } else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM)) {
00478   } else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_HIGH)) {
00479     out << "data_vec = " << std::endl;
00480     for (unsigned int i=0; i<data_vec_.size() ; ++i) {
00481       out << "data_vec[" << i << "] = " << std::endl;
00482       data_vec_[i].describe(out,this->getVerbLevel());
00483     }
00484   }
00485 }
00486 
00487 
00488 template <class Scalar>
00489 void InterpolationBuffer<Scalar>::setParameterList(RCP<Teuchos::ParameterList> const& paramList)
00490 {
00491   // 2007/12/05: rabartl: ToDo: Validate the parameter list!
00492   parameterList_ = paramList;
00493   int outputLevel = parameterList_->get( "outputLevel", int(-1) );
00494   outputLevel = std::min(std::max(outputLevel,-1),4);
00495   this->setVerbLevel(static_cast<Teuchos::EVerbosityLevel>(outputLevel));
00496   int policyLevel = parameterList_->get( "InterpolationBufferPolicy", int(1) );
00497   policyLevel = std::min(std::max(policyLevel,0),1);
00498   policy_ = static_cast<IBPolicy>(policyLevel);
00499   int storage_limit = parameterList_->get( "StorageLimit", storage_limit_ );
00500   if (storage_limit != storage_limit_) {
00501     this->setStorage(storage_limit);
00502   }
00503 }
00504 
00505 
00506 template <class Scalar>
00507 RCP<Teuchos::ParameterList>
00508 InterpolationBuffer<Scalar>::getNonconstParameterList()
00509 {
00510   return(parameterList_);
00511 }
00512 
00513 
00514 template <class Scalar>
00515 RCP<Teuchos::ParameterList> InterpolationBuffer<Scalar>::unsetParameterList()
00516 {
00517   RCP<Teuchos::ParameterList> temp_param_list = parameterList_;
00518   parameterList_ = Teuchos::null;
00519   return(temp_param_list);
00520 }
00521 
00522 
00523 } // namespace Rythmos
00524 
00525 
00526 #endif // Rythmos_INTERPOLATION_BUFFER_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends

Generated on Tue Oct 20 10:24:09 2009 for Rythmos - Transient Integration for Differential Equations by  doxygen 1.6.1