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_HELPERS_HPP
00030 #define Rythmos_INTERPOLATION_BUFFER_HELPERS_HPP
00031
00032
00033 #include "Rythmos_InterpolationBufferBase.hpp"
00034 #include "Teuchos_Assert.hpp"
00035 #include "Teuchos_as.hpp"
00036
00037
00038 namespace Rythmos {
00039
00040
00045 template<class Scalar>
00046 void assertTimePointsAreSorted(const Array<Scalar>& time_vec);
00047
00048
00066 template<class Scalar>
00067 void assertNoTimePointsBeforeCurrentTimeRange(
00068 const InterpolationBufferBase<Scalar> &interpBuffer,
00069 const Array<Scalar>& time_vec,
00070 const int &startingTimePointIndex = 0
00071 );
00072
00073
00088 template<class Scalar>
00089 void assertNoTimePointsInsideCurrentTimeRange(
00090 const InterpolationBufferBase<Scalar> &interpBuffer,
00091 const Array<Scalar>& time_vec
00092 );
00093
00094
00099 template<class TimeType>
00100 void selectPointsInTimeRange(
00101 const Array<TimeType>& points_in,
00102 const TimeRange<TimeType>& range,
00103 const Ptr<Array<TimeType> >& points_out
00104 );
00105
00106
00111 template<class TimeType>
00112 void removePointsInTimeRange(
00113 Array<TimeType>* points_in,
00114 const TimeRange<TimeType>& range
00115 );
00116
00117
00164 template<class Scalar>
00165 bool getCurrentPoints(
00166 const InterpolationBufferBase<Scalar> &interpBuffer,
00167 const Array<Scalar>& time_vec,
00168 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec,
00169 Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec,
00170 int *nextTimePointIndex
00171 );
00172
00173
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 template<class Scalar>
00183 void Rythmos::assertTimePointsAreSorted(const Array<Scalar>& time_vec)
00184 {
00185 const int numTimePoints = time_vec.size();
00186 for ( int i = 0; i < numTimePoints-1; ++ i ) {
00187 TEST_FOR_EXCEPTION(
00188 time_vec[i] >= time_vec[i+1], std::logic_error,
00189 "Error, the time vector points time_vec["<<i<<"] = " << time_vec[i]
00190 << " >= time_vec["<<i+1<<"] = " << time_vec[i+1] << " are not [unique|sorted]!"
00191 );
00192 }
00193 }
00194
00195
00196 template<class Scalar>
00197 void Rythmos::assertNoTimePointsBeforeCurrentTimeRange(
00198 const InterpolationBufferBase<Scalar> &interpBuffer,
00199 const Array<Scalar>& time_vec,
00200 const int &startingTimePointIndex
00201 )
00202 {
00203 typedef ScalarTraits<Scalar> ST;
00204 const int numTimePoints = time_vec.size();
00205 const TimeRange<Scalar> currentTimeRange = interpBuffer.getTimeRange();
00206 if (currentTimeRange.length() >= ST::zero()) {
00207 for ( int i = 0; i < numTimePoints; ++i ) {
00208 TEST_FOR_EXCEPTION(
00209 time_vec[i] < currentTimeRange.lower(), std::out_of_range,
00210 "Error, time_vec["<<i<<"] = " << time_vec[i] << " < currentTimeRange.lower() = "
00211 << currentTimeRange.lower() << " for " << interpBuffer.description() << "!"
00212 );
00213 }
00214 }
00215 }
00216
00217
00218 template<class Scalar>
00219 void Rythmos::assertNoTimePointsInsideCurrentTimeRange(
00220 const InterpolationBufferBase<Scalar>& interpBuffer,
00221 const Array<Scalar>& time_vec
00222 )
00223 {
00224 typedef ScalarTraits<Scalar> ST;
00225 const int numTimePoints = time_vec.size();
00226 const TimeRange<Scalar> currentTimeRange = interpBuffer.getTimeRange();
00227 if (currentTimeRange.length() >= ST::zero()) {
00228 for ( int i = 0; i < numTimePoints; ++i ) {
00229 TEST_FOR_EXCEPTION(
00230 currentTimeRange.isInRange(time_vec[i]), std::out_of_range,
00231 "Error, time_vec["<<i<<"] = " << time_vec[i] << " is in TimeRange of "
00232 << interpBuffer.description() << " = ["
00233 << currentTimeRange.lower() << "," << currentTimeRange.upper() << "]!"
00234 );
00235 }
00236 }
00237 }
00238
00239
00240 template<class TimeType>
00241 void Rythmos::selectPointsInTimeRange(
00242 const Array<TimeType>& points_in,
00243 const TimeRange<TimeType>& range,
00244 const Ptr<Array<TimeType> >& points_out
00245 )
00246 {
00247 points_out->clear();
00248 int Nt = Teuchos::as<int>(points_in.size());
00249 for (int i=0; i < Nt ; ++i) {
00250 if (range.isInRange(points_in[i])) {
00251 points_out->push_back(points_in[i]);
00252 }
00253 }
00254 }
00255
00256
00257 template<class TimeType>
00258 void Rythmos::removePointsInTimeRange(
00259 Array<TimeType>* points_in,
00260 const TimeRange<TimeType>& range
00261 )
00262 {
00263 Array<TimeType> values_to_remove;
00264 for (int i=0 ; i<Teuchos::as<int>(points_in->size()) ; ++i) {
00265 if (range.isInRange((*points_in)[i])) {
00266 values_to_remove.push_back((*points_in)[i]);
00267 }
00268 }
00269 typename Array<TimeType>::iterator point_it;
00270 for (int i=0 ; i< Teuchos::as<int>(values_to_remove.size()) ; ++i) {
00271 point_it = std::find(points_in->begin(),points_in->end(),values_to_remove[i]);
00272 TEST_FOR_EXCEPTION(
00273 point_it == points_in->end(), std::logic_error,
00274 "Error, point to remove = " << values_to_remove[i] << " not found with std:find!\n"
00275 );
00276 points_in->erase(point_it);
00277 }
00278 }
00279
00280
00281 template<class Scalar>
00282 bool Rythmos::getCurrentPoints(
00283 const InterpolationBufferBase<Scalar> &interpBuffer,
00284 const Array<Scalar>& time_vec,
00285 Array<RCP<const Thyra::VectorBase<Scalar> > >* x_vec,
00286 Array<RCP<const Thyra::VectorBase<Scalar> > >* xdot_vec,
00287 int *nextTimePointIndex_inout
00288 )
00289 {
00290
00291 typedef ScalarTraits<Scalar> ST;
00292 using Teuchos::as;
00293
00294 const int numTotalTimePoints = time_vec.size();
00295
00296
00297 #ifdef RYTHMOS_DEBUG
00298 TEST_FOR_EXCEPT(nextTimePointIndex_inout==0);
00299 TEUCHOS_ASSERT( 0 <= *nextTimePointIndex_inout && *nextTimePointIndex_inout < numTotalTimePoints );
00300 TEUCHOS_ASSERT( x_vec == 0 || as<int>(x_vec->size()) == numTotalTimePoints );
00301 TEUCHOS_ASSERT( xdot_vec == 0 || as<int>(xdot_vec->size()) == numTotalTimePoints );
00302 #endif // RYTHMOS_DEBUG
00303
00304 int &nextTimePointIndex = *nextTimePointIndex_inout;
00305 const int initNextTimePointIndex = nextTimePointIndex;
00306
00307 const TimeRange<Scalar> currentTimeRange = interpBuffer.getTimeRange();
00308
00309 if (currentTimeRange.length() >= ST::zero()) {
00310
00311
00312
00313 Array<Scalar> current_time_vec;
00314 int i;
00315 for ( i = 0; i < numTotalTimePoints-nextTimePointIndex; ++i ) {
00316 const Scalar t = time_vec[nextTimePointIndex];
00317 #ifdef RYTHMOS_DEBUG
00318 TEUCHOS_ASSERT( t >= currentTimeRange.lower() );
00319 #endif // RYTHMOS_DEBUG
00320 if ( currentTimeRange.isInRange(t) ) {
00321 ++nextTimePointIndex;
00322 current_time_vec.push_back(t);
00323 }
00324 else {
00325 break;
00326 }
00327 }
00328 #ifdef RYTHMOS_DEBUG
00329
00330
00331 TEUCHOS_ASSERT( nextTimePointIndex-initNextTimePointIndex == i );
00332 #endif
00333
00334
00335
00336 const int numCurrentTimePoints = current_time_vec.size();
00337
00338 if ( numCurrentTimePoints > 0 ) {
00339
00340
00341
00342 Array<RCP<const Thyra::VectorBase<Scalar> > > current_x_vec;
00343 Array<RCP<const Thyra::VectorBase<Scalar> > > current_xdot_vec;
00344 if (x_vec || xdot_vec) {
00345 interpBuffer.getPoints(
00346 current_time_vec,
00347 x_vec ? ¤t_x_vec : 0,
00348 xdot_vec ? ¤t_xdot_vec : 0,
00349 0
00350 );
00351 }
00352
00353
00354
00355 for ( int i = initNextTimePointIndex; i < nextTimePointIndex; ++i ) {
00356 if (x_vec)
00357 (*x_vec)[i] = current_x_vec[i-initNextTimePointIndex];
00358 if (xdot_vec)
00359 (*xdot_vec)[i] = current_xdot_vec[i-initNextTimePointIndex];
00360 }
00361
00362 }
00363
00364 }
00365
00366 return ( nextTimePointIndex == initNextTimePointIndex ? false : true );
00367
00368 }
00369
00370
00371 #endif //Rythmos_INTERPOLATION_BUFFER_HELPERS_HPP