Reference documentation for deal.II version 8.4.2
polynomials_piecewise.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2014 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/polynomials_piecewise.h>
17 
18 
19 DEAL_II_NAMESPACE_OPEN
20 
21 
22 
23 namespace Polynomials
24 {
25 
26  template <typename number>
28  const unsigned int n_intervals,
29  const unsigned int interval,
30  const bool spans_next_interval)
31  :
32  polynomial (coefficients_on_interval),
33  n_intervals (n_intervals),
34  interval (interval),
35  spans_two_intervals (spans_next_interval)
36  {
37  Assert (n_intervals > 0, ExcMessage ("No intervals given"));
38  AssertIndexRange (interval, n_intervals);
39  }
40 
41 
42 
43  template <typename number>
44  void
46  std::vector<number> &values) const
47  {
48  Assert (values.size() > 0, ExcZero());
49  const unsigned int values_size=values.size();
50 
51  // shift polynomial if necessary
52  number y = x;
53  double derivative_change_sign = 1.;
54  if (n_intervals > 0)
55  {
56  const number step = 1./n_intervals;
57  // polynomial spans over two intervals
58  if (spans_two_intervals)
59  {
60  const double offset = step * interval;
61  if (x<offset || x>offset+step+step)
62  {
63  for (unsigned int k=0; k<values.size(); ++k)
64  values[k] = 0;
65  return;
66  }
67  else if (x<offset+step)
68  y = x-offset;
69  else
70  {
71  derivative_change_sign = -1.;
72  y = offset+step+step-x;
73  }
74  }
75  else
76  {
77  const double offset = step * interval;
78  if (x<offset || x>offset+step)
79  {
80  for (unsigned int k=0; k<values.size(); ++k)
81  values[k] = 0;
82  return;
83  }
84  else
85  y = x-offset;
86  }
87 
88  // on subinterval boundaries, cannot evaluate derivatives properly, so
89  // set them to zero
90  if ((std::abs(y)<1e-14 && (interval > 0 ||
91  derivative_change_sign == -1.))
92  ||
93  (std::abs(y-step)<1e-14 &&
94  (interval < n_intervals-1 || derivative_change_sign == -1.)))
95  {
96  values[0] = value(x);
97  for (unsigned int d=1; d<values_size; ++d)
98  values[d] = 0;
99  return;
100  }
101  }
102 
103  polynomial.value(y, values);
104 
105  // change sign if necessary
106  for (unsigned int j=1; j<values_size; j+=2)
107  values[j] *= derivative_change_sign;
108  }
109 
110 
111 
112  std::vector<PiecewisePolynomial<double> >
113  generate_complete_Lagrange_basis_on_subdivisions (const unsigned int n_subdivisions,
114  const unsigned int base_degree)
115  {
116  std::vector<Polynomial<double> > p_base =
117  LagrangeEquidistant::generate_complete_basis(base_degree);
118  for (unsigned int i=0; i<p_base.size(); ++i)
119  p_base[i].scale(n_subdivisions);
120 
121  std::vector<PiecewisePolynomial<double> > p;
122  p.reserve (n_subdivisions * base_degree + 1);
123 
124  p.push_back (PiecewisePolynomial<double> (p_base[0], n_subdivisions, 0,
125  false));
126  for (unsigned int s=0; s<n_subdivisions; ++s)
127  for (unsigned int i=0; i<base_degree; ++i)
128  p.push_back (PiecewisePolynomial<double> (p_base[i+1], n_subdivisions,
129  s,
130  i==(base_degree-1) &&
131  s<n_subdivisions-1));
132  return p;
133  }
134 
135 }
136 
137 // ------------------ explicit instantiations --------------- //
138 
139 namespace Polynomials
140 {
141  template class PiecewisePolynomial<float>;
142  template class PiecewisePolynomial<double>;
143  template class PiecewisePolynomial<long double>;
144 }
145 
146 DEAL_II_NAMESPACE_CLOSE
::ExceptionBase & ExcMessage(std::string arg1)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1081
#define Assert(cond, exc)
Definition: exceptions.h:294
std::vector< PiecewisePolynomial< double > > generate_complete_Lagrange_basis_on_subdivisions(const unsigned int n_subdivisions, const unsigned int base_degree)
PiecewisePolynomial(const Polynomial< number > &coefficients_on_interval, const unsigned int n_intervals, const unsigned int interval, const bool spans_next_interval)
void value(const number x, std::vector< number > &values) const