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_DEF_H
00030 #define Rythmos_INTERPOLATION_BUFFER_DEF_H
00031
00032 #include "Rythmos_InterpolationBuffer_decl.hpp"
00033 #include "Rythmos_InterpolatorBaseHelpers.hpp"
00034 #include "Rythmos_LinearInterpolator.hpp"
00035 #include "Thyra_VectorStdOps.hpp"
00036 #include "Teuchos_StandardParameterEntryValidators.hpp"
00037 #include "Teuchos_VerboseObjectParameterListHelpers.hpp"
00038
00039 namespace {
00040
00041 static std::string IBPolicyTypeInvalid_name = "Invalid Policy";
00042 static std::string IBPolicyTypeStatic_name = "Static Policy";
00043 static std::string IBPolicyTypeKeepNewest_name = "Keep Newest Policy";
00044 static std::string interpolationBufferPolicySelection_name = "InterpolationBufferPolicy";
00045 static std::string interpolationBufferPolicySelection_default = IBPolicyTypeKeepNewest_name;
00046
00047 static std::string interpolationBufferStorageLimit_name = "StorageLimit";
00048 static int interpolationBufferStorageLimit_default = 0;
00049
00050 Teuchos::Array<std::string>
00051 S_InterpolationBufferPolicyTypes = Teuchos::tuple<std::string>(
00052 IBPolicyTypeInvalid_name,
00053 IBPolicyTypeStatic_name,
00054 IBPolicyTypeKeepNewest_name
00055 );
00056
00057 const Teuchos::RCP<Teuchos::StringToIntegralParameterEntryValidator<Rythmos::IBPolicy> >
00058 interpolationBufferPolicyValidator = Teuchos::rcp(
00059 new Teuchos::StringToIntegralParameterEntryValidator<Rythmos::IBPolicy>(
00060 S_InterpolationBufferPolicyTypes,
00061 Teuchos::tuple<Rythmos::IBPolicy>(
00062 Rythmos::BUFFER_POLICY_INVALID,
00063 Rythmos::BUFFER_POLICY_STATIC,
00064 Rythmos::BUFFER_POLICY_KEEP_NEWEST
00065 ),
00066 interpolationBufferPolicySelection_name
00067 )
00068 );
00069
00070 }
00071
00072
00073 namespace Rythmos {
00074
00075
00076
00077
00078
00079 template<class Scalar>
00080 InterpolationBuffer<Scalar>::InterpolationBuffer()
00081 {
00082 this->defaultInitializeAll_();
00083 initialize(Teuchos::null,0);
00084 }
00085
00086 template<class Scalar>
00087 void InterpolationBuffer<Scalar>::defaultInitializeAll_()
00088 {
00089 interpolator_ = Teuchos::null;
00090 storage_limit_ = -1;
00091 data_vec_ = Teuchos::null;
00092 paramList_ = Teuchos::null;
00093 policy_ = BUFFER_POLICY_INVALID;
00094 }
00095
00096 template<class Scalar>
00097 RCP<const Thyra::VectorSpaceBase<Scalar> >
00098 InterpolationBuffer<Scalar>::get_x_space() const
00099 {
00100 if (data_vec_->size() == 0) {
00101 RCP<const Thyra::VectorSpaceBase<Scalar> > space;
00102 return(space);
00103 } else {
00104 return((*data_vec_)[0].x->space());
00105 }
00106 }
00107
00108
00109 template<class Scalar>
00110 void InterpolationBuffer<Scalar>::initialize(
00111 const RCP<InterpolatorBase<Scalar> >& interpolator
00112 ,int storage
00113 )
00114 {
00115 RCP<Teuchos::FancyOStream> out = this->getOStream();
00116 Teuchos::OSTab ostab(out,1,"IB::initialize");
00117 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00118 *out << "Initializing InterpolationBuffer" << std::endl;
00119 *out << "Calling setInterpolator..." << std::endl;
00120 }
00121 data_vec_ = rcp(new typename DataStore<Scalar>::DataStoreVector_t);
00122 setInterpolator(interpolator);
00123 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00124 *out << "Calling setStorage..." << std::endl;
00125 }
00126 setStorage(storage);
00127 policy_ = BUFFER_POLICY_KEEP_NEWEST;
00128 }
00129
00130 template<class Scalar>
00131 void InterpolationBuffer<Scalar>::setStorage( int storage )
00132 {
00133 int storage_limit = std::max(2,storage);
00134 TEST_FOR_EXCEPTION(
00135 Teuchos::as<int>(data_vec_->size()) > storage_limit,
00136 std::logic_error,
00137 "Error, specified storage = " << storage_limit
00138 << " is below current number of vectors stored = " << data_vec_->size() << "!\n"
00139 );
00140 storage_limit_ = storage_limit;
00141 RCP<Teuchos::FancyOStream> out = this->getOStream();
00142 Teuchos::OSTab ostab(out,1,"IB::setStorage");
00143 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00144 *out << "storage_limit = " << storage_limit_ << std::endl;
00145 }
00146 }
00147
00148
00149 template<class Scalar>
00150 int InterpolationBuffer<Scalar>::getStorage() const
00151 {
00152 return(storage_limit_);
00153 }
00154
00155
00156 template<class Scalar>
00157 void InterpolationBuffer<Scalar>::setInterpolator(
00158 const RCP<InterpolatorBase<Scalar> >& interpolator
00159 )
00160 {
00161 if (interpolator == Teuchos::null) {
00162 interpolator_ = linearInterpolator<Scalar>();
00163 } else {
00164 interpolator_ = interpolator;
00165 }
00166 RCP<Teuchos::FancyOStream> out = this->getOStream();
00167 Teuchos::OSTab ostab(out,1,"IB::setInterpolator");
00168 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00169 *out << "interpolator = " << interpolator_->description() << std::endl;
00170 }
00171 }
00172
00173 template<class Scalar>
00174 RCP<InterpolatorBase<Scalar> >
00175 InterpolationBuffer<Scalar>::getNonconstInterpolator()
00176 {
00177 return interpolator_;
00178 }
00179
00180 template<class Scalar>
00181 RCP<const InterpolatorBase<Scalar> >
00182 InterpolationBuffer<Scalar>::getInterpolator() const
00183 {
00184 return interpolator_;
00185 }
00186
00187 template<class Scalar>
00188 RCP<InterpolatorBase<Scalar> > InterpolationBuffer<Scalar>::unSetInterpolator()
00189 {
00190 RCP<InterpolatorBase<Scalar> > old_interpolator = interpolator_;
00191 interpolator_ = linearInterpolator<Scalar>();
00192 return old_interpolator;
00193 }
00194
00195
00196 template<class Scalar>
00197 void InterpolationBuffer<Scalar>::addPoints(
00198 const Array<Scalar>& time_vec
00199 ,const Array<RCP<const Thyra::VectorBase<Scalar> > >& x_vec
00200 ,const Array<RCP<const Thyra::VectorBase<Scalar> > >& xdot_vec
00201 )
00202 {
00203 #ifdef RYTHMOS_DEBUG
00204
00205 assertTimePointsAreSorted(time_vec);
00206 int tsize = Teuchos::as<int>(time_vec.size());
00207 TEST_FOR_EXCEPTION(
00208 tsize == 0, std::logic_error,
00209 "Error, time_vec is empty!"
00210 );
00211 TEST_FOR_EXCEPTION(
00212 Teuchos::as<int>(x_vec.size()) != tsize, std::logic_error,
00213 "Error, size of x_vec = " << x_vec.size() << " != " << tsize << " = size of time_vec!\n"
00214 );
00215 TEST_FOR_EXCEPTION(
00216 Teuchos::as<int>(xdot_vec.size()) != tsize, std::logic_error,
00217 "Error, size of xdot_vec = " << x_vec.size() << " != " << tsize << " = size of time_vec!\n"
00218 );
00219 for (int i=0; i<tsize ; ++i) {
00220 TEST_FOR_EXCEPTION(
00221 x_vec[i] == Teuchos::null, std::logic_error,
00222 "Error, x_vec[" << i << "] == null!\n"
00223 );
00224
00225
00226
00227
00228 }
00229 assertNoTimePointsInsideCurrentTimeRange(*this,time_vec);
00230 #endif // RYTHMOS_DEBUG
00231 RCP<Teuchos::FancyOStream> out = this->getOStream();
00232 Teuchos::OSTab ostab(out,1,"IB::addPoints");
00233 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00234 *out << "time_vec = " << std::endl;
00235 for (unsigned int i=0 ; i<time_vec.size() ; ++i) {
00236 *out << "time_vec[" << i << "] = " << time_vec[i] << std::endl;
00237 }
00238 *out << "x_vec = " << std::endl;
00239 for (unsigned int i=0 ; i<x_vec.size() ; ++i) {
00240 *out << "x_vec[" << i << "] = " << std::endl;
00241 x_vec[i]->describe(*out,Teuchos::VERB_EXTREME);
00242 }
00243 *out << "xdot_vec = " << std::endl;
00244 for (unsigned int i=0 ; i<xdot_vec.size() ; ++i) {
00245 if (!is_null(xdot_vec[i])) {
00246 *out << "xdot_vec[" << i << "] = " << std::endl;
00247 xdot_vec[i]->describe(*out,Teuchos::VERB_EXTREME);
00248 }
00249 }
00250 }
00251 typename DataStore<Scalar>::DataStoreList_t input_data_list;
00252 vectorToDataStoreList<Scalar>(time_vec,x_vec,xdot_vec,&input_data_list);
00253
00254 if (Teuchos::as<int>(data_vec_->size()+input_data_list.size()) > storage_limit_) {
00255 if (policy_ == BUFFER_POLICY_STATIC) {
00256 TEST_FOR_EXCEPTION(
00257 true, std::logic_error,
00258 "Error, buffer would be over-full and buffer policy is BUFFER_POLICY_STATIC, these points can not be added\n"
00259 );
00260 } else if (policy_ == BUFFER_POLICY_KEEP_NEWEST) {
00261 if (input_data_list.front() > data_vec_->back()) {
00262
00263
00264 int num_extra_points = input_data_list.size()-(storage_limit_-data_vec_->size());
00265 #ifdef RYTHMOS_DEBUG
00266 TEST_FOR_EXCEPTION( num_extra_points <= 0, std::logic_error,
00267 "Error! Buffer policy is keep newest and input data size = " << input_data_list.size() << ", storage limit = " << storage_limit_ << ", and data_vec size = " << data_vec_->size() << ". Somehow number of points to delete = " << num_extra_points << " <= 0!"
00268 );
00269 #endif // RYTHMOS_DEBUG
00270 typename DataStore<Scalar>::DataStoreVector_t::iterator
00271 data_it = data_vec_->begin();
00272 for (int i=0 ; i < num_extra_points ; ++i) {
00273 data_it++;
00274 }
00275 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00276 *out << "Removing " << num_extra_points
00277 << " from beginning of data_vec to make room for new points." << std::endl;
00278 }
00279 data_vec_->erase(data_vec_->begin(),data_it);
00280 } else if (input_data_list.back() < data_vec_->front()) {
00281
00282
00283 int num_extra_points = input_data_list.size()-(storage_limit_-data_vec_->size());
00284 #ifdef RYTHMOS_DEBUG
00285 TEST_FOR_EXCEPTION( num_extra_points <= 0, std::logic_error,
00286 "Error! Buffer policy is keep newest and input data size = " << input_data_list.size() << ", storage limit = " << storage_limit_ << ", and data_vec size = " << data_vec_->size() << ". Somehow number of points to delete = " << num_extra_points << " <= 0!"
00287 );
00288 #endif // RYTHMOS_DEBUG
00289 typename DataStore<Scalar>::DataStoreVector_t::iterator
00290 data_it = data_vec_->end();
00291 for (int i=0 ; i < num_extra_points ; ++i) {
00292 data_it--;
00293 }
00294 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00295 *out << "Removing " << num_extra_points
00296 << " from end of data_vec to make room for new points." << std::endl;
00297 }
00298 data_vec_->erase(data_it,data_vec_->end());
00299 } else {
00300
00301 TEST_FOR_EXCEPTION(
00302 true, std::logic_error,
00303 "Error, incoming points are on both sides of TimeRange, I don't know which points are newest in this case.\n"
00304 );
00305 }
00306 } else {
00307
00308 TEST_FOR_EXCEPTION(
00309 true, std::logic_error,
00310 "Error, unknown buffer policy.\n"
00311 );
00312 }
00313 }
00314
00315 std::list<DataStore<Scalar> > internal_input_data_list;
00316 typename DataStore<Scalar>::DataStoreList_t::iterator it_list;
00317 for (it_list = input_data_list.begin() ; it_list != input_data_list.end() ; it_list++) {
00318 RCP<DataStore<Scalar> > ds_clone = it_list->clone();
00319 internal_input_data_list.push_back(*ds_clone);
00320 }
00321
00322 data_vec_->insert(data_vec_->end(),internal_input_data_list.begin(),internal_input_data_list.end());
00323
00324 std::sort(data_vec_->begin(),data_vec_->end());
00325 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00326 *out << "data_vec at end of addPoints:" << std::endl;
00327 for (unsigned int i=0 ; i<data_vec_->size() ; ++i) {
00328 *out << "data_vec[" << i << "] = " << std::endl;
00329 (*data_vec_)[i].describe(*out,Teuchos::VERB_EXTREME);
00330 }
00331 }
00332 }
00333
00334
00335 template<class Scalar>
00336 void InterpolationBuffer<Scalar>::getPoints(
00337 const Array<Scalar>& time_vec
00338 ,Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec
00339 ,Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec
00340 ,Array<ScalarMag>* accuracy_vec
00341 ) const
00342 {
00343 RCP<Teuchos::FancyOStream> out = this->getOStream();
00344 Teuchos::OSTab ostab(out,1,"IB::getPoints");
00345 typename DataStore<Scalar>::DataStoreVector_t data_out;
00346 interpolate<Scalar>(*interpolator_, data_vec_, time_vec, &data_out);
00347 Array<Scalar> time_out_vec;
00348 dataStoreVectorToVector<Scalar>(data_out, &time_out_vec, x_vec, xdot_vec, accuracy_vec);
00349 TEST_FOR_EXCEPTION(
00350 (time_vec.size() != time_out_vec.size()), std::logic_error,
00351 "Error, number of time points returned from interpolator = " <<
00352 time_out_vec.size() << " != " << time_vec.size() <<
00353 " = number of time points requested\n"
00354 );
00355 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00356 *out << "Conversion of DataStoreVector to Vector successful" << std::endl;
00357 }
00358 }
00359
00360
00361 template<class Scalar>
00362 TimeRange<Scalar> InterpolationBuffer<Scalar>::getTimeRange() const
00363 {
00364 TimeRange<Scalar> timerange;
00365 if (data_vec_->size() > 0) {
00366 timerange = TimeRange<Scalar>(data_vec_->front().time,data_vec_->back().time);
00367 }
00368 return(timerange);
00369 }
00370
00371
00372 template<class Scalar>
00373 void InterpolationBuffer<Scalar>::getNodes( Array<Scalar>* time_vec ) const
00374 {
00375 int N = data_vec_->size();
00376 time_vec->clear();
00377 time_vec->reserve(N);
00378 for (int i=0 ; i<N ; ++i) {
00379 time_vec->push_back((*data_vec_)[i].time);
00380 }
00381 RCP<Teuchos::FancyOStream> out = this->getOStream();
00382 Teuchos::OSTab ostab(out,1,"IB::getNodes");
00383 if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00384 *out << this->description() << std::endl;
00385 for (unsigned int i=0 ; i<time_vec->size() ; ++i) {
00386 *out << "time_vec[" << i << "] = " << (*time_vec)[i] << std::endl;
00387 }
00388 }
00389 }
00390
00391
00392 template<class Scalar>
00393 void InterpolationBuffer<Scalar>::removeNodes( Array<Scalar>& time_vec )
00394 {
00395 typedef Teuchos::ScalarTraits<Scalar> ST;
00396 int N = time_vec.size();
00397 #ifdef RYTHMOS_DEBUG
00398
00399 TimeRange<Scalar> range = this->getTimeRange();
00400 for (int i=0; i<N ; ++i) {
00401 TEST_FOR_EXCEPTION(
00402 ~(range.lower() <= time_vec[i]) && (time_vec[i] <= range.upper()),
00403 std::logic_error,
00404 "Error, time_vec[" << i << "] = " << time_vec[i] <<
00405 "is not in range of this interpolation buffer = [" <<
00406 range.lower() << "," << range.upper() << "]!\n"
00407 );
00408 }
00409 #endif // RYTHMOS_DEBUG
00410 RCP<Thyra::VectorBase<Scalar> > vec_temp;
00411 ScalarMag z = ST::zero();
00412 for (int i=0; i<N ; ++i) {
00413 DataStore<Scalar> ds_temp(time_vec[i],vec_temp,vec_temp,z);
00414 typename DataStore<Scalar>::DataStoreVector_t::iterator
00415 data_it = std::find(data_vec_->begin(),data_vec_->end(),ds_temp);
00416 TEST_FOR_EXCEPTION(
00417 data_it == data_vec_->end(), std::logic_error,
00418 "Error, time_vec[" << i << "] = " << time_vec[i] << "is not a node in the interpolation buffer!\n"
00419 );
00420 data_vec_->erase(data_it);
00421 }
00422 }
00423
00424
00425 template<class Scalar>
00426 int InterpolationBuffer<Scalar>::getOrder() const
00427 {
00428 return(interpolator_->order());
00429 }
00430
00431
00432 template<class Scalar>
00433 std::string InterpolationBuffer<Scalar>::description() const
00434 {
00435 std::string name = "Rythmos::InterpolationBuffer";
00436 return(name);
00437 }
00438
00439
00440 template<class Scalar>
00441 void InterpolationBuffer<Scalar>::describe(
00442 Teuchos::FancyOStream &out
00443 ,const Teuchos::EVerbosityLevel verbLevel
00444 ) const
00445 {
00446 if ( (Teuchos::as<int>(verbLevel) == Teuchos::as<int>(Teuchos::VERB_DEFAULT) ) ||
00447 (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW) )
00448 ) {
00449 out << description() << "::describe" << std::endl;
00450 out << "interpolator = " << interpolator_->description() << std::endl;
00451 out << "storage_limit = " << storage_limit_ << std::endl;
00452 } else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW)) {
00453 } else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM)) {
00454 } else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_HIGH)) {
00455 out << "data_vec = " << std::endl;
00456 for (unsigned int i=0; i<data_vec_->size() ; ++i) {
00457 out << "data_vec[" << i << "] = " << std::endl;
00458 (*data_vec_)[i].describe(out,this->getVerbLevel());
00459 }
00460 }
00461 }
00462
00463
00464 template <class Scalar>
00465 void InterpolationBuffer<Scalar>::setParameterList(RCP<Teuchos::ParameterList> const& paramList)
00466 {
00467 TEST_FOR_EXCEPT( is_null(paramList) );
00468 paramList->validateParameters(*this->getValidParameters());
00469 paramList_ = paramList;
00470
00471 Teuchos::readVerboseObjectSublist(&*paramList_,this);
00472
00473
00474
00475
00476 IBPolicy policyLevel = interpolationBufferPolicyValidator->getIntegralValue(
00477 *paramList_, interpolationBufferPolicySelection_name, interpolationBufferPolicySelection_default
00478 );
00479 if (policyLevel != BUFFER_POLICY_INVALID) {
00480 policy_ = policyLevel;
00481 }
00482 int storage_limit = paramList_->get( interpolationBufferStorageLimit_name, interpolationBufferStorageLimit_default);
00483 setStorage(storage_limit);
00484 }
00485
00486 template<class Scalar>
00487 RCP<const Teuchos::ParameterList> InterpolationBuffer<Scalar>::getValidParameters() const
00488 {
00489 static RCP<Teuchos::ParameterList> validPL;
00490
00491 if (is_null(validPL)) {
00492
00493 RCP<Teuchos::ParameterList>
00494 pl = Teuchos::parameterList();
00495
00496 Teuchos::setupVerboseObjectSublist(&*pl);
00497
00498 pl->set(
00499 interpolationBufferPolicySelection_name,
00500 interpolationBufferPolicySelection_default,
00501 "Interpolation Buffer Policy for when the maximum storage size is exceeded. Static will throw an exception when the storage limit is exceeded. Keep Newest will over-write the oldest data in the buffer when the storage limit is exceeded.",
00502 interpolationBufferPolicyValidator
00503 );
00504
00505 pl->set(
00506 interpolationBufferStorageLimit_name,
00507 interpolationBufferStorageLimit_default,
00508 "Storage limit for the interpolation buffer."
00509 );
00510
00511 validPL = pl;
00512
00513 }
00514 return validPL;
00515 }
00516
00517
00518 template <class Scalar>
00519 RCP<Teuchos::ParameterList>
00520 InterpolationBuffer<Scalar>::getNonconstParameterList()
00521 {
00522 return(paramList_);
00523 }
00524
00525
00526 template <class Scalar>
00527 RCP<Teuchos::ParameterList> InterpolationBuffer<Scalar>::unsetParameterList()
00528 {
00529 RCP<Teuchos::ParameterList> temp_param_list = paramList_;
00530 paramList_ = Teuchos::null;
00531 return(temp_param_list);
00532 }
00533
00534 template <class Scalar>
00535 IBPolicy InterpolationBuffer<Scalar>::getIBPolicy()
00536 {
00537 return policy_;
00538 }
00539
00540
00541
00542
00543
00544
00545
00546 #define RYTHMOS_INTERPOLATION_BUFFER_INSTANT(SCALAR) \
00547 \
00548 template class InterpolationBuffer< SCALAR >; \
00549 \
00550 template RCP<InterpolationBuffer< SCALAR > > interpolationBuffer( \
00551 const RCP<InterpolatorBase< SCALAR > >& interpolator, \
00552 int storage \
00553 );
00554
00555 }
00556
00557
00558 #endif // Rythmos_INTERPOLATION_BUFFER_DEF_H