ASPECT
compat.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2015 - 2024 by the authors of the ASPECT code.
3 
4  This file is part of ASPECT.
5 
6  ASPECT is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)
9  any later version.
10 
11  ASPECT is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with ASPECT; see the file LICENSE. If not see
18  <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef _aspect_compat_h
22 #define _aspect_compat_h
23 
24 #include <deal.II/base/config.h>
25 #include <deal.II/base/mpi.h>
26 
27 // C++11 related includes.
28 #include <functional>
29 #include <memory>
30 
31 #if !DEAL_II_VERSION_GTE(9,6,0)
32 # include <deal.II/grid/manifold.h>
34 #else
35 // We have a 'using' declaration for new enough deal.II versions. When
36 // we remove the backward compatibility, we should also remove the
37 // 'using' declaration and then can also remove the following
38 // #include:
40 #endif
41 
42 #if !DEAL_II_VERSION_GTE(9,7,0)
44 #endif
45 
48 
49 namespace aspect
50 {
51  namespace big_mpi
52  {
53 
54  using ::Utilities::MPI::broadcast;
55 
56  }
57 
58  // deal.II 9.6 introduced MGTransferMF as a replacement for
59  // MGTransferMatrixFree; deal.II 9.9 renamed it back.
60 #if DEAL_II_VERSION_GTE(9,9,0)
61  template <int dim, typename NumberType>
63 #else
64  template <int dim, typename NumberType>
66 #endif
67 
68  // Global-coarsening transfers share the same class as local smoothing
69  // from deal.II 9.7 onward; 9.6 still needs MGTransferGlobalCoarsening.
70 #if DEAL_II_VERSION_GTE(9,7,0)
71  template <int dim, typename NumberType>
73 #else
74  template <int dim, typename NumberType>
76 #endif
77 
78 
79 #if !DEAL_II_VERSION_GTE(9,7,0)
86  template <typename T, typename P = void>
88 
93 #endif
94 
95 
96 // deal.II versions up to 9.5 had a poorly designed interface of the
97 // SphericalManifold class that made it impossible for us to use.
98 // This file thus contains a copy of it.
99 #if !DEAL_II_VERSION_GTE(9,6,0)
100  using namespace dealii;
101 
110  template <int dim, int spacedim = dim>
111  class SphericalManifold : public Manifold<dim, spacedim>
112  {
113  public:
121 
125  virtual std::unique_ptr<Manifold<dim, spacedim>>
126  clone() const override;
127 
135  virtual Point<spacedim>
137  const Point<spacedim> &p2,
138  const double w) const override;
139 
144  virtual Tensor<1, spacedim>
146  const Point<spacedim> &x2) const override;
147 
151  virtual Tensor<1, spacedim>
153  const typename Triangulation<dim, spacedim>::face_iterator &face,
154  const Point<spacedim> &p) const override;
155 
159  virtual void
161  const typename Triangulation<dim, spacedim>::face_iterator &face,
162  typename Manifold<dim, spacedim>::FaceVertexNormals &face_vertex_normals)
163  const override;
164 
179  virtual void
180  get_new_points(const ArrayView<const Point<spacedim>> &surrounding_points,
181  const Table<2, double> &weights,
182  ArrayView<Point<spacedim>> new_points) const override;
183 
188  virtual Point<spacedim>
189  get_new_point(const ArrayView<const Point<spacedim>> &vertices,
190  const ArrayView<const double> &weights) const override;
191 
196 
197  private:
204  std::pair<double, Tensor<1, spacedim>>
206  const ArrayView<const double> &distances,
207  const ArrayView<const double> &weights) const;
208 
226  void
227  do_get_new_points(const ArrayView<const Point<spacedim>> &surrounding_points,
228  const ArrayView<const double> &weights,
229  ArrayView<Point<spacedim>> new_points) const;
230 
235  };
236 
237 #else
238 
239 // For sufficiently new deal.II versions, we can use the deal.II class, but to
240 // avoid name clashes, we have to import the class into namespace aspect. Once
241 // we rely on these sufficiently new versions of deal.II, we can not only remove
242 // the code above, but also the following lines, and in all places where we
243 // reference 'aspect::SphericalManifold' simply use 'SphericalManifold' instead
244 // (which then refers to the deal.II class).
245 
246  using ::SphericalManifold;
247 
248 #endif
249 
250 
251 // deal.II version 9.7 introduces a new class VectorFunctionFromTensorFunctionObject
252 // that we would like to use also for earlier versions
253 #if !DEAL_II_VERSION_GTE(9,7,0)
254 
255  using namespace dealii;
256 
291  template <int dim, typename RangeNumberType = double>
293  : public Function<dim, RangeNumberType>
294  {
295  public:
314  &tensor_function_object,
315  const unsigned int selected_component = 0,
316  const unsigned int n_components = dim);
317 
322  virtual ~VectorFunctionFromTensorFunctionObject() override = default;
323 
327  virtual RangeNumberType
328  value(const Point<dim> &p, const unsigned int component = 0) const override;
329 
335  virtual void
336  vector_value(const Point<dim> &p,
337  Vector<RangeNumberType> &values) const override;
338 
346  virtual void
347  vector_value_list(
348  const std::vector<Point<dim>> &points,
349  std::vector<Vector<RangeNumberType>> &value_list) const override;
350 
351  private:
356  const std::function<Tensor<1, dim, RangeNumberType>(const Point<dim> &)>
358 
365  const unsigned int selected_component;
366  };
367 
368 
369  template <int dim, typename RangeNumberType>
373  &tensor_function_object,
374  const unsigned int selected_component,
375  const unsigned int n_components)
376  : Function<dim, RangeNumberType>(n_components)
377  , tensor_function_object(tensor_function_object)
378  , selected_component(selected_component)
379  {
380  // Verify that the Tensor<1,dim,RangeNumberType> will fit in the given length
381  // selected_components and not hang over the end of the vector.
382  AssertIndexRange(selected_component + dim - 1, this->n_components);
383  }
384 
385 
386 
387  template <int dim, typename RangeNumberType>
388  inline RangeNumberType
390  const Point<dim> &p,
391  const unsigned int component) const
392  {
393  AssertIndexRange(component, this->n_components);
394 
395  // if the requested component is out of the range selected, then we can
396  // return early
397  if ((component < selected_component) ||
398  (component >= selected_component + dim))
399  return 0;
400 
401  // otherwise retrieve the values from the <tt>tensor_function</tt> to be
402  // placed at the <tt>selected_component</tt> to
403  // <tt>selected_component + dim - 1</tt> elements of the <tt>Vector</tt>
404  // values and pick the correct one
405  const Tensor<1, dim, RangeNumberType> tensor_value =
406  tensor_function_object(p);
407 
408  return tensor_value[component - selected_component];
409  }
410 
411 
412  template <int dim, typename RangeNumberType>
413  inline void
415  const Point<dim> &p,
416  Vector<RangeNumberType> &values) const
417  {
418  Assert(values.size() == this->n_components,
419  ExcDimensionMismatch(values.size(), this->n_components));
420 
421  // Retrieve the values from the <tt>tensor_function</tt> to be placed at
422  // the <tt>selected_component</tt> to
423  // <tt>selected_component + dim - 1</tt> elements of the <tt>Vector</tt>
424  // values.
425  const Tensor<1, dim, RangeNumberType> tensor_value =
426  tensor_function_object(p);
427 
428  // First we make all elements of values = 0
429  values = 0;
430 
431  // Second we adjust the desired components to take on the values in
432  // <tt>tensor_value</tt>.
433  for (unsigned int i = 0; i < dim; ++i)
434  values(i + selected_component) = tensor_value[i];
435  }
436 
437 
445  template <int dim, typename RangeNumberType>
446  void
448  const std::vector<Point<dim>> &points,
449  std::vector<Vector<RangeNumberType>> &value_list) const
450  {
451  Assert(value_list.size() == points.size(),
452  ExcDimensionMismatch(value_list.size(), points.size()));
453 
454  const unsigned int n_points = points.size();
455 
456  for (unsigned int p = 0; p < n_points; ++p)
458  points[p], value_list[p]);
459  }
460 
461 #endif
462 
463 // deal.II versions up to 9.6 had a bug for very thin shell geometries.
464 // This function contains a fixed version.
465 #if !DEAL_II_VERSION_GTE(9,7,0)
466 
467  template <int dim>
468  void
470  const Point<dim> &center,
471  const double inner_radius,
472  const double outer_radius);
473 #endif
474 
475  // deal.II 9.8 made ReferenceCell a template class, whereas older versions
476  // had it as a non-template class. This is a problem.
477  // Rather than litter our own code base with #ifdefs, we can just define the
478  // templated class variant here for older deal.II versions, and then we can
479  // use the same code in all versions.
480 #if !DEAL_II_VERSION_GTE(9,8,0)
481  template <int dim> using ReferenceCell = ::ReferenceCell;
482 #endif
483 
484 }
485 
486 #endif
std::array< Tensor< 1, spacedim >, GeometryInfo< dim >::vertices_per_face > FaceVertexNormals
virtual Tensor< 1, spacedim > get_tangent_vector(const Point< spacedim > &x1, const Point< spacedim > &x2) const override
void do_get_new_points(const ArrayView< const Point< spacedim >> &surrounding_points, const ArrayView< const double > &weights, ArrayView< Point< spacedim >> new_points) const
virtual void get_normals_at_vertices(const typename Triangulation< dim, spacedim >::face_iterator &face, typename Manifold< dim, spacedim >::FaceVertexNormals &face_vertex_normals) const override
virtual Tensor< 1, spacedim > normal_vector(const typename Triangulation< dim, spacedim >::face_iterator &face, const Point< spacedim > &p) const override
virtual Point< spacedim > get_intermediate_point(const Point< spacedim > &p1, const Point< spacedim > &p2, const double w) const override
virtual Point< spacedim > get_new_point(const ArrayView< const Point< spacedim >> &vertices, const ArrayView< const double > &weights) const override
const Point< spacedim > center
Definition: compat.h:195
virtual void get_new_points(const ArrayView< const Point< spacedim >> &surrounding_points, const Table< 2, double > &weights, ArrayView< Point< spacedim >> new_points) const override
SphericalManifold(const Point< spacedim > center=Point< spacedim >())
std::pair< double, Tensor< 1, spacedim > > guess_new_point(const ArrayView< const Tensor< 1, spacedim >> &directions, const ArrayView< const double > &distances, const ArrayView< const double > &weights) const
const PolarManifold< spacedim > polar_manifold
Definition: compat.h:234
virtual std::unique_ptr< Manifold< dim, spacedim > > clone() const override
const std::function< Tensor< 1, dim, RangeNumberType >const Point< dim > &)> tensor_function_object
Definition: compat.h:357
VectorFunctionFromTensorFunctionObject(const std::function< Tensor< 1, dim, RangeNumberType >(const Point< dim > &)> &tensor_function_object, const unsigned int selected_component=0, const unsigned int n_components=dim)
Definition: compat.h:371
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const override
Definition: compat.h:389
virtual void vector_value_list(const std::vector< Point< dim >> &points, std::vector< Vector< RangeNumberType >> &value_list) const override
Definition: compat.h:447
virtual void vector_value(const Point< dim > &p, Vector< RangeNumberType > &values) const override
Definition: compat.h:414
virtual ~VectorFunctionFromTensorFunctionObject() override=default
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void colorize_quarter_hyper_shell(Triangulation< dim > &tria, const Point< dim > &center, const double inner_radius, const double outer_radius)
::ReferenceCell ReferenceCell
Definition: compat.h:481