valib
Vortex Analysis LIBrary
corotation_common.h
1 
5 #ifndef VA_COROTATION_COMMON_H
6 #define VA_COROTATION_COMMON_H
7 
8 #include "common_defs.h"
9 #include "linalg3.h"
10 #include "spherical_integrators.h"
11 
12 /***************************************************************************/
17 /***************************************************************************/
23 VA_DEVICE_FUN void valib_resvortstrain2D(VA_REAL *SO,
24  VA_REAL *residual_vorticity,
25  VA_REAL *residual_strain,
26  VA_REAL *principal_axis)
27 {
28  VA_REAL S_D_11, S_D_12;
29  VA_REAL vort;
30  VA_REAL as_D;
31  VA_REAL length;
32 
33  // omega
34  vort = (SO[1] - SO[3]) / 2.;
35 
36  // values of the S_D tensor - deviatoric symmetric part of nabla u
37  S_D_11 = 0.5 * (SO[0] - SO[4]);
38  S_D_12 = 0.5 * (SO[1] + SO[3]);
39 
40  // |s_D| - positive eigenvalue of deviatoric strain-rate tensor S_D
41  // version from the paper
42  // as_D = sqrt ( (SO[0] - SO[4])*(SO[0] - SO[4])
43  // +(SO[1] + SO[3])*(SO[1] + SO[3])) / 2.;
44  // using intermediate values
45  as_D = sqrt( S_D_12 * S_D_12 + S_D_11 * S_D_11 );
46 
47  // try to use the first row for determining the eigenvector
48  length = sqrt(((S_D_11 - as_D)*(S_D_11 - as_D) ) + (S_D_12 * S_D_12));
49  if (length >= (VA_REAL) 1.e-5) {
50  // diagonal is not an eigenvalue
51  principal_axis[0] = S_D_12 / length;
52  principal_axis[1] = - (S_D_11 - as_D) / length;
53  }
54  else {
55  // try to use the second row for determining the eigenvector
56  length = sqrt(((-S_D_11 - as_D)*(-S_D_11 - as_D))
57  +( S_D_12 * S_D_12 ) );
58  if (length >= (VA_REAL) 1.e-5) {
59  principal_axis[0] = (S_D_11 + as_D) / length;
60  principal_axis[1] = S_D_12 / length;
61  }
62  else {
63  // the matrix contains just zeros, 0 is a multiple eigenvalue and any
64  // vector is an eigenvector
65  principal_axis[0] = (VA_REAL) 1.;
66  principal_axis[1] = (VA_REAL) 0.;
67  }
68  }
69 
70  // omega_res and s_res
71  if (fabs (vort) >= as_D) {
72  *residual_vorticity = valib_sign( fabs(vort) - as_D,vort );
73  *residual_strain = (VA_REAL) 0.;
74  }
75  else {
76  *residual_vorticity = (VA_REAL) 0.;
77  *residual_strain = as_D - fabs(vort);
78  }
79 }
80 
81 /***************************************************************************/
88 /***************************************************************************/
94 VA_DEVICE_FUN void valib_integrand_resvort(VA_REAL *n, VA_REAL *weight,
95  VA_DEVICE_ADDR VA_REAL *A,
96  VA_DEVICE_ADDR VA_REAL *avgcorot)
97 {
98 #if defined(CUDA)
99  // put Q into shared memory
100  extern __shared__ VA_REAL s_data[];
101  VA_REAL *Q = &s_data[0];
102 #elif defined(OPENCL)
103  // put Q into shared memory
104  __private VA_REAL Q[9];
105 #else
106  VA_REAL Q[9]; // orthogonal matrices of transformations
107 #endif
108 
109  VA_REAL SO[9]; // symmetric (upper triangle) and antisymmetric (lower
110  // triangle) parts of velocity gradient
111 
112  VA_REAL vort_res, s_res, principal_axis[3];
113 
114  VA_REAL sina, cosa;
115  VA_REAL sinb, cosb;
116 
117  cosb = n[2];
118  sinb = sqrt(1. - cosb*cosb); // this is safe, points are never 0
119  sina = n[1] / sinb;
120  cosa = n[0] / sinb;
121 
122  // generate matrix Q
123 #if defined(CUDA)
124  if (threadIdx.x == 0) {
125 #elif defined(OPENCL)
126  if (get_local_id(0) == 0) {
127 #endif
128  valib_constructQ3(sina, cosa, sinb, cosb, 0., 1., Q);
129 #if defined(CUDA)
130  }
131  __syncthreads();
132 #elif defined(OPENCL)
133  }
134  barrier(CLK_LOCAL_MEM_FENCE);
135 #endif
136 
137  // SO = QAQ^T
138  valib_tatt3(A, Q, SO);
139 
140  // get residual vorticity in 2D
141  valib_resvortstrain2D(SO, &vort_res, &s_res, principal_axis);
142  // previous function only works on first two entries, correct the third
143  principal_axis[2] = 0.;
144 
145  // add contribution to the surface integral in spherical coordinates
146  avgcorot[0] = avgcorot[0] + 6. * ( vort_res * n[0] ) * *weight;
147  avgcorot[1] = avgcorot[1] + 6. * ( vort_res * n[1] ) * *weight;
148  avgcorot[2] = avgcorot[2] + 6. * ( vort_res * n[2] ) * *weight;
149 
150 #if defined(CUDA)
151  __syncthreads();
152 #elif defined(OPENCL)
153  barrier(CLK_LOCAL_MEM_FENCE);
154 #endif
155 }
156 
157 /***************************************************************************/
163 VA_DEVICE_FUN void valib_integrand_resstrain(VA_REAL *n, VA_REAL *weight,
164  VA_DEVICE_ADDR VA_REAL *A,
165  VA_DEVICE_ADDR VA_REAL *S_RAVG)
166 {
167  int i;
168 
169 #if defined(CUDA)
170  // put Q into shared memory
171  extern __shared__ VA_REAL s_data[];
172  VA_REAL *Q = &s_data[0];
173 #elif defined(OPENCL)
174  // put Q into shared memory
175  __private VA_REAL Q[9];
176 #else
177  VA_REAL Q[9]; // orthogonal matrices of transformations
178 #endif
179 
180  VA_REAL SO[9]; // symmetric (upper triangle) and antisymmetric (lower
181  // triangle) parts of velocity gradient
182 
183  VA_REAL localResStrain[9]; // tensor of residual strain returned
184  // to original coordinate system
185 
186  VA_REAL vort_res, s_res, principal_axis[3];
187 
188  VA_REAL sina, cosa;
189  VA_REAL sinb, cosb;
190 
191  cosb = n[2];
192  sinb = sqrt(1. - cosb*cosb); // this is safe, points are never 0
193  sina = n[1] / sinb;
194  cosa = n[0] / sinb;
195 
196  // generate matrix Q
197 #if defined(CUDA)
198  if (threadIdx.x == 0) {
199 #elif defined(OPENCL)
200  if (get_local_id(0) == 0) {
201 #endif
202  valib_constructQ3(sina, cosa, sinb, cosb, 0., 1., Q);
203 #if defined(CUDA)
204  }
205  __syncthreads();
206 #elif defined(OPENCL)
207  }
208  barrier(CLK_LOCAL_MEM_FENCE);
209 #endif
210 
211  // SO = QAQ^T
212  valib_tatt3(A, Q, SO);
213 
214  // get residual strain in 2D
215  valib_resvortstrain2D(SO, &vort_res, &s_res, principal_axis);
216  // previous function only works on first two entries
217  principal_axis[2] = 0.;
218 
219  // now use SO to transform residual strain back
220  for (i = 0; i < 9; i++) {
221  SO[i] = (VA_REAL) 0.;
222  }
223  valib_rank1_update3(s_res, principal_axis, principal_axis, SO);
224  // do the same for the second eigenvalue
225  s_res = -s_res;
226  principal_axis[2] = principal_axis[0]; // to tmp
227  principal_axis[0] = -principal_axis[1]; // orthogonal vector to [v1, v2]
228  // in 2D is [-v2, v1]
229  principal_axis[1] = principal_axis[2]; // from tmp
230  principal_axis[2] = (VA_REAL) 0.; // correct tmp
231  valib_rank1_update3(s_res, principal_axis, principal_axis, SO);
232 
233  // transpose Q to multiply with it back
234 #if defined(CUDA)
235  __syncthreads();
236  if (threadIdx.x == 0) {
237 #elif defined(OPENCL)
238  if (get_local_id(0) == 0) {
239 #endif
240  valib_transpose3(Q);
241 #if defined(CUDA)
242  }
243  __syncthreads();
244 #elif defined(OPENCL)
245  }
246  barrier(CLK_LOCAL_MEM_FENCE);
247 #endif
248 
249  // result = Q^T*SO*Q
250  valib_tatt3(SO, Q, localResStrain);
251 
252  // add contribution to the surface integral in spherical coordinates
253  for (i = 0; i < 9; i++) {
254  S_RAVG[i] = S_RAVG[i] + (VA_REAL) 2.5 * localResStrain[i] * *weight;
255  }
256 
257 #if defined(CUDA)
258  __syncthreads();
259 #elif defined(OPENCL)
260  barrier(CLK_LOCAL_MEM_FENCE);
261 #endif
262 }
263 
264 /***************************************************************************/
269 VA_DEVICE_FUN void valib_integrand_surface(VA_REAL *n, VA_REAL *weight,
270  VA_DEVICE_ADDR VA_REAL *A,
271  VA_DEVICE_ADDR VA_REAL *result)
272 {
273  result[0] = result[0] + *weight;
274 }
275 
276 /***************************************************************************/
280 #endif // VA_COROTATION_COMMON_H
valib_tatt3
VA_DEVICE_FUN void valib_tatt3(VA_REAL *A, VA_REAL *T, VA_REAL *TATT)
Definition: linalg3.h:406
valib_integrand_resvort
VA_DEVICE_FUN void valib_integrand_resvort(VA_REAL *n, VA_REAL *weight, VA_DEVICE_ADDR VA_REAL *A, VA_DEVICE_ADDR VA_REAL *avgcorot)
Definition: corotation_common.h:94
valib_sign
VA_DEVICE_FUN VA_REAL valib_sign(VA_REAL a, VA_REAL b)
Definition: linalg3.h:20
valib_transpose3
VA_DEVICE_FUN void valib_transpose3(VA_REAL *A)
Definition: linalg3.h:307
valib_resvortstrain2D
VA_DEVICE_FUN void valib_resvortstrain2D(VA_REAL *SO, VA_REAL *residual_vorticity, VA_REAL *residual_strain, VA_REAL *principal_axis)
Definition: corotation_common.h:23
valib_rank1_update3
VA_DEVICE_FUN void valib_rank1_update3(VA_REAL alpha, VA_REAL *x, VA_REAL *y, VA_REAL *A)
Definition: linalg3.h:383
valib_integrand_surface
VA_DEVICE_FUN void valib_integrand_surface(VA_REAL *n, VA_REAL *weight, VA_DEVICE_ADDR VA_REAL *A, VA_DEVICE_ADDR VA_REAL *result)
Definition: corotation_common.h:269
valib_integrand_resstrain
VA_DEVICE_FUN void valib_integrand_resstrain(VA_REAL *n, VA_REAL *weight, VA_DEVICE_ADDR VA_REAL *A, VA_DEVICE_ADDR VA_REAL *S_RAVG)
Definition: corotation_common.h:163
valib_constructQ3
VA_DEVICE_FUN void valib_constructQ3(VA_REAL sina, VA_REAL cosa, VA_REAL sinb, VA_REAL cosb, VA_REAL sing, VA_REAL cosg, VA_REAL *Q)
Definition: linalg3.h:743