Rythmos_LinearInterpolator.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_LINEAR_INTERPOLATOR_H
00030 #define Rythmos_LINEAR_INTERPOLATOR_H
00031 
00032 #include "Rythmos_InterpolatorBase.hpp"
00033 #include "Thyra_VectorStdOps.hpp"
00034 
00035 
00036 namespace Rythmos {
00037 
00038 
00042 template<class Scalar>
00043 class LinearInterpolator : virtual public InterpolatorBase<Scalar>
00044 {
00045 public:
00046 
00048   ~LinearInterpolator() {};
00049 
00051   LinearInterpolator();
00052 
00054   bool supportsCloning() const;
00055 
00057   RCP<InterpolatorBase<Scalar> > cloneInterpolator() const;
00058 
00060   void interpolate(
00061     const typename DataStore<Scalar>::DataStoreVector_t &data_in,
00062     const Array<Scalar> &t_values,
00063     typename DataStore<Scalar>::DataStoreVector_t *data_out
00064     ) const;
00065 
00067   int order() const; 
00068 
00070   std::string description() const;
00071 
00073   void describe(
00074     FancyOStream &out,
00075     const Teuchos::EVerbosityLevel verbLevel
00076     ) const;
00077 
00079   void setParameterList(RCP<ParameterList> const& paramList);
00080 
00082   RCP<ParameterList> getNonconstParameterList();
00083 
00085   RCP<ParameterList> unsetParameterList();
00086 
00087 private:
00088 
00089   RCP<ParameterList> parameterList_;
00090 
00091 };
00092 
00093 
00094 template<class Scalar>
00095 LinearInterpolator<Scalar>::LinearInterpolator()
00096 {}
00097 
00098 
00099 template<class Scalar>
00100 bool LinearInterpolator<Scalar>::supportsCloning() const
00101 {
00102   return true;
00103 }
00104 
00105 
00106 template<class Scalar>
00107 RCP<InterpolatorBase<Scalar> >
00108 LinearInterpolator<Scalar>::cloneInterpolator() const
00109 {
00110   RCP<LinearInterpolator<Scalar> >
00111     interpolator = Teuchos::rcp(new LinearInterpolator<Scalar>);
00112   if (!is_null(parameterList_))
00113     interpolator->parameterList_ = parameterList(*parameterList_);
00114   return interpolator;
00115 }
00116 
00117 
00118 template<class Scalar>
00119 void LinearInterpolator<Scalar>::interpolate(
00120   const typename DataStore<Scalar>::DataStoreVector_t &data_in,
00121   const Array<Scalar> &t_values,
00122   typename DataStore<Scalar>::DataStoreVector_t *data_out
00123   ) const
00124 {
00125 
00126   using Teuchos::as;
00127   typedef Teuchos::ScalarTraits<Scalar> ST;
00128 
00129 #ifdef TEUCHOS_DEBUG
00130   assertBaseInterpolatePreconditions(data_in,t_values,data_out);
00131 #endif // TEUCHOS_DEBUG
00132   
00133   // Output info
00134   const RCP<FancyOStream> out = this->getOStream();
00135   const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); 
00136   Teuchos::OSTab ostab(out,1,"LI::interpolator");
00137   if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00138     *out << "data_in:" << std::endl;
00139     for (unsigned int i=0 ; i<data_in.size() ; ++i) {
00140       *out << "data_in[" << i << "] = " << std::endl;
00141       data_in[i].describe(*out,Teuchos::VERB_EXTREME);
00142     }
00143     *out << "t_values = " << std::endl;
00144     for (unsigned int i=0 ; i<t_values.size() ; ++i) {
00145       *out << "t_values[" << i << "] = " << t_values[i] << std::endl;
00146     }
00147   }
00148 
00149   data_out->clear();
00150 
00151   // Return immediatly if not time points are requested ...
00152   if (t_values.size() == 0) {
00153     return;
00154   }
00155 
00156   if (data_in.size() == 1) {
00157     // trivial case of one node.  Preconditions assert that t_values[0] ==
00158     // data_in[0].time so we can just pass it out
00159     DataStore<Scalar> DS(data_in[0]);
00160     data_out->push_back(DS);
00161   }
00162   else { // data_in.size() >= 2
00163     int n = 0; // index into t_values
00164     // Loop through all of the time interpolation points in the buffer and
00165     // satisfiy all of the requested time points that you find.  NOTE: The
00166     // loop will be existed once all of the time points are satisified (see
00167     // return below).
00168     for (int i=0 ; i < as<int>(data_in.size())-1; ++i) {
00169       const Scalar& ti = data_in[i].time;
00170       const Scalar& tip1 = data_in[i+1].time;
00171       const Scalar  h = tip1-ti;
00172       const TimeRange<Scalar> range_i(ti,tip1);
00173       // For the interploation range of [ti,tip1], satisify all of the
00174       // requested points in this range.
00175       while ( range_i.isInRange(t_values[n]) ) {
00176         // First we check for exact node matches:
00177         if (compareTimeValues(t_values[n],ti)==0) {
00178           DataStore<Scalar> DS(data_in[i]);
00179           data_out->push_back(DS);
00180         }
00181         else if (compareTimeValues(t_values[n],tip1)==0) {
00182           DataStore<Scalar> DS(data_in[i+1]);
00183           data_out->push_back(DS);
00184         }
00185         else {
00186           // interpolate this point
00187           //
00188           // x(t) = (t-ti)/(tip1-ti) * xip1 + (1-(t-ti)/(tip1-ti)) * xi
00189           //
00190           // Above, it is easy to see that:
00191           //
00192           //    x(ti) = xi
00193           //    x(tip1) = xip1
00194           //
00195           DataStore<Scalar> DS;
00196           const Scalar& t = t_values[n];
00197           DS.time = t;
00198           // Get the time and interpolation node points
00199           RCP<const Thyra::VectorBase<Scalar> > xi = data_in[i].x;
00200           RCP<const Thyra::VectorBase<Scalar> > xip1 = data_in[i+1].x;
00201           RCP<const Thyra::VectorBase<Scalar> > xdoti = data_in[i].xdot;
00202           RCP<const Thyra::VectorBase<Scalar> > xdotip1 = data_in[i+1].xdot;
00203           // Get constants used in interplation
00204           const Scalar dt = t-ti;
00205           const Scalar dt_over_h = dt / h;
00206           const Scalar one_minus_dt_over_h = ST::one() - dt_over_h;
00207           // x = dt/h * xip1 + (1-dt/h) * xi
00208           RCP<Thyra::VectorBase<Scalar> > x = createMember(xi->space());
00209           Thyra::V_StVpStV(&*x,dt_over_h,*xip1,one_minus_dt_over_h,*xi);
00210           DS.x = x;
00211           // x = dt/h * xdotip1 + (1-dt/h) * xdoti
00212           RCP<Thyra::VectorBase<Scalar> > xdot;
00213           if ((xdoti != Teuchos::null) && (xdotip1 != Teuchos::null)) {
00214             xdot = createMember(xdoti->space());
00215             Thyra::V_StVpStV(&*xdot,dt_over_h,*xdotip1,one_minus_dt_over_h,*xdoti);
00216           }
00217           DS.xdot = xdot;
00218           // Estimate our accuracy ???
00219           DS.accuracy = h;
00220           // 2007/12/06: rabartl: Above, should the be a relative value of
00221           // some type.  What does this really mean?
00222           // Store this interplation
00223           data_out->push_back(DS);
00224         }
00225         // Move to the next user time point to consider!
00226         n++;
00227         if (n == as<int>(t_values.size())) {
00228           // WE ARE ALL DONE!  MOVE OUT!
00229           return;
00230         }
00231       }
00232       // Move on the the next interpolation time range
00233     }
00234   } // data_in.size() == 1
00235 }
00236 
00237 
00238 template<class Scalar>
00239 int LinearInterpolator<Scalar>::order() const
00240 {
00241   return(1);
00242 }
00243 
00244 
00245 template<class Scalar>
00246 std::string LinearInterpolator<Scalar>::description() const
00247 {
00248   std::string name = "Rythmos::LinearInterpolator";
00249   return(name);
00250 }
00251 
00252 
00253 template<class Scalar>
00254 void LinearInterpolator<Scalar>::describe(
00255   FancyOStream &out,
00256   const Teuchos::EVerbosityLevel verbLevel
00257   ) const
00258 {
00259   using Teuchos::as;
00260   if ( (as<int>(verbLevel) == as<int>(Teuchos::VERB_DEFAULT) ) ||
00261        (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW)     )
00262      )
00263   {
00264     out << description() << "::describe" << std::endl;
00265   }
00266   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_LOW))
00267   {}
00268   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_MEDIUM))
00269   {}
00270   else if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH))
00271   {}
00272 }
00273 
00274 
00275 template <class Scalar>
00276 void LinearInterpolator<Scalar>::setParameterList(
00277   RCP<ParameterList> const& paramList
00278   )
00279 {
00280   // 2007/12/06: rabartl: ToDo: Validate this parameter list!
00281   parameterList_ = paramList;
00282   int outputLevel = parameterList_->get( "outputLevel", int(-1) );
00283   outputLevel = std::min(std::max(outputLevel,-1),4);
00284   this->setVerbLevel(static_cast<Teuchos::EVerbosityLevel>(outputLevel));
00285   // 2007/05/18: rabartl: ToDo: Replace with standard "Verbose Object"
00286   // sublist! and validate the sublist!
00287 
00288 }
00289 
00290 
00291 template <class Scalar>
00292 RCP<ParameterList>
00293 LinearInterpolator<Scalar>::getNonconstParameterList()
00294 {
00295   return(parameterList_);
00296 }
00297 
00298 
00299 template <class Scalar>
00300 RCP<ParameterList>
00301 LinearInterpolator<Scalar>::unsetParameterList()
00302 {
00303   RCP<ParameterList> temp_param_list;
00304   std::swap( temp_param_list, parameterList_ );
00305   return(temp_param_list);
00306 }
00307 
00308 
00309 } // namespace Rythmos
00310 
00311 
00312 #endif // Rythmos_LINEAR_INTERPOLATOR_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