Reference documentation for deal.II version 9.1.0-pre
fe_series.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2016 - 2017 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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_fe_series_H
17 #define dealii_fe_series_H
18 
19 
20 
21 #include <deal.II/base/config.h>
22 
23 #include <deal.II/base/exceptions.h>
24 #include <deal.II/base/subscriptor.h>
25 #include <deal.II/base/table.h>
26 #include <deal.II/base/table_indices.h>
27 #include <deal.II/base/tensor.h>
28 
29 #include <deal.II/hp/fe_collection.h>
30 #include <deal.II/hp/q_collection.h>
31 
32 #include <deal.II/lac/full_matrix.h>
33 #include <deal.II/lac/vector.h>
34 
35 #include <deal.II/numerics/vector_tools.h>
36 
37 #include <memory>
38 #include <string>
39 #include <vector>
40 
41 
42 DEAL_II_NAMESPACE_OPEN
43 
44 
47 
48 
57 namespace FESeries
58 {
90  template <int dim>
91  class Fourier : public Subscriptor
92  {
93  public:
101  Fourier(const unsigned int size_in_each_direction,
104 
110  void
111  calculate(const ::Vector<double> & local_dof_values,
112  const unsigned int cell_active_fe_index,
113  Table<dim, std::complex<double>> &fourier_coefficients);
114 
115  private:
120 
125 
130  void
131  ensure_existence(const unsigned int fe_index);
132 
137 
141  std::vector<FullMatrix<std::complex<double>>> fourier_transform_matrices;
142 
146  std::vector<std::complex<double>> unrolled_coefficients;
147  };
148 
192  template <int dim>
193  class Legendre : public Subscriptor
194  {
195  public:
203  Legendre(const unsigned int size_in_each_direction,
206 
212  void
213  calculate(const ::Vector<double> &local_dof_values,
214  const unsigned int cell_active_fe_index,
215  Table<dim, double> & legendre_coefficients);
216 
217  private:
221  const unsigned int N;
222 
227 
232 
237  void
238  ensure_existence(const unsigned int fe_index);
239 
243  std::vector<FullMatrix<double>> legendre_transform_matrices;
244 
248  std::vector<double> unrolled_coefficients;
249  };
250 
251 
266  template <int dim, typename T>
267  std::pair<std::vector<unsigned int>, std::vector<double>>
268  process_coefficients(const Table<dim, T> & coefficients,
269  const std::function<std::pair<bool, unsigned int>(
270  const TableIndices<dim> &)> &predicate,
271  const VectorTools::NormType norm);
272 
273 
274 
280  std::pair<double, double>
281  linear_regression(const std::vector<double> &x, const std::vector<double> &y);
282 
283 } // namespace FESeries
284 
287 #ifndef DOXYGEN
288 
289 // ------------------- inline and template functions ----------------
290 
291 namespace internal
292 {
293  namespace FESeriesImplementation
294  {
295  template <int dim, typename T>
296  void
297  fill_map_index(const Table<dim, T> & coefficients,
298  const TableIndices<dim> & ind,
299  const std::function<std::pair<bool, unsigned int>(
300  const TableIndices<dim> &)> & predicate,
301  std::map<unsigned int, std::vector<T>> &pred_to_values)
302  {
303  const std::pair<bool, unsigned int> pred_pair = predicate(ind);
304  // don't add a value if predicate is false
305  if (pred_pair.first == false)
306  return;
307 
308  const unsigned int &pred_value = pred_pair.second;
309  const T & coeff_value = coefficients(ind);
310  // If pred_value is not in the pred_to_values map, the element will be
311  // created. Otherwise a reference to the existing element is returned.
312  pred_to_values[pred_value].push_back(coeff_value);
313  }
314 
315  template <typename T>
316  void
317  fill_map(const Table<1, T> & coefficients,
318  const std::function<std::pair<bool, unsigned int>(
319  const TableIndices<1> &)> & predicate,
320  std::map<unsigned int, std::vector<T>> &pred_to_values)
321  {
322  for (unsigned int i = 0; i < coefficients.size(0); i++)
323  {
324  const TableIndices<1> ind(i);
325  fill_map_index(coefficients, ind, predicate, pred_to_values);
326  }
327  }
328 
329  template <typename T>
330  void
331  fill_map(const Table<2, T> & coefficients,
332  const std::function<std::pair<bool, unsigned int>(
333  const TableIndices<2> &)> & predicate,
334  std::map<unsigned int, std::vector<T>> &pred_to_values)
335  {
336  for (unsigned int i = 0; i < coefficients.size(0); i++)
337  for (unsigned int j = 0; j < coefficients.size(1); j++)
338  {
339  const TableIndices<2> ind(i, j);
340  fill_map_index(coefficients, ind, predicate, pred_to_values);
341  }
342  }
343 
344  template <typename T>
345  void
346  fill_map(const Table<3, T> & coefficients,
347  const std::function<std::pair<bool, unsigned int>(
348  const TableIndices<3> &)> & predicate,
349  std::map<unsigned int, std::vector<T>> &pred_to_values)
350  {
351  for (unsigned int i = 0; i < coefficients.size(0); i++)
352  for (unsigned int j = 0; j < coefficients.size(1); j++)
353  for (unsigned int k = 0; k < coefficients.size(2); k++)
354  {
355  const TableIndices<3> ind(i, j, k);
356  fill_map_index(coefficients, ind, predicate, pred_to_values);
357  }
358  }
359 
360 
361  template <typename T>
362  double
363  complex_mean_value(const T &value)
364  {
365  return value;
366  }
367 
368  template <typename T>
369  double
370  complex_mean_value(const std::complex<T> &value)
371  {
372  AssertThrow(false,
373  ExcMessage(
374  "FESeries::process_coefficients() can not be used with"
375  "complex-valued coefficients and VectorTools::mean norm."));
376  return std::abs(value);
377  }
378  } // namespace FESeriesImplementation
379 } // namespace internal
380 
381 
382 template <int dim, typename T>
383 std::pair<std::vector<unsigned int>, std::vector<double>>
385  const Table<dim, T> &coefficients,
386  const std::function<std::pair<bool, unsigned int>(const TableIndices<dim> &)>
387  & predicate,
388  const VectorTools::NormType norm)
389 {
390  std::vector<unsigned int> predicate_values;
391  std::vector<double> norm_values;
392 
393  // first, parse all table elements into a map of predicate values and
394  // coefficients. We could have stored (predicate values ->TableIndicies) map,
395  // but its processing would have been much harder later on.
396  std::map<unsigned int, std::vector<T>> pred_to_values;
397  internal::FESeriesImplementation::fill_map(coefficients,
398  predicate,
399  pred_to_values);
400 
401  // now go through the map and populate the @p norm_values based on @p norm:
402  for (typename std::map<unsigned int, std::vector<T>>::const_iterator it =
403  pred_to_values.begin();
404  it != pred_to_values.end();
405  ++it)
406  {
407  predicate_values.push_back(it->first);
408  Vector<T> values(it->second.begin(), it->second.end());
409 
410  switch (norm)
411  {
413  {
414  norm_values.push_back(values.l2_norm());
415  break;
416  }
418  {
419  norm_values.push_back(values.l1_norm());
420  break;
421  }
423  {
424  norm_values.push_back(values.linfty_norm());
425  break;
426  }
427  case VectorTools::mean:
428  {
429  norm_values.push_back(
430  internal::FESeriesImplementation::complex_mean_value(
431  values.mean_value()));
432  break;
433  }
434  default:
435  AssertThrow(false, ExcNotImplemented());
436  break;
437  }
438  }
439 
440  return std::make_pair(predicate_values, norm_values);
441 }
442 
443 
444 #endif // DOXYGEN
445 
446 DEAL_II_NAMESPACE_CLOSE
447 
448 #endif // dealii_fe_series_H
Table< dim, Tensor< 1, dim > > k_vectors
Definition: fe_series.h:136
void calculate(const ::Vector< double > &local_dof_values, const unsigned int cell_active_fe_index, Table< dim, std::complex< double >> &fourier_coefficients)
Definition: fe_series.cc:83
SmartPointer< const hp::FECollection< dim > > fe_collection
Definition: fe_series.h:119
std::pair< double, double > linear_regression(const std::vector< double > &x, const std::vector< double > &y)
Definition: fe_series.cc:373
SmartPointer< const hp::QCollection< dim > > q_collection
Definition: fe_series.h:124
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
Fourier(const unsigned int size_in_each_direction, const hp::FECollection< dim > &fe_collection, const hp::QCollection< dim > &q_collection)
Definition: fe_series.cc:70
std::pair< std::vector< unsigned int >, std::vector< double > > process_coefficients(const Table< dim, T > &coefficients, const std::function< std::pair< bool, unsigned int >(const TableIndices< dim > &)> &predicate, const VectorTools::NormType norm)
std::vector< std::complex< double > > unrolled_coefficients
Definition: fe_series.h:146
SmartPointer< const hp::QCollection< dim > > q_collection
Definition: fe_series.h:231
static::ExceptionBase & ExcMessage(std::string arg1)
size_type size(const unsigned int i) const
SmartPointer< const hp::FECollection< dim > > fe_collection
Definition: fe_series.h:226
void ensure_existence(const unsigned int fe_index)
std::vector< double > unrolled_coefficients
Definition: fe_series.h:248
const unsigned int N
Definition: fe_series.h:221
static::ExceptionBase & ExcNotImplemented()
Definition: table.h:37
std::vector< FullMatrix< std::complex< double > > > fourier_transform_matrices
Definition: fe_series.h:141
std::vector< FullMatrix< double > > legendre_transform_matrices
Definition: fe_series.h:243