High Performance Plasticity  0.5.0
gsh.h
Go to the documentation of this file.
1 #ifndef HPP_GSH_H
5 #define HPP_GSH_H
6 
7 #include <hpp/config.h>
8 #include <cmath>
9 #include <complex>
10 
11 namespace hpp
12 {
13 
26 template <typename T>
27 class GSHCoeffs {
28  public:
30  for (int i=0; i<nl0; i++) {
31  l0[i].real(0.0);
32  l0[i].imag(0.0);
33  }
34  for (int i=0; i<nl1; i++) {
35  l1[i].real(0.0);
36  l1[i].imag(0.0);
37  }
38  for (int i=0; i<nl2; i++) {
39  l2[i].real(0.0);
40  l2[i].imag(0.0);
41  }
42  for (int i=0; i<nl3; i++) {
43  l3[i].real(0.0);
44  l3[i].imag(0.0);
45  }
46  for (int i=0; i<nl4; i++) {
47  l4[i].real(0.0);
48  l4[i].imag(0.0);
49  }
50  }
51 
52  bool isInSymmetrizedSection(int l, int m, int n) {
53  int L = 2*l+1;
54  int nElements = (L*L+1)/2;
55  int mIdx = m+l;
56  int nIdx = n+l;
57  if (mIdx*L + nIdx > nElements-1) {
58  return true;
59  }
60  else {
61  return false;
62  }
63  }
64 
65  unsigned int getFlatIdx(int l, int m, int n) {
66  // If lower triangular, switch to upper triangular section
67  if (this->isInSymmetrizedSection(l,m,n)) {
68  n = -n;
69  m = -m;
70  }
71  unsigned int mIdx = m+l;
72  unsigned int nIdx = n+l;
73 
74  // mIdx and nIdx are indices in an LxL matrix
75  unsigned int L = 2*l+1;
76 
77  // Return
78  return mIdx*L + nIdx;
79  }
80 
81  std::complex<T> get(int l, int m, int n) {
82  unsigned int flatIdx = this->getFlatIdx(l,m,n);
83 
84  // Fetch the value
85  std::complex<T> val;
86  switch (l) {
87  case 0:
88  val = l0[flatIdx];
89  break;
90  case 1:
91  val = l1[flatIdx];
92  break;
93  case 2:
94  val = l2[flatIdx];
95  break;
96  case 3:
97  val = l3[flatIdx];
98  break;
99  case 4:
100  val = l4[flatIdx];
101  break;
102  default:
103  throw std::runtime_error("No implementation for l>4");
104  }
105 
106  // Modify for symmetry if in symmetrized section
107  if (this->isInSymmetrizedSection(l,m,n)) {
108  std::complex<T> mult;
109  mult.real(std::pow(-1.0, m+n));
110  mult.imag(0.0);
111  val = mult*std::conj(val);
112  }
113 
114  // Return
115  return val;
116 
117  }
118 
119  void set(int l, int m, int n, std::complex<T> val) {
120  unsigned int flatIdx = this->getFlatIdx(l,m,n);
121 
122  // Modify for symmetry if in symmetrized section
123  if (this->isInSymmetrizedSection(l,m,n)) {
124  std::complex<T> mult;
125  mult.real(std::pow(-1.0, m+n));
126  mult.imag(0.0);
127  val = mult*std::conj(val);
128  }
129 
130  // Set value
131  switch (l) {
132  case 0:
133  l0[flatIdx] = val;
134  break;
135  case 1:
136  l1[flatIdx] = val;
137  break;
138  case 2:
139  l2[flatIdx] = val;
140  break;
141  case 3:
142  l3[flatIdx] = val;
143  break;
144  case 4:
145  l4[flatIdx] = val;
146  break;
147  default:
148  throw std::runtime_error("No implementation for l>4");
149  }
150  }
151 
152  std::vector<T> getl0Reals() {
153  std::vector<T> vals(2*nl0);
154  for (int i=0; i<nl0; i++) {
155  vals[2*i] = l0[i].real();
156  vals[2*i+1] = l0[i].imag();
157  }
158  return vals;
159  }
160 
161  std::vector<T> getl1Reals() {
162  std::vector<T> vals(2*nl1);
163  for (int i=0; i<nl1; i++) {
164  vals[2*i] = l1[i].real();
165  vals[2*i+1] = l1[i].imag();
166  }
167  return vals;
168  }
169 
170  std::vector<T> getl2Reals() {
171  std::vector<T> vals(2*nl2);
172  for (int i=0; i<nl2; i++) {
173  vals[2*i] = l2[i].real();
174  vals[2*i+1] = l2[i].imag();
175  }
176  return vals;
177  }
178 
179  std::vector<T> getl3Reals() {
180  std::vector<T> vals(2*nl3);
181  for (int i=0; i<nl3; i++) {
182  vals[2*i] = l3[i].real();
183  vals[2*i+1] = l3[i].imag();
184  }
185  return vals;
186  }
187 
188  std::vector<T> getl4Reals() {
189  std::vector<T> vals(2*nl4);
190  for (int i=0; i<nl4; i++) {
191  vals[2*i] = l4[i].real();
192  vals[2*i+1] = l4[i].imag();
193  }
194  return vals;
195  }
196 
197  int nl0 = 2*0*(0+1)+1;
198  int nl1 = 2*1*(1+1)+1;
199  int nl2 = 2*2*(2+1)+1;
200  int nl3 = 2*3*(3+1)+1;
201  int nl4 = 2*4*(4+1)+1;
202  std::complex<T> l0[2*0*(0+1)+1];
203  std::complex<T> l1[2*1*(1+1)+1];
204  std::complex<T> l2[2*2*(2+1)+1];
205  std::complex<T> l3[2*3*(3+1)+1];
206  std::complex<T> l4[2*4*(4+1)+1];
207 };
208 
209 template <typename T>
210 GSHCoeffs<T> operator+(const GSHCoeffs<T>& coeffs1, const GSHCoeffs<T>& coeffs2) {
211  GSHCoeffs<T> res;
212  for (int i=0; i<res.nl0; i++) {
213  res.l0[i] = coeffs1.l0[i]+coeffs2.l0[i];
214  }
215  for (int i=0; i<res.nl1; i++) {
216  res.l1[i] = coeffs1.l1[i]+coeffs2.l1[i];
217  }
218  for (int i=0; i<res.nl2; i++) {
219  res.l2[i] = coeffs1.l2[i]+coeffs2.l2[i];
220  }
221  for (int i=0; i<res.nl3; i++) {
222  res.l3[i] = coeffs1.l3[i]+coeffs2.l3[i];
223  }
224  for (int i=0; i<res.nl4; i++) {
225  res.l4[i] = coeffs1.l4[i]+coeffs2.l4[i];
226  }
227  return res;
228 }
229 
230 template <typename T>
232  A = A+B;
233 }
234 
235 template <typename T>
236 GSHCoeffs<T> operator/(const GSHCoeffs<T>& coeffs, const T val) {
237  GSHCoeffs<T> res;
238  for (int i=0; i<res.nl0; i++) {
239  res.l0[i] = coeffs.l0[i]/val;
240  }
241  for (int i=0; i<res.nl1; i++) {
242  res.l1[i] = coeffs.l1[i]/val;
243  }
244  for (int i=0; i<res.nl2; i++) {
245  res.l2[i] = coeffs.l2[i]/val;
246  }
247  for (int i=0; i<res.nl3; i++) {
248  res.l3[i] = coeffs.l3[i]/val;
249  }
250  for (int i=0; i<res.nl4; i++) {
251  res.l4[i] = coeffs.l4[i]/val;
252  }
253  return res;
254 }
255 
256 template <typename T>
257 void operator/=(GSHCoeffs<T>& A, const T B) {
258  A = A/B;
259 }
260 
261 } //END NAMESPACE HPP
262 #endif /* HPP_GSH_H */
std::complex< T > l2[2 *2 *(2+1)+1]
Definition: gsh.h:204
void operator+=(GSHCoeffs< T > &A, const GSHCoeffs< T > &B)
Definition: gsh.h:231
unsigned int getFlatIdx(int l, int m, int n)
Definition: gsh.h:65
int nl2
Definition: gsh.h:199
void operator/=(GSHCoeffs< T > &A, const T B)
Definition: gsh.h:257
Definition: casesUtils.cpp:4
std::complex< T > l1[2 *1 *(1+1)+1]
Definition: gsh.h:203
std::vector< T > getl1Reals()
Definition: gsh.h:161
GSHCoeffs< T > operator/(const GSHCoeffs< T > &coeffs, const T val)
Definition: gsh.h:236
std::complex< T > l4[2 *4 *(4+1)+1]
Definition: gsh.h:206
bool isInSymmetrizedSection(int l, int m, int n)
Definition: gsh.h:52
Definition: gsh.h:27
std::vector< T > getl4Reals()
Definition: gsh.h:188
std::complex< T > l0[2 *0 *(0+1)+1]
Definition: gsh.h:202
std::vector< T > getl0Reals()
Definition: gsh.h:152
int nl1
Definition: gsh.h:198
int nl0
Definition: gsh.h:197
std::vector< T > getl2Reals()
Definition: gsh.h:170
GSHCoeffs()
Definition: gsh.h:29
std::complex< T > l3[2 *3 *(3+1)+1]
Definition: gsh.h:205
std::vector< T > getl3Reals()
Definition: gsh.h:179
GSHCoeffs< T > operator+(const GSHCoeffs< T > &coeffs1, const GSHCoeffs< T > &coeffs2)
Definition: gsh.h:210
int nl3
Definition: gsh.h:200
int nl4
Definition: gsh.h:201