Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__COMMON__MATH_TENSOR__
34 : #define __H__COMMON__MATH_TENSOR__
35 :
36 : #include <cstddef>
37 : #include <iostream>
38 : #include "../../types.h"
39 :
40 : namespace ug
41 : {
42 :
43 : ////////////////////////////////////////////////////////////////////////
44 : // MathTensor
45 : /**
46 : * \defgroup math_tensor Tensor
47 : * \ingroup ugbase_math
48 : * \{
49 : */
50 :
51 : /// a mathematical Tensor of rank TRank and N entries.
52 : template <size_t TRank, size_t N, typename T = number> class MathTensor;
53 :
54 : template <size_t TRank, size_t N, typename T>
55 : class MathTensor
56 : {
57 : public:
58 : // type of value
59 : typedef MathTensor<TRank-1, N, T> value_type;
60 :
61 : // size type
62 : typedef size_t size_type;
63 :
64 : // Dimension of tensor
65 : static const size_t Dimension = N;
66 :
67 : // Rank of tensor (i.e. number of indices)
68 : static const size_t Rank = TRank;
69 :
70 : public:
71 0 : MathTensor() {}
72 0 : MathTensor(const MathTensor& v) {assign(v);}
73 :
74 : // operations with other vectors
75 : MathTensor& operator= (const MathTensor& v)
76 : {
77 0 : if(this != &v){assign(v);}
78 : return *this;
79 : }
80 :
81 : inline size_t size() const {return N;}
82 : inline size_t rank() const {return TRank;}
83 :
84 : /// sets all values of the tensor to a value
85 : MathTensor& operator=(T val) {set(val); return *this;}
86 0 : inline void set(T val) {for(size_t i = 0; i < N; ++i) m_data[i].set(val);}
87 :
88 : inline value_type& operator[](size_t i) {UG_ASSERT(i < size(), "Index out of range."); return m_data[i];}
89 0 : inline const value_type& operator[](size_t i) const {UG_ASSERT(i < size(), "Index out of range."); return m_data[i];}
90 :
91 : protected:
92 0 : inline void assign(const MathTensor<TRank, N, T>& v){for(size_t i = 0; i < N; ++i) m_data[i] = v[i];}
93 :
94 : protected:
95 : value_type m_data[N];
96 : };
97 :
98 :
99 : template <size_t N, typename T>
100 : class MathTensor<1, N, T>
101 : {
102 : public:
103 : // type of value
104 : typedef T value_type;
105 :
106 : // size type
107 : typedef size_t size_type;
108 :
109 : // Dimension of tensor
110 : static const size_t Dimension = N;
111 :
112 : // Rank of tensor (i.e. number of indices)
113 : static const size_t Rank = 1;
114 :
115 : public:
116 0 : MathTensor(const bool init = true) { if(init) set(0.0);}
117 : MathTensor(const MathTensor& v) {assign(v);}
118 :
119 : // operations with other vectors
120 : MathTensor& operator= (const MathTensor& v)
121 : {
122 0 : if(this != &v){assign(v);}
123 : return *this;
124 : }
125 :
126 : inline size_t size() const {return N;}
127 : inline size_t rank() const {return 1;}
128 :
129 : /// sets all values of the tensor to a value
130 : MathTensor& operator=(T val) {set(val); return *this;}
131 0 : inline void set(T val) {for(size_t i = 0; i < N; ++i) m_data[i] = val;}
132 :
133 : inline value_type& operator[](size_t i) {UG_ASSERT(i < size(), "Index out of range."); return m_data[i];}
134 : inline const value_type& operator[](size_t i) const {UG_ASSERT(i < size(), "Index out of range."); return m_data[i];}
135 :
136 : protected:
137 0 : inline void assign(const MathTensor<1, N, T>& v) {for(size_t i = 0; i < N; ++i) m_data[i] = v[i];}
138 :
139 : protected:
140 : value_type m_data[N];
141 : };
142 :
143 : template <size_t TRank, size_t N, typename T>
144 0 : std::ostream& operator<< (std::ostream& outStream, const ug::MathTensor<TRank, N, T>& v)
145 : {
146 0 : outStream << "[";
147 0 : for(size_t i = 0; i < v.size()-1; ++i)
148 0 : outStream << v[i] << ", ";
149 0 : outStream << v[v.size()-1] << "]";
150 0 : return outStream;
151 : }
152 :
153 : /////////////////////////////////////////////////////////////////////////////////////////////////////////
154 :
155 : // unfortunately, not all tensor are like 3x3x3x3, but also 3x2x3x2.
156 : // merge this if possible with MathVector<MathVector<2> > ?
157 :
158 : template <typename TEntry, size_t N>
159 : class MathTensorX
160 : {
161 : public:
162 : // type of value
163 : typedef TEntry value_type;
164 :
165 : // size type
166 : typedef size_t size_type;
167 :
168 : // Dimension of tensor
169 : static const size_t Dimension = N;
170 :
171 : // Rank of tensor (i.e. number of indices)
172 : static const size_t Rank = TEntry::Rank+1;
173 :
174 : public:
175 : MathTensorX() { }
176 : MathTensorX(const MathTensorX& v) {assign(v);}
177 :
178 : // operations with other vectors
179 : MathTensorX& operator= (const MathTensorX& v)
180 : {
181 : if(this != &v){assign(v);}
182 : return *this;
183 : }
184 :
185 : inline size_t size() const {return N;}
186 : inline size_t rank() const {return Rank;}
187 :
188 : inline value_type& operator[](size_t i) {UG_ASSERT(i < size(), "Index out of range."); return m_data[i];}
189 : inline const value_type& operator[](size_t i) const {UG_ASSERT(i < size(), "Index out of range."); return m_data[i];}
190 :
191 : protected:
192 : inline void assign(const MathTensorX<TEntry, N>& v) {for(size_t i = 0; i < N; ++i) m_data[i] = v[i];}
193 :
194 : protected:
195 : TEntry m_data[N];
196 : };
197 :
198 : template <size_t N, typename T = number>
199 : class MathTensor1 : public MathTensor<1, N, T> { };
200 :
201 : template <size_t N1, size_t N2, typename T = number>
202 : class MathTensor2 : public MathTensorX<MathTensor1<N2, T>, N1> { };
203 :
204 : template <size_t N1, size_t N2, size_t N3, typename T = number>
205 : class MathTensor3 : public MathTensorX< MathTensorX<MathTensor1<N3, T>, N2>, N1> { };
206 :
207 : template <size_t N1, size_t N2, size_t N3, size_t N4, typename T = number>
208 : class MathTensor4 : public MathTensorX< MathTensorX< MathTensorX<MathTensor1<N4, T>, N3>, N2>, N1> { };
209 :
210 : template <typename TEntry>
211 : std::ostream& operator<< (std::ostream& outStream, const ug::MathTensorX<TEntry, 1>& v)
212 : {
213 : outStream << "[";
214 : outStream << v[0] << "]";
215 : return outStream;
216 : }
217 :
218 : template <typename TEntry, size_t N>
219 : std::ostream& operator<< (std::ostream& outStream, const ug::MathTensorX<TEntry, N>& v)
220 : {
221 : outStream << "[";
222 : for(size_t i = 0; i < N-1; ++i)
223 : outStream << v[i] << ", ";
224 : outStream << v[N-1] << "]";
225 : return outStream;
226 : }
227 :
228 : // end group math_tensor
229 : /// \}
230 :
231 : }// end of namespace
232 :
233 :
234 : #endif /* __H__COMMON__MATH_MathVector__ */
|