xref: /libCEED/tests/t304-basis.c (revision 2b730f8b5a9c809740a0b3b302db43a719c636b1)
14411cf47Sjeremylt /// @file
252bfb9bbSJeremy L Thompson /// Test Symmetric Schur Decomposition
352bfb9bbSJeremy L Thompson /// \test Test Symmetric Schur Decomposition
457c64913Sjeremylt #include <ceed.h>
5673160d7Sjeremylt #include <ceed/backend.h>
6673160d7Sjeremylt #include <math.h>
757c64913Sjeremylt 
857c64913Sjeremylt int main(int argc, char **argv) {
957c64913Sjeremylt   Ceed       ceed;
10673160d7Sjeremylt   CeedInt    P = 4;
11673160d7Sjeremylt   CeedScalar M[16], Q[16], lambda[4], Q_lambda_Qt[16];
12673160d7Sjeremylt   CeedBasis  basis;
1357c64913Sjeremylt 
1457c64913Sjeremylt   CeedInit(argv[1], &ceed);
15288c0443SJeremy L Thompson 
16673160d7Sjeremylt   // Create mass matrix
17673160d7Sjeremylt   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, P, P, CEED_GAUSS, &basis);
18673160d7Sjeremylt   const CeedScalar *interp, *quad_weights;
19673160d7Sjeremylt   CeedBasisGetInterp(basis, &interp);
20673160d7Sjeremylt   CeedBasisGetQWeights(basis, &quad_weights);
21*2b730f8bSJeremy L Thompson   for (int i = 0; i < P; i++) {
22673160d7Sjeremylt     for (int j = 0; j < P; j++) {
23673160d7Sjeremylt       CeedScalar sum = 0;
24*2b730f8bSJeremy L Thompson       for (int k = 0; k < P; k++) sum += interp[P * k + i] * quad_weights[k] * interp[P * k + j];
25673160d7Sjeremylt       M[P * i + j] = sum;
26673160d7Sjeremylt       Q[P * i + j] = sum;
2757c64913Sjeremylt     }
28*2b730f8bSJeremy L Thompson   }
29673160d7Sjeremylt 
30673160d7Sjeremylt   CeedSymmetricSchurDecomposition(ceed, Q, lambda, P);
31673160d7Sjeremylt 
32673160d7Sjeremylt   // Check diagonalization of M
33*2b730f8bSJeremy L Thompson   for (int i = 0; i < P; i++) {
34673160d7Sjeremylt     for (int j = 0; j < P; j++) {
35673160d7Sjeremylt       CeedScalar sum = 0;
36*2b730f8bSJeremy L Thompson       for (int k = 0; k < P; k++) sum += Q[P * i + k] * lambda[k] * Q[P * j + k];
37673160d7Sjeremylt       Q_lambda_Qt[P * i + j] = sum;
3852bfb9bbSJeremy L Thompson     }
39*2b730f8bSJeremy L Thompson   }
40*2b730f8bSJeremy L Thompson   for (int i = 0; i < P; i++) {
41*2b730f8bSJeremy L Thompson     for (int j = 0; j < P; j++) {
42*2b730f8bSJeremy L Thompson       if (fabs(M[P * i + j] - Q_lambda_Qt[P * i + j]) > 100. * CEED_EPSILON) {
43673160d7Sjeremylt         // LCOV_EXCL_START
44*2b730f8bSJeremy L Thompson         printf("Error in diagonalization [%" CeedInt_FMT ", %" CeedInt_FMT "]: %f != %f\n", i, j, M[P * i + j], Q_lambda_Qt[P * i + j]);
45673160d7Sjeremylt         // LCOV_EXCL_STOP
46*2b730f8bSJeremy L Thompson       }
47*2b730f8bSJeremy L Thompson     }
48*2b730f8bSJeremy L Thompson   }
49673160d7Sjeremylt 
50673160d7Sjeremylt   CeedBasisDestroy(&basis);
5157c64913Sjeremylt   CeedDestroy(&ceed);
5257c64913Sjeremylt   return 0;
5357c64913Sjeremylt }
54