Alamo
Matrix4_Full.H
Go to the documentation of this file.
1#ifndef SET_MATRIX4_FULL_H
2#define SET_MATRIX4_FULL_H
3#include "Util/Util.H"
4#include "Base.H"
5namespace Set
6{
7
8/// \brief Data structure for a symmetrix 4th order 3D tensor
9///
10/// Let the tensor
11/// \f$\mathbb{C}\in\mathbb{R}^3\times\mathbb{R}^3\times\mathbb{R}^3\times\mathbb{R}^3\f$
12/// be fully symmetrix such that \f$\mathbb{C}_{ijkl}=\mathbb{C}_{\sigma(i,j,k,l)\f$ where
13/// \f$\sigma\f$ is any permutation.
14/// Then there are only 5 (2D) or 15(3D) unique elements (rather than 81).
15///
16/// This object acts like a 4D array such that `C(i,j,k,l)` returns the corresponding
17/// element, but symmetry is always obeyed. This allows the user code to be much prettier.
18///
19
20template<>
21class Matrix4<2,Sym::Full>
22{
23 Scalar data[5] = {NAN,NAN,NAN,NAN,NAN};
24public:
28 Scalar & operator () (const int i, const int j, const int k, const int l)
29 {
30 int uid = i + 2*j + 4*k + 8*l;
31 // [0, 0, 0, 0]
32 if (uid==0 ) return data[0];
33 // [0, 0, 0, 1]
34 else if (uid==8 || uid==4 || uid==2 || uid==1 ) return data[1];
35 // [0, 0, 1, 1]
36 else if (uid==12 || uid==10 || uid==6 || uid==9 || uid==5 || uid==3 ) return data[2];
37 // [0, 1, 1, 1]
38 else if (uid==14 || uid==13 || uid==11 || uid==7 ) return data[3];
39 // [1, 1, 1, 1]
40 else if (uid==15 ) return data[4];
41 else Util::Abort(INFO,"Index out of range");
42 return data[0]; // this code is unreachable
43 }
44 Scalar operator () (const int i, const int j, const int k, const int l) const
45 {
46 int uid = i + 2*j + 4*k + 8*l;
47 // [0, 0, 0, 0]
48 if (uid==0 ) return data[0];
49 // [0, 0, 0, 1]
50 else if (uid==8 || uid==4 || uid==2 || uid==1 ) return data[1];
51 // [0, 0, 1, 1]
52 else if (uid==12 || uid==10 || uid==6 || uid==9 || uid==5 || uid==3 ) return data[2];
53 // [0, 1, 1, 1]
54 else if (uid==14 || uid==13 || uid==11 || uid==7 ) return data[3];
55 // [1, 1, 1, 1]
56 else if (uid==15 ) return data[4];
57 else Util::Abort(INFO,"Index out of range");
58 return data[0]; // this code is unreachable
59 }
61 {
63 for (int i = 0 ; i < 5; i++) ret.data[i] = Util::Random();
64 return ret;
65 }
66 void Print (std::ostream& /* os */)
67 {
68 Util::Abort(INFO,"Not yet implemented");
69 }
71 {
73 zero.data[0] = 0.0;
74 zero.data[1] = 0.0;
75 zero.data[2] = 0.0;
76 zero.data[3] = 0.0;
77 zero.data[4] = 0.0;
78 return zero;
79 }
80 bool contains_nan() const
81 {
82 if (std::isnan(data[0])) return true;
83 if (std::isnan(data[1])) return true;
84 if (std::isnan(data[2])) return true;
85 if (std::isnan(data[3])) return true;
86 if (std::isnan(data[4])) return true;
87 return false;
88 }
89};
90
91template<>
92class Matrix4<3,Sym::Full>
93{
94 Scalar data[15] = { NAN,NAN,NAN,NAN,NAN,
96 NAN,NAN,NAN,NAN,NAN};
97
98public:
102 Scalar & operator () (const int i, const int j, const int k, const int l)
103 {
104 int uid = i + 3*j + 9*k + 27*l;
105 // [0, 0, 0, 0]
106 if (uid==0 ) return data[0];
107 // [0, 0, 0, 1]
108 else if (uid==27 || uid==9 || uid==3 || uid==1 ) return data[1];
109 // [0, 0, 0, 2]
110 else if (uid==54 || uid==18 || uid==6 || uid==2 ) return data[2];
111 // [0, 0, 1, 1]
112 else if (uid==36 || uid==30 || uid==12 || uid==28 || uid==10 || uid==4 ) return data[3];
113 // [0, 0, 1, 2]
114 else if (uid==63 || uid==45 || uid==57 || uid==21 || uid==33 || uid==15 || uid==55 || uid==19 || uid==7 || uid==29 || uid==11 || uid==5 ) return data[4];
115 // [0, 0, 2, 2]
116 else if (uid==72 || uid==60 || uid==24 || uid==56 || uid==20 || uid==8 ) return data[5];
117 // [0, 1, 1, 1]
118 else if (uid==39 || uid==37 || uid==31 || uid==13 ) return data[6];
119 // [0, 1, 1, 2]
120 else if (uid==66 || uid==48 || uid==42 || uid==64 || uid==46 || uid==58 || uid==22 || uid==34 || uid==16 || uid==38 || uid==32 || uid==14 ) return data[7];
121 // [0, 1, 2, 2]
122 else if (uid==75 || uid==69 || uid==51 || uid==73 || uid==61 || uid==25 || uid==65 || uid==47 || uid==59 || uid==23 || uid==35 || uid==17 ) return data[8];
123 // [0, 2, 2, 2]
124 else if (uid==78 || uid==74 || uid==62 || uid==26 ) return data[9];
125 // [1, 1, 1, 1]
126 else if (uid==40 ) return data[10];
127 // [1, 1, 1, 2]
128 else if (uid==67 || uid==49 || uid==43 || uid==41 ) return data[11];
129 // [1, 1, 2, 2]
130 else if (uid==76 || uid==70 || uid==52 || uid==68 || uid==50 || uid==44 ) return data[12];
131 // [1, 2, 2, 2]
132 else if (uid==79 || uid==77 || uid==71 || uid==53 ) return data[13];
133 // [2, 2, 2, 2]
134 else if (uid==80 ) return data[14];
135 else Util::Abort(INFO,"uid not in range (uid=",uid,")");
136 return data[0]; // this return statement is unreachable.
137 }
138 Scalar operator () (const int i, const int j, const int k, const int l) const
139 {
140 int uid = i + 3*j + 9*k + 27*l;
141 // [0, 0, 0, 0]
142 if (uid==0 ) return data[0];
143 // [0, 0, 0, 1]
144 else if (uid==27 || uid==9 || uid==3 || uid==1 ) return data[1];
145 // [0, 0, 0, 2]
146 else if (uid==54 || uid==18 || uid==6 || uid==2 ) return data[2];
147 // [0, 0, 1, 1]
148 else if (uid==36 || uid==30 || uid==12 || uid==28 || uid==10 || uid==4 ) return data[3];
149 // [0, 0, 1, 2]
150 else if (uid==63 || uid==45 || uid==57 || uid==21 || uid==33 || uid==15 || uid==55 || uid==19 || uid==7 || uid==29 || uid==11 || uid==5 ) return data[4];
151 // [0, 0, 2, 2]
152 else if (uid==72 || uid==60 || uid==24 || uid==56 || uid==20 || uid==8 ) return data[5];
153 // [0, 1, 1, 1]
154 else if (uid==39 || uid==37 || uid==31 || uid==13 ) return data[6];
155 // [0, 1, 1, 2]
156 else if (uid==66 || uid==48 || uid==42 || uid==64 || uid==46 || uid==58 || uid==22 || uid==34 || uid==16 || uid==38 || uid==32 || uid==14 ) return data[7];
157 // [0, 1, 2, 2]
158 else if (uid==75 || uid==69 || uid==51 || uid==73 || uid==61 || uid==25 || uid==65 || uid==47 || uid==59 || uid==23 || uid==35 || uid==17 ) return data[8];
159 // [0, 2, 2, 2]
160 else if (uid==78 || uid==74 || uid==62 || uid==26 ) return data[9];
161 // [1, 1, 1, 1]
162 else if (uid==40 ) return data[10];
163 // [1, 1, 1, 2]
164 else if (uid==67 || uid==49 || uid==43 || uid==41 ) return data[11];
165 // [1, 1, 2, 2]
166 else if (uid==76 || uid==70 || uid==52 || uid==68 || uid==50 || uid==44 ) return data[12];
167 // [1, 2, 2, 2]
168 else if (uid==79 || uid==77 || uid==71 || uid==53 ) return data[13];
169 // [2, 2, 2, 2]
170 else if (uid==80 ) return data[14];
171 else Util::Abort(INFO,"uid not in range (uid=",uid,")");
172 return data[0]; // this return statement is unreachable.
173 }
174 void Print (std::ostream& os)
175 {
176 for (int i = 0; i < 14; i++)
177 os << "i = " << i << " " << data[i] << std::endl;
178
179 os.precision(4);
180 for (int k = 0; k < 3; k++)
181 {
182 for (int i = -1; i < 4; i++)
183 {
184 for (int l = 0; l < 3; l++)
185 {
186 if (i==-1) os << "┌ ┐ ";
187 else if (i == 3) os << "└ ┘ ";
188 else
189 {
190 os << "│ ";
191 for (int j = 0; j < 3; j++)
192 {
193 const Set::Scalar &val = (*this)(i,j,k,l);
194 os << std::scientific << std::setw(11) << val ; //(fabs(val)>1E-10 ? val : 0);
195 os << " ";
196 }
197 os << "│ ";
198 }
199 }
200 os<<std::endl;
201 }
202 }
203 }
205 {
207 for (int i = 0 ; i < 15; i++) ret.data[i] = (Set::Scalar)i;
208 return ret;
209 }
211 {
213 for (int i = 0 ; i < 15; i++) ret.data[i] = Util::Random();
214 return ret;
215 }
217 {
219 for (int i = 0 ; i < 15; i++) ret.data[i] = 0.0;
220 return ret;
221 }
222
223 bool contains_nan() const
224 {
225 if (std::isnan(data[ 0])) return true;
226 if (std::isnan(data[ 1])) return true;
227 if (std::isnan(data[ 2])) return true;
228 if (std::isnan(data[ 3])) return true;
229 if (std::isnan(data[ 4])) return true;
230 if (std::isnan(data[ 5])) return true;
231 if (std::isnan(data[ 6])) return true;
232 if (std::isnan(data[ 7])) return true;
233 if (std::isnan(data[ 8])) return true;
234 if (std::isnan(data[ 9])) return true;
235 if (std::isnan(data[10])) return true;
236 if (std::isnan(data[11])) return true;
237 if (std::isnan(data[12])) return true;
238 if (std::isnan(data[13])) return true;
239 if (std::isnan(data[14])) return true;
240 return false;
241 }
242
243};
244std::ostream&
245operator<< (std::ostream& os, const Matrix4<3,Sym::Full>& b);
246}
247#endif
#define INFO
Definition Util.H:20
static Matrix4< 2, Sym::Full > Zero()
AMREX_GPU_HOST_DEVICE Matrix4()
static Matrix4< 2, Sym::Full > Randomize()
void Print(std::ostream &)
void Print(std::ostream &os)
static Matrix4< 3, Sym::Full > Zero()
AMREX_GPU_HOST_DEVICE Matrix4()
static Matrix4< 3, Sym::Full > Randomize()
static Matrix4< 3, Sym::Full > Increment()
A collection of data types and symmetry-reduced data structures.
Definition Base.H:18
Sym
Definition Base.H:197
@ Full
Definition Base.H:197
amrex::Real Scalar
Definition Base.H:19
Eigen::Matrix< amrex::Real, AMREX_SPACEDIM, 1 > Vector
Definition Base.H:20
std::ostream & operator<<(std::ostream &os, const Matrix4< dim, sym > &b)
Definition Base.H:201
void Abort(const char *msg)
Definition Util.cpp:170
Set::Scalar Random()
Definition Set.cpp:9