v0.13.1
Tensor1_value.hpp
Go to the documentation of this file.
1/* The general version, not for pointers. */
2
3#include <iostream>
4#pragma once
5
6namespace FTensor
7{
8 template <class T, int Tensor_Dim> class Tensor1
9 {
10 T data[Tensor_Dim];
11
12 public:
13 /* Initializations for varying numbers of elements. */
14 template <class... U> constexpr Tensor1(U... d) : data{d...}
15 {
16 static_assert(sizeof...(d) == sizeof(data) / sizeof(T),
17 "Incorrect number of Arguments. Constructor should "
18 "initialize the entire Tensor");
19 };
20
21 constexpr Tensor1() {}
22
23 /* There are two operator(int)'s, one for non-consts that lets you
24 change the value, and one for consts that doesn't. */
25
26 T &operator()(const int N)
27 {
28#ifdef FTENSOR_DEBUG
29 if(N >= Tensor_Dim || N < 0)
30 {
31 std::stringstream s;
32 s << "Bad index in Tensor1<T," << Tensor_Dim << ">.operator(" << N
33 << ")" << std::endl;
34 throw std::out_of_range(s.str());
35 }
36#endif
37 return data[N];
38 }
39 T operator()(const int N) const
40 {
41#ifdef FTENSOR_DEBUG
42 if(N >= Tensor_Dim || N < 0)
43 {
44 std::stringstream s;
45 s << "Bad index in Tensor1<T," << Tensor_Dim << ">.operator(" << N
46 << ") const" << std::endl;
47 throw std::out_of_range(s.str());
48 }
49#endif
50 return data[N];
51 }
52
53 /* These operator()'s are the first part in constructing template
54 expressions. They can be used to slice off lower dimensional
55 parts. They are not entirely safe, since you can accidentaly use a
56 higher dimension than what is really allowed (like Dim=5). */
57
58 template <char i, int Dim>
59 typename std::enable_if<
60 (Tensor_Dim >= Dim), Tensor1_Expr<Tensor1<T, Tensor_Dim>, T, Dim, i>>::type
61 operator()(const Index<i, Dim> &)
62 {
63 return Tensor1_Expr<Tensor1<T, Tensor_Dim>, T, Dim, i>(*this);
64 }
65
66 template <char i, int Dim>
67 typename std::enable_if<
68 (Tensor_Dim >= Dim),
70 operator()(const Index<i, Dim> &) const
71 {
72 return Tensor1_Expr<const Tensor1<T, Tensor_Dim>, T, Dim, i>(*this);
73 }
74
75 /* Convenience functions */
76
78 {
80 (*this)(a) /= l2();
81 return *this;
82 }
83
84 T l2() const { return sqrt(l2_squared(Number<Tensor_Dim>())); }
85
86 template <int Current_Dim> T l2_squared(const Number<Current_Dim> &) const
87 {
88 return data[Current_Dim - 1] * data[Current_Dim - 1]
90 }
91 T l2_squared(const Number<1> &) const { return data[0] * data[0]; }
92 };
93
94 template <class T, int Tensor_Dim>
95 std::ostream &operator<<(std::ostream &os,
97 os << '[';
98 for (int i = 0; i + 1 < Tensor_Dim; ++i) {
99 os << t(i) << ',';
100 }
101 if (Tensor_Dim > 0) {
102 os << t(Tensor_Dim - 1);
103 }
104 os << ']';
105 return os;
106 }
107
108 template <class T, int Tensor_Dim>
109 std::istream &operator>>(std::istream &is,
111 char c;
112 is >> c;
113 for (int i = 0; i + 1 < Tensor_Dim; ++i) {
114 is >> t(i) >> c;
115 }
116 if (Tensor_Dim > 0) {
117 is >> t(Tensor_Dim - 1);
118 }
119 is >> c;
120 return is;
121 }
122}
123/// JSON compatible output
124
constexpr double a
T data[Tensor_Dim]
T & operator()(const int N)
constexpr Tensor1()
T l2_squared(const Number< Current_Dim > &) const
T operator()(const int N) const
T l2_squared(const Number< 1 > &) const
constexpr Tensor1(U... d)
Tensor1< T, Tensor_Dim > normalize()
FTensor::Index< 'i', SPACE_DIM > i
const double T
Tensors class implemented by Walter Landry.
Definition: FTensor.hpp:51
const Tensor1_Expr< const dTensor0< T, Dim, i >, typename promote< T, double >::V, Dim, i > d(const Tensor0< T * > &a, const Index< i, Dim > index, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
Definition: dTensor0.hpp:27
std::istream & operator>>(std::istream &is, FTensor::Tensor1< T, Tensor_Dim > &t)
std::ostream & operator<<(std::ostream &os, const FTensor::Tensor1< T, Tensor_Dim > &t)
constexpr double t
plate stiffness
Definition: plate.cpp:76
const int N
Definition: speed_test.cpp:3