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 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
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);
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
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
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
00304
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
00318
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
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
00339 TEST_FOR_EXCEPTION(
00340 true, std::logic_error,
00341 "Error, unknown buffer policy.\n"
00342 );
00343 }
00344 }
00345
00346 data_vec_.insert(data_vec_.end(),input_data_list.begin(),input_data_list.end());
00347
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
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
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 }
00524
00525
00526 #endif // Rythmos_INTERPOLATION_BUFFER_H