Tempus  Version of the Day
Time Integration
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Tempus_InterpolatorLagrange_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ****************************************************************************
3 // Tempus: Copyright (2017) Sandia Corporation
4 //
5 // Distributed under BSD 3-clause license (See accompanying file Copyright.txt)
6 // ****************************************************************************
7 // @HEADER
8 
9 #ifndef Tempus_InterpolatorLagrange_impl_hpp
10 #define Tempus_InterpolatorLagrange_impl_hpp
11 
12 #include <algorithm>
13 #include <iterator>
14 
15 #include "Teuchos_ScalarTraits.hpp"
16 #include "Thyra_VectorStdOps.hpp"
17 
18 namespace Tempus {
19 
20 template <class Scalar>
22  const Scalar& t, SolutionState<Scalar>* state_out) const
23 {
24  int n = (*nodes_).size();
25  TEUCHOS_ASSERT(n > 0);
26  if (n >= order_ + 1)
27  lagrange(order_, t, state_out);
28  else
29  lagrange(n - 1, t, state_out);
30 }
31 
32 template <class Scalar>
34  const Teuchos::RCP<Teuchos::ParameterList>& paramList)
35 {
36  pl_ = Teuchos::parameterList();
37  if (paramList == Teuchos::null)
38  *pl_ = *(this->getValidParameters());
39  else
40  *pl_ = *paramList;
41  pl_->validateParametersAndSetDefaults(*this->getValidParameters());
42  order_ = pl_->get<int>("Order");
43 }
44 
45 template <class Scalar>
48 {
49  return pl_;
50 }
51 
52 template <class Scalar>
55 {
57  pl_ = Teuchos::null;
58  return tmp;
59 }
60 
61 template <class Scalar>
64 {
65  Teuchos::RCP<Teuchos::ParameterList> tmp = Teuchos::parameterList();
66  tmp->set<std::string>("Interpolator Type", "Lagrange");
67  tmp->set<int>("Order", 0);
68  return tmp;
69 }
70 
71 template <class Scalar>
73  const int p, const Scalar& t, SolutionState<Scalar>* state_out) const
74 {
75  using Teuchos::is_null;
76  using Teuchos::RCP;
77  using Thyra::V_StVpStV;
78  using Thyra::VectorBase;
79 
80  // Here we assume we have at least p nodes
81  int n = nodes_->size();
82  TEUCHOS_ASSERT(n >= p);
83 
84  const Scalar t_begin = (*nodes_)[0]->getTime();
85  const Scalar t_final = (*nodes_)[n - 1]->getTime();
86 
87  // Find largest index i such that
88  // (*nodes)[i]->getTime() <= t
89  int i;
90  if (t <= t_begin)
91  i = 0;
92  else if (t >= t_final)
93  i = n - 1;
94  else {
95  auto it = std::find_if(nodes_->begin(), nodes_->end(),
96  [=](const RCP<SolutionState<Scalar> >& s) {
97  return t <= s->getTime();
98  });
99  i = std::distance(nodes_->begin(), it) - 1;
100  }
101  TEUCHOS_ASSERT(i >= 0 && i <= n - 1);
102 
103  // First we check for exact node matches:
104  if (floating_compare_equals((*nodes_)[i]->getTime(), t, t_final)) {
105  state_out->copy((*nodes_)[i]);
106  return;
107  }
108  if (i < n - 1 &&
109  floating_compare_equals((*nodes_)[i + 1]->getTime(), t, t_final)) {
110  state_out->copy((*nodes_)[i + 1]);
111  return;
112  }
113 
114  // Put t roughly in the middle of the interpolation window
115  int k = i - p / 2;
116  if (k < 0) k = 0;
117  if (k + p + 1 > n) k = n - p - 1;
118  TEUCHOS_ASSERT(k >= 0 && k + p + 1 <= n);
119 
120  RCP<VectorBase<Scalar> > x = state_out->getX();
121  RCP<VectorBase<Scalar> > xdot = state_out->getXDot();
122  RCP<VectorBase<Scalar> > xdotdot = state_out->getXDotDot();
123 
124  Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
125  Thyra::assign(x.ptr(), zero);
126  if (!is_null(xdot)) Thyra::assign(xdot.ptr(), zero);
127  if (!is_null(xdotdot)) Thyra::assign(xdotdot.ptr(), zero);
128 
129  for (int j = 0; j <= p; ++j) {
130  const Scalar tj = (*nodes_)[k + j]->getTime();
131  RCP<const VectorBase<Scalar> > xj = (*nodes_)[k + j]->getX();
132  RCP<const VectorBase<Scalar> > xdotj = (*nodes_)[k + j]->getXDot();
133  RCP<const VectorBase<Scalar> > xdotdotj = (*nodes_)[k + j]->getXDotDot();
134 
135  Scalar num = 1.0;
136  Scalar den = 1.0;
137  for (int l = 0; l <= p; ++l) {
138  if (l != j) {
139  const Scalar tl = (*nodes_)[k + l]->getTime();
140  num *= t - tl;
141  den *= tj - tl;
142  }
143  }
144  const Scalar a = num / den;
145  Thyra::Vp_StV(x.ptr(), a, *xj);
146  if (!is_null(xdot)) Thyra::Vp_StV(xdot.ptr(), a, *xdotj);
147  if (!is_null(xdotdot)) Thyra::Vp_StV(xdotdot.ptr(), a, *xdotdotj);
148  }
149 
150  // Set meta-data for interpolated state
151  state_out->getMetaData()->copy((*nodes_)[i]->getMetaData());
152  state_out->getMetaData()->setTime(t);
153  state_out->getMetaData()->setDt(t - (*nodes_)[i]->getTime());
154  state_out->getMetaData()->setIsInterpolated(true);
155  // What else should we set??
156 }
157 
158 } // namespace Tempus
159 
160 #endif // Tempus_InterpolatorLagrange_impl_hpp
bool is_null(const boost::shared_ptr< T > &p)
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getXDot()
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
bool is_null(const std::shared_ptr< T > &p)
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getXDotDot()
void validateParametersAndSetDefaults(ParameterList const &validParamList, int const depth=1000)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
void lagrange(const int p, const Scalar &t, SolutionState< Scalar > *state_out) const
virtual Teuchos::RCP< const SolutionStateMetaData< Scalar > > getMetaData() const
bool floating_compare_equals(const Scalar &a, const Scalar &b, const Scalar &scale)
Helper function for comparing times.
void interpolate(const Scalar &t, SolutionState< Scalar > *state_out) const
Perform an interpolation.
#define TEUCHOS_ASSERT(assertion_test)
virtual Teuchos::RCP< Thyra::VectorBase< Scalar > > getX()
Solution state for integrators and steppers.
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
virtual void copy(const Teuchos::RCP< const SolutionState< Scalar > > &ss)
This is a deep copy.