20#ifndef LIBMESH_TYPE_VECTOR_H
21#define LIBMESH_TYPE_VECTOR_H
24#include "libmesh/libmesh_common.h"
25#include "libmesh/compare_types.h"
26#include "libmesh/tensor_tools.h"
27#include "libmesh/int_range.h"
28#include "libmesh/fuzzy_equals.h"
40template <
typename T>
class TypeTensor;
41template <
typename T>
class VectorValue;
42template <
typename T>
class TensorValue;
64 template <
typename T2>
89 template <
typename Scalar1,
typename Scalar2,
typename Scalar3>
92 const Scalar1>::type & x,
95 const Scalar2>::type & y=0,
98 const Scalar3>::type & z=0);
106 template <
typename Scalar>
110 const Scalar>::type * sfinae =
nullptr);
127 template <
typename T2>
143 template <
typename T2>
149 template <
typename Scalar>
150 typename std::enable_if<
154 { libmesh_assert_equal_to (p, Scalar(0)); this->
zero();
return *
this; }
160 const T &
slice (
const unsigned int i)
const {
return (*
this)(i); }
166 T &
slice (
const unsigned int i) {
return (*
this)(i); }
173 template <
typename T2>
182 template <
typename T2>
188 template <
typename T2>
194 template <
typename T2>
202 template <
typename T2>
211 template <
typename T2>
217 template <
typename T2>
224 template <
typename T2>
237 template <
typename Scalar>
238 typename std::enable_if<
255 template <
typename Scalar>
256 typename std::enable_if<
274 template <
typename T2>
281 template <
typename T2>
288 template <
typename T2>
410 const bool newline =
true)
const;
456 libmesh_assert_equal_to (y, 0);
463 libmesh_assert_equal_to (z, 0);
469template <
typename Scalar1,
typename Scalar2,
typename Scalar3>
473 const Scalar1>::type & x,
476 const Scalar2>::type & y,
479 const Scalar3>::type & z)
486 libmesh_assert_equal_to (y, 0);
492 libmesh_assert_equal_to (z, 0);
499template <
typename Scalar>
504 const Scalar>::type * )
520template <
typename T2>
525 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
532template <
typename T2>
536 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
546 libmesh_assert_less (i, LIBMESH_DIM);
557 libmesh_assert_less (i, LIBMESH_DIM);
565template <
typename T2>
591template <
typename T2>
603template <
typename T2>
627template <
typename T2>
632 _coords[0] += factor*p(0);
636 _coords[0] += factor*p(0);
637 _coords[1] += factor*p(1);
641 _coords[0] += factor*p(0);
642 _coords[1] += factor*p(1);
643 _coords[2] += factor*p(2);
651template <
typename T2>
678template <
typename T2>
690template <
typename T2>
694 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
701template <
typename T2>
705 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
706 _coords[i] -= factor*p(i);
736template <
typename Scalar>
738typename std::enable_if<
763template <
typename T,
typename Scalar>
765typename std::enable_if<
781 _coords[0] *= factor;
785 _coords[0] *= factor;
786 _coords[1] *= factor;
790 _coords[0] *= factor;
791 _coords[1] *= factor;
792 _coords[2] *= factor;
801template <
typename Scalar>
803typename std::enable_if<
810 libmesh_assert_not_equal_to (
static_cast<TS
>(factor),
811 static_cast<TS
>(0.));
838 libmesh_assert_not_equal_to (factor,
static_cast<T
>(0.));
840 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
841 _coords[i] /= factor;
850template <
typename T2>
856 return _coords[0]*p.
_coords[0];
860 return (_coords[0]*p.
_coords[0] +
865 return (_coords[0]*p(0) +
872template <
typename T2>
883template <
typename T2>
888 libmesh_assert_equal_to (LIBMESH_DIM, 3);
911 return sqrt(this->norm_sq());
920 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
951 for (
const auto & val : _coords)
966 decltype(abs(T())) ret{};
968 ret += abs(_coords[i]);
996 return (_coords[0] == rhs.
_coords[0]);
1000 return (_coords[0] == rhs.
_coords[0] &&
1001 _coords[1] == rhs.
_coords[1]);
1005 return (_coords[0] == rhs.
_coords[0] &&
1006 _coords[1] == rhs.
_coords[1] &&
1007 _coords[2] == rhs.
_coords[2]);
1013template <
typename T>
1017 return (!(*
this == rhs));
1030template <
typename T>
1038 a(0)*(
b(1)*c(2) -
b(2)*c(1)) -
1039 a(1)*(
b(0)*c(2) -
b(2)*c(0)) +
1040 a(2)*(
b(0)*c(1) -
b(1)*c(0));
1052template <
typename T>
1061 norm02 = v02.
norm(),
1062 norm03 = v03.
norm();
1063 const T tan_half_angle =
1065 ((v01*v02)*norm03 + (v01*v03)*norm02 + (v02*v03)*norm01 +
1066 norm01*norm02*norm03);
1068 return Real(2)*atan(tan_half_angle);
1078template <
typename T>
1091 (e02.
cross(e21)).cross(scaled_vec);
1093 const T e02_cross_e21_z = e02(0)*e21(1)-e02(1)*e21(0);
1094 const TypeVector<T> numerator {-e02_cross_e21_z*scaled_vec(1),
1095 e02_cross_e21_z*scaled_vec(0)};
1109template <
typename T>
1114 T z =
b(0)*c(1) -
b(1)*c(0);
1117 T x =
b(1)*c(2) -
b(2)*c(1),
1118 y =
b(0)*c(2) -
b(2)*c(0);
1119 return x*x + y*y + z*z;
1130template <
typename T>
1139template <
typename T>
1144 auto && length = norm();
1146 libmesh_assert_not_equal_to (length,
static_cast<Real>(0.));
1165template <
typename T>
1170 os <<
"x=" << (*this)(0);
1176 << std::setw(8) << (*this)(0) <<
", "
1177 << std::setw(8) << (*this)(1) <<
")";
1183 << std::setw(8) << (*this)(0) <<
", "
1184 << std::setw(8) << (*this)(1) <<
", "
1185 << std::setw(8) << (*this)(2) <<
")";
1191template <
typename T>
1194 using std::isfinite;
1210template <
typename T>
1217 bool has_inf =
false;
1223 has_inf = has_inf ||
isinf(var(i));
1235template <
typename T>
1247template <
typename T>
1253template <
typename T,
typename T2>
1259template <typename T, typename T2, typename std::enable_if<ScalarTraits<T>::value,
int>::type = 0>
1264 for (
unsigned int i = 0; i < LIBMESH_DIM; i++)
1270template <typename T, typename T2, typename std::enable_if<ScalarTraits<T2>::value,
int>::type = 0>
1271TypeVector<typename CompareTypes<T, T2>::supertype>
1276 for (
unsigned int i = 0; i < LIBMESH_DIM; i++)
1277 ret(i) = a(i) * conj_b;
1282template <
typename T>
1289template <
typename T,
typename T2>
1300template <
typename T>
1304 return vector.norm_sq();
1308#ifdef LIBMESH_HAVE_METAPHYSICL
1311template <
typename T>
1319 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
1320 ret(i) = raw_value(in(i));
1326template <
typename T,
typename U>
1327struct ReplaceAlgebraicType<
libMesh::TypeVector<T>, U>
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
This class defines a vector in LIBMESH_DIM dimensional space of type T.
void subtract_scaled(const TypeVector< T2 > &, const T &)
Subtract a scaled value from this vector without creating a temporary.
T & slice(const unsigned int i)
bool operator>(const TypeVector< T > &rhs) const
const TypeVector< T > & operator*=(const T &)
Multiply this vector by a scalar value.
T _coords[LIBMESH_DIM]
The coordinates of the TypeVector.
std::enable_if< ScalarTraits< Scalar >::value, TypeVector & >::type operator=(const Scalar &libmesh_dbg_var(p))
Assignment-from-scalar operator.
TypeVector(const T &x, const T &y=0, const T &z=0)
Constructor-from-T.
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
void assign(const TypeVector< T2 > &)
Assign to this vector without creating a temporary.
bool operator>=(const TypeVector< T > &rhs) const
TypeVector(const Scalar &x, typename std::enable_if< ScalarTraits< Scalar >::value, const Scalar >::type *sfinae=nullptr)
Constructor-from-scalar.
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
void zero()
Set all entries of the vector to 0.
TypeVector(const TypeVector &p)=default
Copy-constructor for the trivial case.
TypeVector< typename CompareTypes< T, T2 >::supertype > operator+(const TypeVector< T2 > &) const
Add two vectors.
const T & slice(const unsigned int i) const
bool operator!=(const TypeVector< T > &rhs) const
const TypeVector< T > & operator-=(const TypeVector< T2 > &)
Subtract from this vector.
~TypeVector()=default
Destructor.
bool operator<=(const TypeVector< T > &rhs) const
void write_unformatted(std::ostream &out_stream, const bool newline=true) const
Unformatted print to the stream out.
T value_type
Helper typedef for C++98 generic programming.
unsigned int index_type
Helper typedef for generic index programming.
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
friend std::ostream & operator<<(std::ostream &os, const TypeVector< T > &t)
Formatted print as above but supports the syntax:
std::enable_if< ScalarTraits< Scalar >::value, TypeVector< typenameCompareTypes< T, Scalar >::supertype > >::type operator*(const Scalar &) const
Multiply this vector by a scalar value.
TypeVector(typename std::enable_if< ScalarTraits< Scalar1 >::value, const Scalar1 >::type &x, typename std::enable_if< ScalarTraits< Scalar2 >::value, const Scalar2 >::type &y=0, typename std::enable_if< ScalarTraits< Scalar3 >::value, const Scalar3 >::type &z=0)
Constructor-from-scalars.
CompareTypes< T, T2 >::supertype contract(const TypeVector< T2 > &) const
const TypeVector< T > & operator/=(const T &)
Divide each entry of this vector by scalar value.
TypeVector()
Empty constructor.
void add(const TypeVector< T2 > &)
Add to this vector without creating a temporary.
bool operator<(const TypeVector< T > &rhs) const
void subtract(const TypeVector< T2 > &)
Subtract from this vector without creating a temporary.
TypeVector< T > operator-() const
const T & operator()(const unsigned int i) const
const TypeVector< T > & operator+=(const TypeVector< T2 > &)
Add to this vector.
void add_scaled(const TypeVector< T2 > &, const T &)
Add a scaled value to this vector without creating a temporary.
std::enable_if< ScalarTraits< Scalar >::value, TypeVector< typenameCompareTypes< T, Scalar >::supertype > >::type operator/(const Scalar &) const
Divide each entry of this vector by scalar value.
TypeVector(const TypeVector< T2 > &p)
Copy-constructor.
TypeVector< T > unit() const
bool operator==(const TypeVector< T > &rhs) const
void print(std::ostream &os=libMesh::out) const
Formatted print, by default to libMesh::out.
The libMesh namespace provides an interface to certain functionality in the library.
bool relative_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within a relative tolerance.
bool absolute_fuzzy_equals(const T &var1, const T2 &var2, const Real tol=TOLERANCE *TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
auto l1_norm(const NumericVector< T > &vec)
static constexpr std::size_t libmesh_dim
void libmesh_ignore(const Args &...)
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
bool isfinite(std::complex< T > a)
bool isnan(std::complex< T > a)
std::enable_if< ScalarTraits< Scalar >::value, TypeNTensor< N, typenameCompareTypes< Scalar, T >::supertype > >::type operator*(const Scalar &, const TypeNTensor< N, T > &)
T cross_norm(const TypeVector< T > &b, const TypeVector< T > &c)
Calls cross_norm_sq() and takes the square root of the result.
TypeTensor< typename CompareTypes< T, T2 >::supertype > outer_product(const TypeVector< T > &a, const TypeVector< T2 > &b)
static constexpr Real TOLERANCE
bool isinf(std::complex< T > a)
T solid_angle(const TypeVector< T > &v01, const TypeVector< T > &v02, const TypeVector< T > &v03)
auto l1_norm_diff(const NumericVector< T > &vec1, const NumericVector< T > &vec2)
TypeVector< T > circumcenter(const TypeVector< T > &p0, const TypeVector< T > &p1, const TypeVector< T > &p2)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
T cross_norm_sq(const TypeVector< T > &b, const TypeVector< T > &c)
Compute |b x c|^2 without creating the extra temporary produced by calling b.cross(c)....
auto norm(const libMesh::TypeVector< T > &vector) -> decltype(std::norm(T()))
TypeVector< typename CompareTypes< T, T2 >::supertype > supertype
TypeVector< T > supertype