v0.14.0
Tensor3_antisymmetric_pointer.hpp
Go to the documentation of this file.
1 /* A version for pointers. */
2 
3 #pragma once
4 
5 namespace FTensor
6 {
7  template <class T, int Tensor_Dim0, int Tensor_Dim12>
8  class Tensor3_antisymmetric<T *, Tensor_Dim0, Tensor_Dim12>
9  {
10  mutable T *restrict
11  data[Tensor_Dim0][(Tensor_Dim12 * (Tensor_Dim12 - 1)) / 2];
12 
13  public:
14  template <class... U> Tensor3_antisymmetric(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 
22 
23  /* There are two ways of accessing the values inside,
24  unsafe(int,int,int) and operator(int,int,int).
25  unsafe(int,int,int) will give you a wrong answer if you aren't
26  careful. The problem is that we only store the minimal set of
27  components, but some have different signs. We can't return the
28  negative of a component, and assign something to it, because that
29  would assign something to a temporary. To get the correct answer
30  if you don't want to change the value, just use
31  operator(int,int,int). */
32 
33  T &unsafe(const int N1, const int N2, const int N3)
34  {
35 #ifdef FTENSOR_DEBUG
36  if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
37  || N3 >= Tensor_Dim12 || N3 < 0 || N2 >= N3)
38  {
39  std::stringstream s;
40  s << "Bad index in Tensor3_antisymmetric<T*," << Tensor_Dim0 << ","
41  << Tensor_Dim12 << ">.unsafe(" << N1 << "," << N2 << "," << N3
42  << ")" << std::endl;
43  throw std::out_of_range(s.str());
44  }
45 #endif
46  return *data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2];
47  }
48 
49  T operator()(const int N1, const int N2, const int N3) const
50  {
51 #ifdef FTENSOR_DEBUG
52  if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
53  || N3 >= Tensor_Dim12 || N3 < 0)
54  {
55  std::stringstream s;
56  s << "Bad index in Tensor3_antisymmetric<T*," << Tensor_Dim0 << ","
57  << Tensor_Dim12 << ">.operator(" << N1 << "," << N2 << "," << N3
58  << ") const" << std::endl;
59  throw std::out_of_range(s.str());
60  }
61 #endif
62  return N2 < N3
63  ? *data[N1]
64  [N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2]
65  : (N2 > N3
66  ? -*data[N1][N2 - 1
67  + (N3 * (2 * (Tensor_Dim12 - 1) - N3 - 1)) / 2]
68  : 0.0);
69  }
70 
71  T *ptr(const int N1, const int N2, const int N3) const
72  {
73 #ifdef FTENSOR_DEBUG
74  if(N1 >= Tensor_Dim0 || N1 < 0 || N2 >= Tensor_Dim12 || N2 < 0
75  || N3 >= Tensor_Dim12 || N3 < 0)
76  {
77  std::stringstream s;
78  s << "Bad index in Tensor3_antisymmetric<T*," << Tensor_Dim0 << ","
79  << Tensor_Dim12 << ">.ptr(" << N1 << "," << N2 << "," << N3 << ")"
80  << std::endl;
81  throw std::out_of_range(s.str());
82  }
83 #endif
84  return N2 < N3
85  ? data[N1][N3 - 1 + (N2 * (2 * (Tensor_Dim12 - 1) - N2 - 1)) / 2]
86  : (N2 > N3
87  ? -data[N1][N2 - 1
88  + (N3 * (2 * (Tensor_Dim12 - 1) - N3 - 1)) / 2]
89  : 0);
90  }
91 
92  /* These operator()'s are the first part in constructing template
93  expressions. */
94 
95  template <char i, char j, char k, int Dim0, int Dim12>
98  j, k>
99  operator()(const Index<i, Dim0> index1, const Index<j, Dim12> index2,
100  const Index<k, Dim12> index3)
101  {
104  i, j, k>(*this);
105  }
106 
107  template <char i, char j, char k, int Dim0, int Dim12>
110  Dim12, i, j, k>
111  operator()(const Index<i, Dim0> index1, const Index<j, Dim12> index2,
112  const Index<k, Dim12> index3) const
113  {
116  Dim12, i, j, k>(*this);
117  }
118 
119  /* The ++ operator increments the pointer, not the number that the
120  pointer points to. This allows iterating over a grid. */
121 
123  operator++() const
124  {
125  for(int i = 0; i < Tensor_Dim0; ++i)
126  for(int j = 0; j < (Tensor_Dim12 * (Tensor_Dim12 - 1)) / 2; ++j)
127  ++data[i][j];
128  return *this;
129  }
130  };
131 }
FTensor
JSON compatible output.
Definition: Christof_constructor.hpp:6
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::operator()
T operator()(const int N1, const int N2, const int N3) const
Definition: Tensor3_antisymmetric_pointer.hpp:49
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::Tensor3_antisymmetric_Expr
Definition: Tensor3_antisymmetric_Expr.hpp:18
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::operator()
Tensor3_antisymmetric_Expr< Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >, T, Dim0, Dim12, i, j, k > operator()(const Index< i, Dim0 > index1, const Index< j, Dim12 > index2, const Index< k, Dim12 > index3)
Definition: Tensor3_antisymmetric_pointer.hpp:99
FTensor::Tensor3_antisymmetric
Definition: Tensor3_antisymmetric_value.hpp:8
i
FTensor::Index< 'i', SPACE_DIM > i
Definition: hcurl_divergence_operator_2d.cpp:27
FTensor::Index
Definition: Index.hpp:23
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::Tensor3_antisymmetric
Tensor3_antisymmetric(U *... d)
Definition: Tensor3_antisymmetric_pointer.hpp:14
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::unsafe
T & unsafe(const int N1, const int N2, const int N3)
Definition: Tensor3_antisymmetric_pointer.hpp:33
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::operator++
const Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 > & operator++() const
Definition: Tensor3_antisymmetric_pointer.hpp:123
j
FTensor::Index< 'j', 3 > j
Definition: matrix_function.cpp:19
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >
Definition: Tensor3_antisymmetric_pointer.hpp:8
k
FTensor::Index< 'k', 3 > k
Definition: matrix_function.cpp:20
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::operator()
Tensor3_antisymmetric_Expr< const Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >, T, Dim0, Dim12, i, j, k > operator()(const Index< i, Dim0 > index1, const Index< j, Dim12 > index2, const Index< k, Dim12 > index3) const
Definition: Tensor3_antisymmetric_pointer.hpp:111
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::Tensor3_antisymmetric
Tensor3_antisymmetric()
Definition: Tensor3_antisymmetric_pointer.hpp:21
EshelbianPlasticity::U
@ U
Definition: EshelbianContact.cpp:193
FTensor::Tensor3_antisymmetric< T *, Tensor_Dim0, Tensor_Dim12 >::ptr
T * ptr(const int N1, const int N2, const int N3) const
Definition: Tensor3_antisymmetric_pointer.hpp:71