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"
33 #ifdef LIBMESH_HAVE_EIGEN
34 #include "libmesh/ignore_warnings.h"
36 #include "libmesh/restore_warnings.h"
39 #ifdef LIBMESH_HAVE_METAPHYSICL
40 #include "metaphysicl/dualnumber_decl.h"
44 #ifdef LIBMESH_HAVE_EIGEN
51 template <
typename T,
typename D,
bool asd>
52 using ADRealEigenVector = Eigen::Matrix<MetaPhysicL::DualNumber<T, D, asd>, Eigen::Dynamic, 1>;
63 template <
typename T,
typename D,
bool asd>
75 template <
typename T,
typename D,
bool asd>
87 template <
typename T,
typename D,
bool asd>
99 template <
typename T,
typename D,
bool asd>
111 template <
typename T,
typename D,
bool asd>
123 template <
typename T,
typename D,
bool asd>
132 template <
typename T>
class TypeTensor;
133 template <
typename T>
class VectorValue;
134 template <
typename T>
class TensorValue;
139 template <
typename T>
153 template <
typename T>
156 template <
typename T2>
178 template <
typename Scalar1,
typename Scalar2,
typename Scalar3>
180 boostcopy::enable_if_c<ScalarTraits<Scalar1>::value,
181 const Scalar1>::type & x,
183 boostcopy::enable_if_c<ScalarTraits<Scalar2>::value,
184 const Scalar2>::type & y=0,
186 boostcopy::enable_if_c<ScalarTraits<Scalar3>::value,
187 const Scalar3>::type & z=0);
195 template <
typename Scalar>
198 boostcopy::enable_if_c<ScalarTraits<Scalar>::value,
199 const Scalar>::type * sfinae =
nullptr);
219 template <
typename T2>
238 template <
typename T2>
248 template <
typename Scalar>
249 typename boostcopy::enable_if_c<
250 ScalarTraits<Scalar>::value,
253 { libmesh_assert_equal_to (p, Scalar(0)); this->
zero();
return *
this; }
261 const T &
operator () (
const unsigned int i)
const;
262 const T &
slice (
const unsigned int i)
const {
return (*
this)(i); }
271 T &
slice (
const unsigned int i) {
return (*
this)(i); }
280 template <
typename T2>
291 template <
typename T2>
301 template <
typename T2>
312 template <
typename T2>
321 template <
typename T2>
331 template <
typename T2>
348 template <
typename Scalar>
349 typename boostcopy::enable_if_c<
350 ScalarTraits<Scalar>::value,
370 template <
typename Scalar>
371 typename boostcopy::enable_if_c<
372 ScalarTraits<Scalar>::value,
395 template <
typename T2>
396 typename CompareTypes<T, T2>::supertype
406 template <
typename T2>
407 typename CompareTypes<T, T2>::supertype
417 template <
typename T2>
433 auto norm() const -> decltype(std::
norm(T()));
480 bool operator==(const
TypeVector<T> &rhs) const;
488 bool operator!=(const
TypeVector<T> &rhs) const;
498 bool operator<(const
TypeVector<T> &rhs) const;
508 bool operator<=(const
TypeVector<T> &rhs) const;
518 bool operator>(const
TypeVector<T> &rhs) const;
528 bool operator>=(const
TypeVector<T> &rhs) const;
535 void print(std::ostream &os = libMesh::
out) const;
545 friend std::ostream &operator<<(std::ostream &os, const
TypeVector<T> &t)
558 void write_unformatted(std::ostream &out_stream,
const bool newline =
true)
const;
575 template <
typename T>
592 template <
typename T>
604 libmesh_assert_equal_to (y, 0);
611 libmesh_assert_equal_to (z, 0);
616 template <
typename T>
617 template <
typename Scalar1,
typename Scalar2,
typename Scalar3>
620 boostcopy::enable_if_c<ScalarTraits<Scalar1>::value,
621 const Scalar1>::type & x,
623 boostcopy::enable_if_c<ScalarTraits<Scalar2>::value,
624 const Scalar2>::type & y,
626 boostcopy::enable_if_c<ScalarTraits<Scalar3>::value,
627 const Scalar3>::type & z)
634 libmesh_assert_equal_to (y, 0);
640 libmesh_assert_equal_to (z, 0);
646 template <
typename T>
647 template <
typename Scalar>
651 boostcopy::enable_if_c<ScalarTraits<Scalar>::value,
652 const Scalar>::type * )
667 template <
typename T>
668 template <
typename T2>
673 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
674 _coords[i] = p._coords[i];
679 template <
typename T>
680 template <
typename T2>
684 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
685 _coords[i] = p._coords[i];
690 template <
typename T>
694 libmesh_assert_less (i, LIBMESH_DIM);
701 template <
typename T>
705 libmesh_assert_less (i, LIBMESH_DIM);
712 template <
typename T>
713 template <
typename T2>
718 typedef typename CompareTypes<T, T2>::supertype TS;
725 _coords[1] + p._coords[1]);
730 _coords[1] + p._coords[1],
731 _coords[2] + p._coords[2]);
738 template <
typename T>
739 template <
typename T2>
750 template <
typename T>
751 template <
typename T2>
756 _coords[0] += p._coords[0];
760 _coords[0] += p._coords[0];
761 _coords[1] += p._coords[1];
765 _coords[0] += p._coords[0];
766 _coords[1] += p._coords[1];
767 _coords[2] += p._coords[2];
774 template <
typename T>
775 template <
typename T2>
777 void TypeVector<T>::add_scaled (
const TypeVector<T2> & p,
const T & factor)
780 _coords[0] += factor*p(0);
784 _coords[0] += factor*p(0);
785 _coords[1] += factor*p(1);
789 _coords[0] += factor*p(0);
790 _coords[1] += factor*p(1);
791 _coords[2] += factor*p(2);
798 template <
typename T>
799 template <
typename T2>
801 TypeVector<typename CompareTypes<T, T2>::supertype>
804 typedef typename CompareTypes<T, T2>::supertype TS;
812 _coords[1] - p._coords[1]);
817 _coords[1] - p._coords[1],
818 _coords[2] - p._coords[2]);
825 template <
typename T>
826 template <
typename T2>
837 template <
typename T>
838 template <
typename T2>
842 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
843 _coords[i] -= p._coords[i];
848 template <
typename T>
849 template <
typename T2>
853 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
854 _coords[i] -= factor*p(i);
859 template <
typename T>
883 template <
typename T>
884 template <
typename Scalar>
886 typename boostcopy::enable_if_c<
887 ScalarTraits<Scalar>::value,
891 typedef typename CompareTypes<T, Scalar>::supertype SuperType;
911 template <
typename T,
typename Scalar>
913 typename boostcopy::enable_if_c<
914 ScalarTraits<Scalar>::value,
924 template <
typename T>
929 _coords[0] *= factor;
933 _coords[0] *= factor;
934 _coords[1] *= factor;
938 _coords[0] *= factor;
939 _coords[1] *= factor;
940 _coords[2] *= factor;
948 template <
typename T>
949 template <
typename Scalar>
951 typename boostcopy::enable_if_c<
952 ScalarTraits<Scalar>::value,
956 libmesh_assert_not_equal_to (factor, static_cast<T>(0.));
958 typedef typename CompareTypes<T, Scalar>::supertype TS;
980 template <
typename T>
985 libmesh_assert_not_equal_to (factor, static_cast<T>(0.));
987 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
988 _coords[i] /= factor;
996 template <
typename T>
997 template <
typename T2>
999 typename CompareTypes<T, T2>::supertype
1002 #if LIBMESH_DIM == 1
1003 return _coords[0]*p._coords[0];
1006 #if LIBMESH_DIM == 2
1007 return (_coords[0]*p._coords[0] +
1008 _coords[1]*p._coords[1]);
1011 #if LIBMESH_DIM == 3
1012 return (_coords[0]*p(0) +
1018 template <
typename T>
1019 template <
typename T2>
1021 typename CompareTypes<T, T2>::supertype
1029 template <
typename T>
1030 template <
typename T2>
1034 typedef typename CompareTypes<T, T2>::supertype TS;
1035 libmesh_assert_equal_to (LIBMESH_DIM, 3);
1041 #if LIBMESH_DIM == 3
1042 return TypeVector<TS>( _coords[1]*p._coords[2] - _coords[2]*p._coords[1],
1043 -_coords[0]*p._coords[2] + _coords[2]*p._coords[0],
1044 _coords[0]*p._coords[1] - _coords[1]*p._coords[0]);
1053 template <
typename T>
1062 template <
typename T>
1066 for (
unsigned int i=0; i<LIBMESH_DIM; i++)
1072 template <
typename T>
1076 #if LIBMESH_DIM == 1
1080 #if LIBMESH_DIM == 2
1085 #if LIBMESH_DIM == 3
1093 template <
typename T>
1097 for (
const auto & val : _coords)
1103 template <
typename T>
1107 #if LIBMESH_DIM == 1
1108 return (
std::abs(_coords[0] - rhs._coords[0])
1112 #if LIBMESH_DIM == 2
1113 return (
std::abs(_coords[0] - rhs._coords[0]) +
1114 std::abs(_coords[1] - rhs._coords[1])
1118 #if LIBMESH_DIM == 3
1119 return (
std::abs(_coords[0] - rhs._coords[0]) +
1120 std::abs(_coords[1] - rhs._coords[1]) +
1121 std::abs(_coords[2] - rhs._coords[2])
1128 template <
typename T>
1132 #if LIBMESH_DIM == 1
1133 return this->absolute_fuzzy_equals(rhs, tol *
1137 #if LIBMESH_DIM == 2
1138 return this->absolute_fuzzy_equals(rhs, tol *
1143 #if LIBMESH_DIM == 3
1144 return this->absolute_fuzzy_equals(rhs, tol *
1153 template <
typename T>
1157 #if LIBMESH_DIM == 1
1158 return (_coords[0] == rhs._coords[0]);
1161 #if LIBMESH_DIM == 2
1162 return (_coords[0] == rhs._coords[0] &&
1163 _coords[1] == rhs._coords[1]);
1166 #if LIBMESH_DIM == 3
1167 return (_coords[0] == rhs._coords[0] &&
1168 _coords[1] == rhs._coords[1] &&
1169 _coords[2] == rhs._coords[2]);
1175 template <
typename T>
1179 return (!(*
this == rhs));
1192 template <
typename T>
1198 #if LIBMESH_DIM == 3
1200 a(0)*(b(1)*c(2) - b(2)*c(1)) -
1201 a(1)*(b(0)*c(2) - b(2)*c(0)) +
1202 a(2)*(b(0)*c(1) - b(1)*c(0));
1215 template <
typename T>
1220 T z = b(0)*c(1) - b(1)*c(0);
1222 #if LIBMESH_DIM == 3
1223 T x = b(1)*c(2) - b(2)*c(1),
1224 y = b(0)*c(2) - b(2)*c(0);
1225 return x*x + y*y + z*z;
1236 template <
typename T>
1244 template <
typename T>
1249 auto && length =
norm();
1251 libmesh_assert_not_equal_to (length, static_cast<Real>(0.));
1253 #if LIBMESH_DIM == 1
1257 #if LIBMESH_DIM == 2
1262 #if LIBMESH_DIM == 3
1270 template <
typename T>
1276 template <
typename T,
typename T2>
1282 template <typename T, typename T2, typename std::enable_if<ScalarTraits<T>::value,
int>::type = 0>
1287 for (
unsigned int i = 0; i < LIBMESH_DIM; i++)
1293 template <typename T, typename T2, typename std::enable_if<ScalarTraits<T2>::value,
int>::type = 0>
1294 TypeVector<typename CompareTypes<T, T2>::supertype>
1299 for (
unsigned int i = 0; i < LIBMESH_DIM; i++)
1300 ret(i) = a(i) * conj_b;
1308 template <
typename T>
1311 return vector.norm();
1315 #ifdef LIBMESH_HAVE_METAPHYSICL
1316 namespace MetaPhysicL
1318 template <
typename T>
1319 struct RawType<libMesh::TypeVector<T>>
1326 for (
unsigned int i = 0; i < LIBMESH_DIM; ++i)
1327 ret(i) = raw_value(in(i));
1333 template <
typename T,
typename U>
1334 struct ReplaceAlgebraicType<libMesh::TypeVector<T>, U>
1341 #endif // LIBMESH_TYPE_VECTOR_H
T _coords[LIBMESH_DIM]
TypeVector 的坐标。
bool operator==(const TypeVector< T > &rhs) const
判断两个向量的每个分量是否相等。
const TypeVector< T > & operator*=(const T &)
将该向量乘以标量值。
const T & slice(const unsigned int i) const
TypeTensor< typename CompareTypes< T, T2 >::supertype > outer_product(const TypeVector< T > &a, const TypeVector< T2 > &b)
auto norm() const -> decltype(std::norm(T()))
返回向量的模,即元素平方和的平方根。
void subtract_scaled(const TypeVector< T2 > &, const T &)
从该向量中减去另一个向量的缩放值,不创建临时对象。
CompareTypes< T, T2 >::supertype contract(const TypeVector< T2 > &) const
返回 TypeVector::operator*() 的结果。
static constexpr Real TOLERANCE
bool is_zero() const
判断向量的所有值是否为零。
T cross_norm(const TypeVector< T > &b, const TypeVector< T > &c)
Calls cross_norm_sq() and takes the square root of the result.
TypeVector< typename CompareTypes< T, T2 >::supertype > supertype
unsigned int index_type
辅助 typedef 用于泛型索引编程。
TypeVector< T > supertype
TypeVector< T > operator-() const
返回该向量的相反向量的副本。
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的平方根。
void write_unformatted(std::ostream &out_stream, const bool newline=true) const
无格式输出到流 out。只是将向量的元素用空格分隔打印出来。 默认情况下,还会打印一个换行符,但可以通过 newline 参数来控制这个行为。
TypeVector< typename CompareTypes< T, T2 >::supertype > operator+(const TypeVector< T2 > &) const
向量相加。
const TypeVector< T > & operator+=(const TypeVector< T2 > &)
向量相加。
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的绝对值。
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).norm_sq().
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
void libmesh_ignore(const Args &...)
auto norm_sq() const -> decltype(std::norm(T()))
返回向量的模的平方,即元素模的平方和。
void subtract(const TypeVector< T2 > &)
从另一个向量中减去该向量,不创建临时对象。
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, TypeNTensor< N, typename CompareTypes< Scalar, T >::supertype > >::type operator*(const Scalar &, const TypeNTensor< N, T > &)
T value_type
辅助 typedef 用于 C++98 泛型编程。
void print(std::ostream &os=libMesh::out) const
格式化输出,默认输出到 libMesh::out 流。
bool operator!=(const TypeVector< T > &rhs) const
判断两个向量是否不相等。
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
计算该向量与另一个向量的叉积。
该类定义了一个在 LIBMESH_DIM 维度空间中类型为 T 的向量。
const TypeVector< T > & operator/=(const T &)
将该向量的每个分量除以标量值。
TypeVector< T > unit() const
返回指向该向量方向的单位向量。
TypeVector()
空构造函数。将向量初始化为 LIBMESH_DIM 维中的零向量。
const TypeVector< T > & operator-=(const TypeVector< T2 > &)
从该向量中减去另一个向量。
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
判断两个向量是否在绝对容差 tol 内相等。
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, TypeVector< typename CompareTypes< T, Scalar >::supertype > >::type operator/(const Scalar &) const
将该向量的每个分量除以标量值。
void assign(const TypeVector< T2 > &)
在不创建临时对象的情况下将向量赋值给该向量。
const T & operator()(const unsigned int i) const
返回向量中的第 i 个分量的常量引用。
T & slice(const unsigned int i)
Eigen::Matrix< MetaPhysicL::DualNumber< T, D, asd >, Eigen::Dynamic, 1 > ADRealEigenVector
使用MetaPhysicL::DualNumber类型的Eigen矩阵来定义自动微分实数向量类型。
ADRealEigenVector< T, D, asd > norm(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的范数。
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, TypeVector & >::type operator=(const Scalar &libmesh_dbg_var(p))
赋值操作符,用于将标量值赋给该向量以清零。
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
判断两个向量是否在相对容差 tol 内相等。
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, TypeVector< typename CompareTypes< T, Scalar >::supertype > >::type operator*(const Scalar &) const
将该向量乘以标量值。
~TypeVector()=default
析构函数。