xref: /libCEED/tests/t304-basis.c (revision 49aac155e7a09736f56fb3abac0f57dab29f7cbf)
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>
7*49aac155SJeremy L Thompson #include <stdio.h>
857c64913Sjeremylt 
957c64913Sjeremylt int main(int argc, char **argv) {
1057c64913Sjeremylt   Ceed              ceed;
114fee36f0SJeremy L Thompson   CeedInt           p = 4;
12673160d7Sjeremylt   CeedScalar        M[16], Q[16], lambda[4], Q_lambda_Qt[16];
13673160d7Sjeremylt   CeedBasis         basis;
144fee36f0SJeremy L Thompson   const CeedScalar *interpolation, *quadrature_weights;
1557c64913Sjeremylt 
1657c64913Sjeremylt   CeedInit(argv[1], &ceed);
17288c0443SJeremy L Thompson 
18673160d7Sjeremylt   // Create mass matrix
194fee36f0SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, p, p, CEED_GAUSS, &basis);
204fee36f0SJeremy L Thompson   CeedBasisGetInterp(basis, &interpolation);
214fee36f0SJeremy L Thompson   CeedBasisGetQWeights(basis, &quadrature_weights);
224fee36f0SJeremy L Thompson   for (int i = 0; i < p; i++) {
234fee36f0SJeremy L Thompson     for (int j = 0; j < p; j++) {
24673160d7Sjeremylt       CeedScalar sum = 0;
254fee36f0SJeremy L Thompson       for (int k = 0; k < p; k++) sum += interpolation[p * k + i] * quadrature_weights[k] * interpolation[p * k + j];
264fee36f0SJeremy L Thompson       M[p * i + j] = sum;
274fee36f0SJeremy L Thompson       Q[p * i + j] = sum;
2857c64913Sjeremylt     }
292b730f8bSJeremy L Thompson   }
30673160d7Sjeremylt 
314fee36f0SJeremy L Thompson   CeedSymmetricSchurDecomposition(ceed, Q, lambda, p);
32673160d7Sjeremylt 
33673160d7Sjeremylt   // Check diagonalization of M
344fee36f0SJeremy L Thompson   for (int i = 0; i < p; i++) {
354fee36f0SJeremy L Thompson     for (int j = 0; j < p; j++) {
36673160d7Sjeremylt       CeedScalar sum = 0;
374fee36f0SJeremy L Thompson       for (int k = 0; k < p; k++) sum += Q[p * i + k] * lambda[k] * Q[p * j + k];
384fee36f0SJeremy L Thompson       Q_lambda_Qt[p * i + j] = sum;
3952bfb9bbSJeremy L Thompson     }
402b730f8bSJeremy L Thompson   }
414fee36f0SJeremy L Thompson   for (int i = 0; i < p; i++) {
424fee36f0SJeremy L Thompson     for (int j = 0; j < p; j++) {
434fee36f0SJeremy L Thompson       if (fabs(M[p * i + j] - Q_lambda_Qt[p * i + j]) > 100. * CEED_EPSILON) {
44673160d7Sjeremylt         // LCOV_EXCL_START
454fee36f0SJeremy 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]);
46673160d7Sjeremylt         // LCOV_EXCL_STOP
472b730f8bSJeremy L Thompson       }
482b730f8bSJeremy L Thompson     }
492b730f8bSJeremy L Thompson   }
50673160d7Sjeremylt 
51673160d7Sjeremylt   CeedBasisDestroy(&basis);
5257c64913Sjeremylt   CeedDestroy(&ceed);
5357c64913Sjeremylt   return 0;
5457c64913Sjeremylt }
55