valib
Vortex Analysis LIBrary
Loading...
Searching...
No Matches
triple_decomposition.h
Go to the documentation of this file.
1
5#ifndef VA_TRIPLE_DECOMPOSITION_H
6#define VA_TRIPLE_DECOMPOSITION_H
7
8#include "common_defs.h"
9#include "linalg3.h"
10
11/***************************************************************************/
16/***************************************************************************/
38VA_DEVICE_FUN void valib_get_brf(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals,
39 VA_REAL *alpha_brf,
40 VA_REAL *beta_brf,
41 VA_REAL *gamma_brf,
42 VA_REAL *goal_brf)
43{
44 int ialpha, ibeta, igamma;
45
46#if defined(CUDA)
47 // put Q into shared memory
48 extern __shared__ VA_REAL s_data[];
49 VA_REAL *Q = &s_data[0];
50#else
51 VA_REAL Q[9]; // orthogonal matrices of transformations
52#endif
53 VA_REAL SO[9]; // symmetric (upper triangle) and antisymmetric (lower
54 // triangle) parts of velocity gradient
55
56 VA_REAL alpha, beta, gamma; // rotation angles
57 VA_REAL sina, cosa; // sin(alpha), cos(alpha)
58 VA_REAL sinb, cosb; // sin(beta), cos(beta)
59 VA_REAL sing, cosg; // sin(gamma), cos(gamma)
60 VA_REAL goal_function;
61
62 // compute stepSize in radians
63 VA_REAL stepSize = VA_PI / (VA_REAL) *num_intervals;
64
65 // initialize optimal angles
66 *alpha_brf = 0.;
67 *beta_brf = 0.;
68 *gamma_brf = 0.;
69
70 // initialize maxima
71 *goal_brf = 0.;
72
73
74 // perform search over all combinations of spherical coordinates
75 for (ialpha = 0; ialpha < *num_intervals + 1; ialpha++) {
76 alpha = ialpha*stepSize; // alpha in [0,pi]
77#if defined(CUDA)
78 sincos(alpha, &sina, &cosa);
79#else
80 sina = sin(alpha);
81 cosa = cos(alpha);
82#endif
83 for (ibeta = 0; ibeta < *num_intervals + 1; ibeta++) {
84 beta = ibeta*stepSize; // beta in [0,pi]
85#if defined(CUDA)
86 sincos(beta, &sinb, &cosb);
87#else
88 sinb = sin(beta);
89 cosb = cos(beta);
90#endif
91 for (igamma = 0; igamma < *num_intervals / 2 + 1; igamma++) {
92 gamma = igamma*stepSize; // gamma in [0,pi/2]
93#if defined(CUDA)
94 sincos(gamma, &sing, &cosg);
95#else
96 sing = sin(gamma);
97 cosg = cos(gamma);
98#endif
99
100 // generate matrix Q
101#if defined(CUDA)
102 __syncthreads();
103 if (threadIdx.x == 0) {
104#endif
105 valib_constructQ3(sina, cosa, sinb, cosb, sing, cosg, Q);
106#if defined(CUDA)
107 }
108 __syncthreads();
109#endif
110 // SO = QAQ^T
111 valib_tatt3(A, Q, SO);
112
113 // get residual vorticity in 2D
115
116 // evaluate the goal function
117 goal_function = fabs(SO[1]*SO[3])
118 + fabs(SO[2]*SO[6])
119 + fabs(SO[5]*SO[7]);
120
121 // update maxima
122 if (goal_function > *goal_brf) {
123 *alpha_brf = alpha;
124 *beta_brf = beta;
125 *gamma_brf = gamma;
126
127 *goal_brf = goal_function;
128 }
129 }
130 }
131 }
132}
133
134/***************************************************************************/
192 VA_DEVICE_ADDR VA_REAL *A,
193 int *num_intervals,
194 VA_DEVICE_ADDR VA_REAL *residual_vorticity_strain,
195 VA_DEVICE_ADDR VA_REAL *shear_vorticity_strain,
196 VA_DEVICE_ADDR VA_REAL *alpha,
197 VA_DEVICE_ADDR VA_REAL *beta,
198 VA_DEVICE_ADDR VA_REAL *gamma
199)
200{
201 VA_REAL Q[9]; // orthogonal matrices of
202 // transformations
203 VA_REAL QAQT[9]; // transformed gradient QAQ^T
204 VA_REAL alpha_brf, beta_brf, gamma_brf; // angles of basic reference
205 // frame (BRF)
206 VA_REAL goal_brf; // value of the shear scalar in BRF
207 VA_REAL sina, cosa; // sin(alpha), cos(alpha)
208 VA_REAL sinb, cosb; // sin(beta), cos(beta)
209 VA_REAL sing, cosg; // sin(gamma), cos(gamma)
210
211 int i;
212 VA_REAL aux;
213
214 // find BRF angles
215 valib_get_brf(A, num_intervals, &alpha_brf, &beta_brf, &gamma_brf, &goal_brf);
216
217 // Fill output variables with the results
218 *alpha = alpha_brf;
219 *beta = beta_brf;
220 *gamma = gamma_brf;
221
222#if defined(CUDA)
223 sincos(alpha_brf, &sina, &cosa);
224 sincos(beta_brf, &sinb, &cosb);
225 sincos(gamma_brf, &sing, &cosg);
226#else
227 sina = sin(alpha_brf);
228 cosa = cos(alpha_brf);
229 sinb = sin(beta_brf);
230 cosb = cos(beta_brf);
231 sing = sin(gamma_brf);
232 cosg = cos(gamma_brf);
233#endif
234
235 // generate matrix Q (this call is not shared for CUDA because this time,
236 // each thread has different Q)
237 valib_constructQ3(sina, cosa, sinb, cosb, sing, cosg, Q);
238
239 // QAQ^T
240 valib_tatt3(A, Q, QAQT);
241
242 // Construct the residual tensor.
243 // diagonal entries of the residual tensor are just copied
244 for (i = 0; i < 3; i++) {
245 residual_vorticity_strain[i*3+i] = QAQT[i*3+i];
246 }
247 // Find the residual vorticity and shear inside SO - filter out shear stress
248 aux = valib_min(fabs(QAQT[3]), fabs(QAQT[1]));
249 residual_vorticity_strain[3] = valib_sign(aux, QAQT[3]);
250 residual_vorticity_strain[1] = valib_sign(aux, QAQT[1]);
251
252 aux = valib_min(fabs(QAQT[6]), fabs(QAQT[2]));
253 residual_vorticity_strain[6] = valib_sign(aux, QAQT[6]);
254 residual_vorticity_strain[2] = valib_sign(aux, QAQT[2]);
255
256 aux = valib_min(fabs(QAQT[7]), fabs(QAQT[5]));
257 residual_vorticity_strain[7] = valib_sign(aux, QAQT[7]);
258 residual_vorticity_strain[5] = valib_sign(aux, QAQT[5]);
259
260 // Construct the shear tensor as QAQT - residual tensor
261 for (i = 0; i < 9; i++) {
262 shear_vorticity_strain[i] = QAQT[i] - residual_vorticity_strain[i];
263 }
264
265 // Return to the original coordinate frame by applying the
266 // inverse transformation
267 valib_ttat3(residual_vorticity_strain, Q, QAQT);
268 valib_mat_copy3(QAQT, residual_vorticity_strain);
269 valib_ttat3(shear_vorticity_strain, Q, QAQT);
270 valib_mat_copy3(QAQT, shear_vorticity_strain);
271
272 // Find symmetric and antisymmetric parts of the residual tensor
273 valib_sym_antisym3(residual_vorticity_strain);
274 // Find symmetric and antisymmetric parts of the shear tensor
275 valib_sym_antisym3(shear_vorticity_strain);
276}
277/***************************************************************************/
281/***************************************************************************/
325VA_DEVICE_FUN void valib_triple_decomposition(
326 VA_DEVICE_ADDR VA_REAL *A,
327 int *num_intervals,
328 VA_DEVICE_ADDR VA_REAL *residual_vorticity,
329 VA_DEVICE_ADDR VA_REAL *residual_strain,
330 VA_DEVICE_ADDR VA_REAL *shear)
331{
332 VA_REAL residual_vorticity_strain[9];
333 VA_REAL shear_vorticity_strain[9];
334 VA_REAL alpha_brf, beta_brf, gamma_brf; // angles of basic reference
335 // frame (BRF)
336
337 valib_triple_decomposition_base(A, num_intervals,
338 residual_vorticity_strain,
339 shear_vorticity_strain,
340 &alpha_brf, &beta_brf, &gamma_brf);
341
342 // ||Omega_RES||_F
343 // read from the lower triangle of the residual_vorticity_strain array
344 *residual_vorticity = sqrt(
345 2.*valib_square(residual_vorticity_strain[1])
346 + 2.*valib_square(residual_vorticity_strain[2])
347 + 2.*valib_square(residual_vorticity_strain[5])
348 );
349
350 // ||S_RES||_F
351 // read from the upper triangle of the residual_strain array
352 *residual_strain = sqrt(
353 2.*valib_square(residual_vorticity_strain[3])
354 + 2.*valib_square(residual_vorticity_strain[6])
355 + 2.*valib_square(residual_vorticity_strain[7])
356 + valib_square(residual_vorticity_strain[0])
357 + valib_square(residual_vorticity_strain[4])
358 + valib_square(residual_vorticity_strain[8])
359 );
360
361 *shear = sqrt(
362 // diagonal terms
363 valib_square(shear_vorticity_strain[0])
364 + valib_square(shear_vorticity_strain[4])
365 + valib_square(shear_vorticity_strain[8])
366 // upper square
367 + valib_square(shear_vorticity_strain[3]-shear_vorticity_strain[1])
368 + valib_square(shear_vorticity_strain[6]-shear_vorticity_strain[2])
369 + valib_square(shear_vorticity_strain[7]-shear_vorticity_strain[5])
370 // lower square
371 + valib_square(shear_vorticity_strain[3]+shear_vorticity_strain[1])
372 + valib_square(shear_vorticity_strain[6]+shear_vorticity_strain[2])
373 + valib_square(shear_vorticity_strain[7]+shear_vorticity_strain[5])
374 );
375}
376
377/***************************************************************************/
435VA_DEVICE_FUN void valib_residual_vorticity(
436 VA_DEVICE_ADDR VA_REAL *A,
437 int *num_intervals,
438 VA_DEVICE_ADDR VA_REAL *residual_vorticity,
439 VA_DEVICE_ADDR VA_REAL *residual_strain,
440 VA_DEVICE_ADDR VA_REAL *shear)
441{
442 VA_REAL residual_vorticity_strain[9];
443 VA_REAL shear_vorticity_strain[9];
444 VA_REAL alpha_brf, beta_brf, gamma_brf; // angles of basic reference
445 // frame (BRF)
446
447 valib_triple_decomposition_base(A, num_intervals,
448 residual_vorticity_strain,
449 shear_vorticity_strain,
450 &alpha_brf, &beta_brf, &gamma_brf);
451
452 // Get omega_RES from the antisymmetric tensor.
453 residual_vorticity[0] = 2. * residual_vorticity_strain[5];
454 residual_vorticity[1] = -2. * residual_vorticity_strain[2];
455 residual_vorticity[2] = 2. * residual_vorticity_strain[1];
456
457 // ||S_RES||_F
458 // read from the upper triangle of the residual_strain array
459 if (residual_strain != NULL) {
460 *residual_strain = sqrt(
461 2.*valib_square(residual_vorticity_strain[3])
462 + 2.*valib_square(residual_vorticity_strain[6])
463 + 2.*valib_square(residual_vorticity_strain[7])
464 + valib_square(residual_vorticity_strain[0])
465 + valib_square(residual_vorticity_strain[4])
466 + valib_square(residual_vorticity_strain[8])
467 );
468 }
469
470 if (shear != NULL) {
471 *shear = sqrt(
472 // diagonal terms
473 valib_square(shear_vorticity_strain[0])
474 + valib_square(shear_vorticity_strain[4])
475 + valib_square(shear_vorticity_strain[8])
476 // upper square
477 + valib_square(shear_vorticity_strain[3]-shear_vorticity_strain[1])
478 + valib_square(shear_vorticity_strain[6]-shear_vorticity_strain[2])
479 + valib_square(shear_vorticity_strain[7]-shear_vorticity_strain[5])
480 // lower square
481 + valib_square(shear_vorticity_strain[3]+shear_vorticity_strain[1])
482 + valib_square(shear_vorticity_strain[6]+shear_vorticity_strain[2])
483 + valib_square(shear_vorticity_strain[7]+shear_vorticity_strain[5])
484 );
485 }
486}
487
488/***************************************************************************/
546 VA_DEVICE_ADDR VA_REAL *A, int *num_intervals,
547 VA_DEVICE_ADDR VA_REAL *residual_vorticity,
548 VA_DEVICE_ADDR VA_REAL *residual_strain,
549 VA_DEVICE_ADDR VA_REAL *shear_vorticity,
550 VA_DEVICE_ADDR VA_REAL *shear_strain)
551{
552 VA_REAL residual_vorticity_strain[9];
553 VA_REAL shear_vorticity_strain[9];
554 VA_REAL alpha_brf, beta_brf, gamma_brf; // angles of basic reference
555 // frame (BRF)
556
557 valib_triple_decomposition_base(A, num_intervals,
558 residual_vorticity_strain,
559 shear_vorticity_strain,
560 &alpha_brf, &beta_brf, &gamma_brf);
561
562 // ||Omega_RES||_F
563 // read from the lower triangle of the residual_vorticity_strain array
564 *residual_vorticity = sqrt(
565 2.*valib_square(residual_vorticity_strain[1])
566 + 2.*valib_square(residual_vorticity_strain[2])
567 + 2.*valib_square(residual_vorticity_strain[5])
568 );
569
570 // ||S_RES||_F
571 // read from the upper triangle of the residual_strain array
572 *residual_strain = sqrt(
573 2.*valib_square(residual_vorticity_strain[3])
574 + 2.*valib_square(residual_vorticity_strain[6])
575 + 2.*valib_square(residual_vorticity_strain[7])
576 + valib_square(residual_vorticity_strain[0])
577 + valib_square(residual_vorticity_strain[4])
578 + valib_square(residual_vorticity_strain[8])
579 );
580
581 *shear_vorticity = sqrt(
582 // lower square
583 2.*valib_square(shear_vorticity_strain[1])
584 + 2.*valib_square(shear_vorticity_strain[2])
585 + 2.*valib_square(shear_vorticity_strain[5])
586 );
587
588 *shear_strain = sqrt(
589 2.*valib_square(shear_vorticity_strain[3])
590 + 2.*valib_square(shear_vorticity_strain[6])
591 + 2.*valib_square(shear_vorticity_strain[7])
592 + valib_square(shear_vorticity_strain[0])
593 + valib_square(shear_vorticity_strain[4])
594 + valib_square(shear_vorticity_strain[8])
595 );
596}
597
598/***************************************************************************/
657 VA_DEVICE_ADDR VA_REAL *A,
658 int *num_intervals,
659 VA_DEVICE_ADDR VA_REAL *residual_vorticity,
660 VA_DEVICE_ADDR VA_REAL *residual_strain,
661 VA_DEVICE_ADDR VA_REAL *shear,
662 VA_DEVICE_ADDR VA_REAL *alpha,
663 VA_DEVICE_ADDR VA_REAL *beta,
664 VA_DEVICE_ADDR VA_REAL *gamma
665 )
666{
667 VA_REAL residual_vorticity_strain[9];
668 VA_REAL shear_vorticity_strain[9];
669 VA_REAL alpha_brf, beta_brf, gamma_brf; // angles of basic reference
670 // frame (BRF)
671
672 valib_triple_decomposition_base(A, num_intervals,
673 residual_vorticity_strain,
674 shear_vorticity_strain,
675 &alpha_brf, &beta_brf, &gamma_brf);
676
677 // return the angles
678 *alpha = alpha_brf;
679 *beta = beta_brf;
680 *gamma = gamma_brf;
681
682 // ||Omega_RES||_F
683 // read from the lower triangle of the residual_vorticity_strain array
684 *residual_vorticity = sqrt(
685 2.*valib_square(residual_vorticity_strain[1])
686 + 2.*valib_square(residual_vorticity_strain[2])
687 + 2.*valib_square(residual_vorticity_strain[5])
688 );
689
690 // ||S_RES||_F
691 // read from the upper triangle of the residual_strain array
692 *residual_strain = sqrt(
693 2.*valib_square(residual_vorticity_strain[3])
694 + 2.*valib_square(residual_vorticity_strain[6])
695 + 2.*valib_square(residual_vorticity_strain[7])
696 + valib_square(residual_vorticity_strain[0])
697 + valib_square(residual_vorticity_strain[4])
698 + valib_square(residual_vorticity_strain[8])
699 );
700
701 *shear = sqrt(
702 // diagonal terms
703 valib_square(shear_vorticity_strain[0])
704 + valib_square(shear_vorticity_strain[4])
705 + valib_square(shear_vorticity_strain[8])
706 // upper square
707 + valib_square(shear_vorticity_strain[3]-shear_vorticity_strain[1])
708 + valib_square(shear_vorticity_strain[6]-shear_vorticity_strain[2])
709 + valib_square(shear_vorticity_strain[7]-shear_vorticity_strain[5])
710 // lower square
711 + valib_square(shear_vorticity_strain[3]+shear_vorticity_strain[1])
712 + valib_square(shear_vorticity_strain[6]+shear_vorticity_strain[2])
713 + valib_square(shear_vorticity_strain[7]+shear_vorticity_strain[5])
714 );
715}
716
717#endif // VA_TRIPLE_DECOMPOSITION_H
VA_DEVICE_FUN void valib_triple_decomposition_4norms(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals, VA_DEVICE_ADDR VA_REAL *residual_vorticity, VA_DEVICE_ADDR VA_REAL *residual_strain, VA_DEVICE_ADDR VA_REAL *shear_vorticity, VA_DEVICE_ADDR VA_REAL *shear_strain)
Triple Decomposition Method (TDM, a.k.a. residual vorticity and residual strain rate) ,...
VA_DEVICE_FUN void valib_triple_decomposition(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals, VA_DEVICE_ADDR VA_REAL *residual_vorticity, VA_DEVICE_ADDR VA_REAL *residual_strain, VA_DEVICE_ADDR VA_REAL *shear)
Triple Decomposition Method (TDM, a.k.a. residual vorticity and residual strain rate) ,...
VA_DEVICE_FUN void valib_triple_decomposition_with_angles(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals, VA_DEVICE_ADDR VA_REAL *residual_vorticity, VA_DEVICE_ADDR VA_REAL *residual_strain, VA_DEVICE_ADDR VA_REAL *shear, VA_DEVICE_ADDR VA_REAL *alpha, VA_DEVICE_ADDR VA_REAL *beta, VA_DEVICE_ADDR VA_REAL *gamma)
Triple Decomposition Method (TDM, a.k.a. residual vorticity and residual strain rate) ,...
VA_DEVICE_FUN void valib_residual_vorticity(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals, VA_DEVICE_ADDR VA_REAL *residual_vorticity, VA_DEVICE_ADDR VA_REAL *residual_strain, VA_DEVICE_ADDR VA_REAL *shear)
Triple Decomposition Method (TDM, a.k.a. residual vorticity and residual strain rate) ,...
VA_DEVICE_FUN void valib_tatt3(VA_REAL *A, VA_REAL *T, VA_REAL *TATT)
Definition linalg3.h:503
VA_DEVICE_FUN void valib_ttat3(VA_REAL *A, VA_REAL *T, VA_REAL *TTAT)
Definition linalg3.h:555
VA_DEVICE_FUN void valib_get_brf(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals, VA_REAL *alpha_brf, VA_REAL *beta_brf, VA_REAL *gamma_brf, VA_REAL *goal_brf)
VA_DEVICE_FUN VA_REAL valib_min(VA_REAL a, VA_REAL b)
Definition linalg3.h:89
VA_DEVICE_FUN void valib_sym_antisym3(VA_REAL *A)
Definition linalg3.h:417
VA_DEVICE_FUN void valib_mat_copy3(VA_REAL *A, VA_REAL *B)
Definition linalg3.h:340
VA_DEVICE_FUN VA_REAL valib_square(VA_REAL a)
Definition linalg3.h:98
VA_DEVICE_FUN VA_REAL valib_sign(VA_REAL a, VA_REAL b)
Definition linalg3.h:20
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:857
VA_DEVICE_FUN void valib_triple_decomposition_base(VA_DEVICE_ADDR VA_REAL *A, int *num_intervals, VA_DEVICE_ADDR VA_REAL *residual_vorticity_strain, VA_DEVICE_ADDR VA_REAL *shear_vorticity_strain, VA_DEVICE_ADDR VA_REAL *alpha, VA_DEVICE_ADDR VA_REAL *beta, VA_DEVICE_ADDR VA_REAL *gamma)
Triple Decomposition Method (TDM, a.k.a. residual vorticity and residual strain rate) ,...