File traits.hxx#

namespace bout

Provides access to the Hypre library, handling initialisation and finalisation.

Usage

#include <bout/hyprelib.hxx>

class MyClass { public:

private: HypreLib lib; };

This will then automatically initialise Hypre the first time an object is created, and finalise it when the last object is destroyed.

Copyright 2012 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu

Contact: Ben Dudson, bd512@york.ac.uk

This file is part of BOUT++.

BOUT++ is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

BOUT++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with BOUT++. If not, see http://www.gnu.org/licenses/.

Explicit inversion of a 3x3 matrix a

If the matrix is singular (ill conditioned), the determinant is return. Otherwise, an empty std::optional is return

SNB model

namespace utils#

Typedefs

template<class T>
using is_Field = std::is_base_of<Field, T>#
template<class T>
using is_Field2D = std::is_base_of<Field2D, T>#
template<class T>
using is_Field3D = std::is_base_of<Field3D, T>#
template<class T>
using is_FieldPerp = std::is_base_of<FieldPerp, T>#
template<class T>
using is_Options = std::is_base_of<Options, T>#
template<class... Ts> EnableIfField = std::enable_if_t<(is_Field_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of Field, and returns the common type: i.e. Field3D if at least one argument is Field3D, otherwise Field2D if they are all Field2D

This is most useful in two particular cases:

  1. when there are multiple overloads for a function but some only make sense for fields (as opposed to BoutReal, say) or vice-versa, and some overloads should not be used for fields

  2. when a function takes multiple fields and the return type is also a field and must be “big enough”

In other cases, such as a function without overloads that only works for fields, consider using static_assert with is_Field to give a nice compile-time error

Examples

Consider the following template function:

template <class T, class U, class V,
     class ResultType = typename bout::utils::EnableIfField<T, U, V>>
auto where(const T& test, const U& gt0, const V& le0) -> ResultType {
  // function body
}
This function only “appears” if T, U and V are all subclasses of Field. ResultType is the common type of T, U and V. If T and U are both Field2D, ResultType is Field2D if V is Field2D, and Field3D if V is Field3D.

template<class... Ts> EnableIfField2D = std::enable_if_t<(is_Field2D_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of Field2D, and returns the common type

template<class... Ts> EnableIfField3D = std::enable_if_t<(is_Field3D_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of Field3D, and returns the common type

template<class... Ts> EnableIfFieldPerp = std::enable_if_t<(is_FieldPerp_v< Ts > and ...), std::common_type_t< Ts... > >

Enable a function if all the Ts are subclasses of FieldPerp, and returns the common type

template<class T>
using EnableIfOptions = std::enable_if_t<std::is_base_of_v<Options, T>>#

Enable a function if T is a subclass of Options.

template<typename T>
using tuple_index_sequence = std::make_index_sequence<std::tuple_size_v<T>>#

Create a std::index_sequence with the length of a tuple T

Variables

template<class T>
constexpr bool is_Field_v = std::is_base_of_v<Field, T>#

True if T is derived from Field, otherwise false

Examples

template <class T>
void print_field(const T& field) {
  static_assert(bout::utils::is_Field_v<T>,
      "print_field only works with Field2Ds, Field3Ds or FieldPerps")
  // implementation
}
template<class T>
constexpr bool is_Field2D_v = std::is_base_of_v<Field2D, T>#

True if T is derived from Field2D, otherwise false.

template<class T>
constexpr bool is_Field3D_v = std::is_base_of_v<Field3D, T>#

True if T is derived from Field3D, otherwise false.

template<class T>
constexpr bool is_FieldPerp_v = std::is_base_of_v<FieldPerp, T>#

True if T is derived from FieldPerp, otherwise false.

template<class T>
constexpr bool is_Options_v = std::is_base_of_v<Options, T>#

True if T is derived from Options, otherwise false.