v0.14.0
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 
6 namespace 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),
69  Tensor1_Expr<const Tensor1<T, Tensor_Dim>, T, Dim, i>>::type
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 
FTensor::Tensor1::operator()
T operator()(const int N) const
Definition: Tensor1_value.hpp:39
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::Tensor1
Definition: Tensor1_value.hpp:8
FTensor::operator>>
std::istream & operator>>(std::istream &is, FTensor::Tensor1< T, Tensor_Dim > &t)
Definition: Tensor1_value.hpp:109
FTensor::Tensor1::l2
T l2() const
Definition: Tensor1_value.hpp:84
FTensor::d
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
FTensor::Tensor1::data
T data[Tensor_Dim]
Definition: Tensor1_value.hpp:10
c
const double c
speed of light (cm/ns)
Definition: initial_diffusion.cpp:39
FTensor::Number
Definition: Number.hpp:11
FTensor::Tensor1_Expr
Definition: Tensor1_Expr.hpp:27
a
constexpr double a
Definition: approx_sphere.cpp:30
FTensor::Tensor1::Tensor1
constexpr Tensor1()
Definition: Tensor1_value.hpp:21
convert.type
type
Definition: convert.py:64
FTensor::Tensor1::Tensor1
constexpr Tensor1(U... d)
Definition: Tensor1_value.hpp:14
FTensor::Tensor1::l2_squared
T l2_squared(const Number< 1 > &) const
Definition: Tensor1_value.hpp:91
FTensor::operator<<
std::ostream & operator<<(std::ostream &os, const FTensor::Tensor1< T, Tensor_Dim > &t)
Definition: Tensor1_value.hpp:95
t
constexpr double t
plate stiffness
Definition: plate.cpp:59
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Index
Definition: Index.hpp:23
FTensor::Tensor1::normalize
Tensor1< T, Tensor_Dim > normalize()
Definition: Tensor1_value.hpp:77
std::enable_if
Definition: enable_if.hpp:7
N
const int N
Definition: speed_test.cpp:3
FTensor::Tensor1::l2_squared
T l2_squared(const Number< Current_Dim > &) const
Definition: Tensor1_value.hpp:86
EshelbianPlasticity::U
@ U
Definition: EshelbianContact.cpp:193
FTensor::Tensor1::operator()
T & operator()(const int N)
Definition: Tensor1_value.hpp:26