Rythmos_HermiteInterpolator.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_HERMITE_INTERPOLATOR_H
00030 #define Rythmos_HERMITE_INTERPOLATOR_H
00031 
00032 #include "Rythmos_InterpolatorBase.hpp"
00033 
00034 namespace Rythmos {
00052 template<class Scalar>
00053 class HermiteInterpolator : virtual public InterpolatorBase<Scalar>
00054 {
00055   public:
00056 
00058     ~HermiteInterpolator() {};
00059 
00061     HermiteInterpolator();
00062 
00064 
00071     void interpolate(
00072       const typename DataStore<Scalar>::DataStoreVector_t &data_in,
00073       const Array<Scalar> &t_values,
00074       typename DataStore<Scalar>::DataStoreVector_t *data_out
00075       ) const;
00076 
00078     int order() const; 
00079 
00081 
00082     std::string description() const;
00083 
00085     void describe(
00086       Teuchos::FancyOStream &out,
00087       const Teuchos::EVerbosityLevel verbLevel
00088       ) const;
00089 
00091 
00092     void setParameterList(RCP<ParameterList> const& paramList);
00093 
00095     RCP<ParameterList> getNonconstParameterList();
00096 
00098     RCP<ParameterList> unsetParameterList();
00099 
00100     void assertInterpolatePreconditions(
00101         const typename DataStore<Scalar>::DataStoreVector_t &data_in
00102         ,const Array<Scalar> &t_values
00103         ,typename DataStore<Scalar>::DataStoreVector_t *data_out
00104         ) const;
00105 
00106   private:
00107 
00108     RCP<ParameterList> parameterList;
00109 
00110 };
00111 
00112 template<class Scalar>
00113 HermiteInterpolator<Scalar>::HermiteInterpolator()
00114 {
00115 }
00116 
00117 template<class Scalar>
00118 void HermiteInterpolator<Scalar>::interpolate(
00119     const typename DataStore<Scalar>::DataStoreVector_t &data_in
00120     ,const Array<Scalar> &t_values
00121     ,typename DataStore<Scalar>::DataStoreVector_t *data_out ) const
00122 {
00123 
00124   TEST_FOR_EXCEPT_MSG(true, "Error, ths function is not tested!" );
00125 
00126   typedef Teuchos::ScalarTraits<Scalar> ST;
00127 #ifdef TEUCHOS_DEBUG
00128   assertInterpolatePreconditions(data_in,t_values,data_out);
00129 #endif // TEUCHOS_DEBUG
00130   RCP<Teuchos::FancyOStream> out = this->getOStream();
00131   Teuchos::OSTab ostab(out,1,"HI::interpolator");
00132   if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) {
00133     *out << "data_in:" << std::endl;
00134     for (unsigned int i=0 ; i<data_in.size() ; ++i) {
00135       *out << "data_in[" << i << "] = " << std::endl;
00136       data_in[i].describe(*out,Teuchos::VERB_EXTREME);
00137     }
00138     *out << "t_values = " << std::endl;
00139     for (unsigned int i=0 ; i<t_values.size() ; ++i) {
00140       *out << "t_values[" << i << "] = " << t_values[i] << std::endl;
00141     }
00142     for (unsigned int i=0; i<data_out->size() ; ++i) {
00143       *out << "data_out[" << i << "] = " << std::endl;
00144       (*data_out)[i].describe(*out,Teuchos::VERB_EXTREME);
00145     }
00146   }
00147   data_out->clear();
00148   if (t_values.size() == 0) {
00149     return;
00150   }
00151   
00152   if (data_in.size() == 1) {
00153     // trivial case of one node
00154     // preconditions assert that t_values[0] == data_in[0].time so we can just pass it out
00155     DataStore<Scalar> DS(data_in[0]);
00156     data_out->push_back(DS);
00157   } else {
00158     // data_in.size() >= 2
00159     int n = 0;
00160     for (int i=0 ; i<Teuchos::as<int>(data_in.size())-1 ; ++i) {
00161       const Scalar& ti = data_in[i].time;
00162       const Scalar& tip1 = data_in[i+1].time;
00163       while ((ti <= t_values[n]) && (t_values[n] <= tip1)) {
00164         const Scalar& t = t_values[n];
00165         // First we check for exact node matches:
00166         if (t == ti) {
00167           DataStore<Scalar> DS(data_in[i]);
00168           data_out->push_back(DS);
00169         } else if (t == tip1) {
00170           DataStore<Scalar> DS(data_in[i+1]);
00171           data_out->push_back(DS);
00172         } else {
00173           RCP<const Thyra::VectorBase<Scalar> > xi =      data_in[i  ].x;
00174           RCP<const Thyra::VectorBase<Scalar> > xip1 =    data_in[i+1].x;
00175           RCP<const Thyra::VectorBase<Scalar> > xdoti =   data_in[i  ].xdot;
00176           RCP<const Thyra::VectorBase<Scalar> > xdotip1 = data_in[i+1].xdot;
00177           
00178           // 10/10/06 tscoffe:  this could be expensive:
00179           RCP<Thyra::VectorBase<Scalar> > tmp_vec = xi->clone_v(); 
00180           RCP<Thyra::VectorBase<Scalar> > xdot_temp = xip1->clone_v(); 
00181           Scalar dt = tip1-ti;
00182           Scalar dt2 = dt*dt;
00183           Scalar t_t0 = t - ti;
00184           Scalar t_t1 = t - tip1;
00185           Scalar tmp_t;
00186 
00187           // Compute numerical divided difference:
00188           Thyra::Vt_S(&*xdot_temp,Scalar(ST::one()/dt));
00189           Thyra::Vp_StV(&*xdot_temp,Scalar(-ST::one()/dt),*xi);
00190 
00191           // interpolate this point
00192           DataStore<Scalar> DS;
00193           DS.time = t;
00194 
00195           //  H_3(x) = f(x0) + f'(x0)(x-x0) + ((f(x1)-f(x0))/(x1-x0) - f'(x0))(x-x0)^2/(x1-x0)
00196           //           +(f'(x1) - 2(f(x1)-f(x0))/(x1-x0) + f'(x0))(x-x0)^2(x-x1)/(x1-x0)^2
00197           RCP<Thyra::VectorBase<Scalar> > x_vec = xi->clone_v(); 
00198           Thyra::Vp_StV(&*x_vec,t_t0,*xdoti);
00199           tmp_t = t_t0*t_t0/dt;
00200           Thyra::V_StVpStV(&*tmp_vec,tmp_t,*xdot_temp,Scalar(-ST::one()*tmp_t),*xdoti);
00201           Thyra::Vp_V(&*x_vec,*tmp_vec);
00202           tmp_t = t_t0*t_t0*t_t1/dt2;
00203           Thyra::V_StVpStV(&*tmp_vec,tmp_t,*xdotip1,Scalar(-2*tmp_t),*xdot_temp);
00204           Thyra::Vp_StV(&*tmp_vec,tmp_t,*xdoti);
00205           Thyra::Vp_V(&*x_vec,*tmp_vec);
00206           DS.x = x_vec;
00207 
00208           //  H_3'(x) =        f'(x0) + 2*((f(x1)-f(x0))/(x1-x0) - f'(x0))(x-x0)/(x1-x0)
00209           //           +(f'(x1) - 2(f(x1)-f(x0))/(x1-x0) + f'(x0))[2*(x-x0)(x-x1) + (x-x0)^2]/(x1-x0)^2
00210           RCP<Thyra::VectorBase<Scalar> > xdot_vec = xdoti->clone_v(); 
00211           tmp_t = t_t0/dt;
00212           Thyra::Vp_StV(&*xdot_vec,Scalar(2*tmp_t),*xdot_temp);
00213           Thyra::Vp_StV(&*xdot_vec,Scalar(-ST::one()*tmp_t),*xdoti);
00214           tmp_t = Scalar((2*t_t0*t_t1+t_t0*t_t0)/dt2);
00215           Thyra::V_StVpStV(&*tmp_vec,tmp_t,*xdotip1,Scalar(-2*tmp_t),*xdot_temp);
00216           Thyra::Vp_StV(&*tmp_vec,tmp_t,*xdoti);
00217           Thyra::Vp_V(&*xdot_vec,*tmp_vec);
00218           DS.xdot = xdot_vec;
00219           
00220           // Accuracy:
00221           // f(x) - H_3(x) = (f^{(3)}(\xi(x))/(4!))(x-x0)^2(x-x1)^2
00222           DS.accuracy = (t_t0)*(t_t0)*(t_t1)*(t_t1);
00223 
00224           // Push DataStore object onto vector:
00225           data_out->push_back(DS);
00226         }
00227         n++;
00228         if (n == Teuchos::as<int>(t_values.size())) {
00229           return;
00230         }
00231       }
00232     }
00233   } // data_in.size() == 1
00234 }
00235 
00236 template<class Scalar>
00237 int HermiteInterpolator<Scalar>::order() const
00238 {
00239   return(2);
00240 }
00241 
00242 template<class Scalar>
00243 std::string HermiteInterpolator<Scalar>::description() const
00244 {
00245   std::string name = "Rythmos::HermiteInterpolator";
00246   return(name);
00247 }
00248 
00249 template<class Scalar>
00250 void HermiteInterpolator<Scalar>::describe(
00251       Teuchos::FancyOStream       &out
00252       ,const Teuchos::EVerbosityLevel      verbLevel
00253       ) const
00254 {
00255   if ( (Teuchos::as<int>(verbLevel) == Teuchos::as<int>(Teuchos::VERB_DEFAULT) ) ||
00256        (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW)     )
00257      )
00258   {
00259     out << description() << "::describe" << std::endl;
00260   }
00261   else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_LOW))
00262   {}
00263   else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_MEDIUM))
00264   {}
00265   else if (Teuchos::as<int>(verbLevel) >= Teuchos::as<int>(Teuchos::VERB_HIGH))
00266   {}
00267 }
00268 
00269 template <class Scalar>
00270 void HermiteInterpolator<Scalar>::setParameterList(RCP<ParameterList> const& paramList)
00271 {
00272   parameterList = paramList;
00273   int outputLevel = parameterList->get( "outputLevel", int(-1) );
00274   outputLevel = std::min(std::max(outputLevel,-1),4);
00275   this->setVerbLevel(static_cast<Teuchos::EVerbosityLevel>(outputLevel));
00276 }
00277 
00278 template <class Scalar>
00279 RCP<ParameterList> HermiteInterpolator<Scalar>::getNonconstParameterList()
00280 {
00281   return(parameterList);
00282 }
00283 
00284 template <class Scalar>
00285 RCP<ParameterList> HermiteInterpolator<Scalar>::unsetParameterList()
00286 {
00287   RCP<ParameterList> temp_param_list = parameterList;
00288   parameterList = Teuchos::null;
00289   return(temp_param_list);
00290 }
00291 
00292 template<class Scalar>
00293 void HermiteInterpolator<Scalar>::assertInterpolatePreconditions(
00294         const typename DataStore<Scalar>::DataStoreVector_t &data_in
00295         ,const Array<Scalar> &t_values
00296         ,typename DataStore<Scalar>::DataStoreVector_t *data_out
00297         ) const
00298 {
00299   assertBaseInterpolatePreconditions(data_in,t_values,data_out);
00300   for (int i=0; i<Teuchos::as<int>(data_in.size()) ; ++i) {
00301     TEST_FOR_EXCEPTION(
00302         data_in[i].xdot == Teuchos::null, std::logic_error,
00303         "Error, data_in[" << i << "].xdot == Teuchos::null.\n"
00304         );
00305   }
00306 }
00307 
00308 } // namespace Rythmos
00309 
00310 #endif // Rythmos_HERMITE_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