Reference documentation for deal.II version 8.4.2
function_derivative.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/point.h>
17 #include <deal.II/base/function_derivative.h>
18 #include <deal.II/lac/vector.h>
19 
20 #include <cmath>
21 
22 DEAL_II_NAMESPACE_OPEN
23 
24 template <int dim>
26  const Point<dim> &dir,
27  const double h)
28  :
29  AutoDerivativeFunction<dim> (h, f.n_components, f.get_time()),
30  f(f),
31  h(h),
32  incr(1, h *dir)
33 {
34  set_formula();
35 }
36 
37 
38 
39 template <int dim>
41  const std::vector<Point<dim> > &dir,
42  const double h)
43  :
45  f(f),
46  h(h),
47  incr(dir.size())
48 {
49  for (unsigned int i=0; i<incr.size (); ++i)
50  incr[i] = h*dir[i];
51  set_formula();
52 }
53 
54 
55 
56 template <int dim>
57 void
59 {
60  formula = form;
61 }
62 
63 
64 
65 template <int dim>
66 void
67 FunctionDerivative<dim>::set_h (const double new_h)
68 {
69  for (unsigned int i=0; i<incr.size (); ++i)
70  incr[i] *= new_h/h;
71  h = new_h;
72 }
73 
74 
75 
76 template <int dim>
77 double
79  const unsigned int component) const
80 {
81  Assert (incr.size() == 1,
82  ExcMessage ("FunctionDerivative was not initialized for constant direction"));
83 
84  switch (formula)
85  {
87  return (f.value(p+incr[0], component)-f.value(p-incr[0], component))/(2*h);
89  return (f.value(p, component)-f.value(p-incr[0], component))/h;
91  return (-f.value(p+2*incr[0], component) + 8*f.value(p+incr[0], component)
92  -8*f.value(p-incr[0], component) + f.value(p-2*incr[0], component))/(12*h);
93  default:
94  Assert(false, ExcInvalidFormula());
95  }
96  return 0.;
97 }
98 
99 
100 
101 template <int dim>
102 void
104  const Point<dim> &p,
105  Vector<double> &result) const
106 {
107  Assert (incr.size() == 1,
108  ExcMessage ("FunctionDerivative was not initialized for constant direction"));
109  Vector<double> aux(result.size());
110 
111  // Formulas are the same as in
112  // value, but here we have to use
113  // Vector arithmetic
114  switch (formula)
115  {
117  f.vector_value(p+incr[0], result);
118  f.vector_value(p-incr[0], aux);
119  result.sadd(1./(2*h), -1./(2*h), aux);
120  return;
122  f.vector_value(p, result);
123  f.vector_value(p-incr[0], aux);
124  result.sadd(1./h, -1./h, aux);
125  return;
127  f.vector_value(p-2*incr[0], result);
128  f.vector_value(p+2*incr[0], aux);
129  result.add(-1., aux);
130  f.vector_value(p-incr[0], aux);
131  result.add(-8., aux);
132  f.vector_value(p+incr[0], aux);
133  result.add(8., aux);
134  result/=(12.*h);
135  return;
136  default:
137  Assert(false, ExcInvalidFormula());
138  }
139 }
140 
141 
142 
143 template <int dim>
144 void
145 FunctionDerivative<dim>::value_list (const std::vector<Point<dim> > &points,
146  std::vector<double> &values,
147  const unsigned int component) const
148 {
149  const unsigned int n = points.size();
150  const bool variable_direction = (incr.size() == 1) ? false : true;
151  if (variable_direction)
152  Assert (incr.size() == points.size(),
153  ExcDimensionMismatch(incr.size(), points.size()));
154 
155  // Vector of auxiliary values
156  std::vector<double> aux(n);
157  // Vector of auxiliary points
158  std::vector<Point<dim> > paux(n);
159  // Use the same formulas as in
160  // value, but with vector
161  // arithmetic
162  switch (formula)
163  {
165  for (unsigned int i=0; i<n; ++i)
166  paux[i] = points[i]+incr[(variable_direction) ? i : 0U];
167  f.value_list(paux, values, component);
168  for (unsigned int i=0; i<n; ++i)
169  paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
170  f.value_list(paux, aux, component);
171  for (unsigned int i=0; i<n; ++i)
172  values[i] = (values[i]-aux[i])/(2*h);
173  return;
175  f.value_list(points, values, component);
176  for (unsigned int i=0; i<n; ++i)
177  paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
178  f.value_list(paux, aux, component);
179  for (unsigned int i=0; i<n; ++i)
180  values[i] = (values[i]-aux[i])/h;
181  return;
183  for (unsigned int i=0; i<n; ++i)
184  paux[i] = points[i]-2*incr[(variable_direction) ? i : 0U];
185  f.value_list(paux, values, component);
186  for (unsigned int i=0; i<n; ++i)
187  paux[i] = points[i]+2*incr[(variable_direction) ? i : 0U];
188  f.value_list(paux, aux, component);
189  for (unsigned int i=0; i<n; ++i)
190  values[i] -= aux[i];
191  for (unsigned int i=0; i<n; ++i)
192  paux[i] = points[i]+incr[(variable_direction) ? i : 0U];
193  f.value_list(paux, aux, component);
194  for (unsigned int i=0; i<n; ++i)
195  values[i] += 8.*aux[i];
196  for (unsigned int i=0; i<n; ++i)
197  paux[i] = points[i]-incr[(variable_direction) ? i : 0U];
198  f.value_list(paux, aux, component);
199  for (unsigned int i=0; i<n; ++i)
200  values[i] = (values[i] - 8.*aux[i])/(12*h);
201  return;
202  default:
203  Assert(false, ExcInvalidFormula());
204  }
205 }
206 
207 
208 
209 template <int dim>
210 std::size_t
212 {
213  // only simple data elements, so
214  // use sizeof operator
215  return sizeof (*this);
216 }
217 
218 
219 
220 // explicit instantiations
221 template class FunctionDerivative<1>;
222 template class FunctionDerivative<2>;
223 template class FunctionDerivative<3>;
224 
225 DEAL_II_NAMESPACE_CLOSE
void sadd(const Number s, const Vector< Number > &V)
virtual double value(const Point< dim > &p, const unsigned int component=0) const
::ExceptionBase & ExcMessage(std::string arg1)
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< double > &values, const unsigned int component=0) const
void set_formula(typename AutoDerivativeFunction< dim >::DifferenceFormula formula=AutoDerivativeFunction< dim >::Euler)
const unsigned int n_components
Definition: function.h:144
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
#define Assert(cond, exc)
Definition: exceptions.h:294
std::size_t size() const
std::size_t memory_consumption() const
FunctionDerivative(const Function< dim > &f, const Point< dim > &direction, const double h=1.e-6)
const Function< dim > & f
AutoDerivativeFunction< dim >::DifferenceFormula formula
virtual Number value(const Point< dim > &p, const unsigned int component=0) const
virtual void vector_value(const Point< dim > &p, Vector< double > &value) const
virtual void value_list(const std::vector< Point< dim > > &points, std::vector< Number > &values, const unsigned int component=0) const
Number get_time() const
std::vector< Tensor< 1, dim > > incr
unsigned int n_components(const DoFHandler< dim, spacedim > &dh)
virtual void vector_value(const Point< dim > &p, Vector< Number > &values) const
void set_h(const double h)