MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
dgcartesianinterpolation.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef DGINTERPOLATION_H_
8#define DGINTERPOLATION_H_
9//#define CALC_POLY_DERIV_SORTING
10
11#include <algorithm>
12#include <iomanip>
13
15#include "INCLUDE/maiatypes.h"
16#include "UTIL/maiamath.h"
17#include "UTIL/tensor.h"
18#include "enums.h"
19
36 // Member methods
37 public:
39 DgInterpolation(const MInt polyDeg, const DgPolynomialType polyType, const MInt noNodes,
40 const DgIntegrationMethod intMethod, const MBool sbpMode, const MString sbpOperator);
42
43 void init(const MInt polyDeg, const DgPolynomialType polyType, const MInt noNodes,
44 const DgIntegrationMethod intMethod, const MBool sbpMode, const MString sbpOperator);
45
46 void initInterpolation(const MInt polyDeg, const DgPolynomialType polyType, const MInt noNodes,
47 const DgIntegrationMethod intMethod, const MBool sbpMode, const MString sbpOperator);
48
49 // Member variables
50 public:
51 // SBP Mode
53 // SBP Operator
55 // Polynomial degree.
57 // No nodes 1D
59 // Polynomial type (i.e. Legendre).
61 // Quadrature method (i.e. Gauss or Gauss-Lobatto).
63 // Nodes for integration & interpolation.
65 // Quadrature weights for integration.
67 // Barycentric weights for Lagrange interpolation.
69 // Derivative matrix normalized by integration weights.
71 // Values of Lagrange polynomials at x = -1.0 (index 0) and +1.0 (index 1)
73 // Values of normalized Lagrange polynomials at x = -1.0 (index 0)
74 // and +1.0 (index 1)
76 // mutable spline m_spline;
77};
78
79
80namespace maia {
81namespace dg {
82
97namespace interpolation {
98
99
114inline void calcLegendrePolyAndDeriv(MInt Nmax, MFloat x, MFloat* polynomial, MFloat* derivative) {
115 maia::math::calculateLegendrePolyAndDeriv(Nmax, x, polynomial, derivative);
116}
117
131inline void calcLegendreGaussNodesAndWeights(MInt Nmax, MFloat* nodes, MFloat* wInt) {
133}
134
135
151inline void calcQandL(MInt Nmax, MFloat x, MFloat& q, MFloat& qDeriv, MFloat& poly) {
152 TRACE();
153 // This may only be called for Nmax >= 2 (see Kopriva09)
154 if(Nmax < 2) {
155 mTerm(1, AT_, "Gauss-Lobatto needs at least two nodes!");
156 }
157
158 MFloat polyLast1, polyLast2, derivLast1, derivLast2, deriv;
159
160 polyLast2 = F1;
161 polyLast1 = x;
162 derivLast2 = F0;
163 derivLast1 = F1;
164
165 for(MInt k = 2; k <= Nmax; k++) {
166 poly = (F2 * k - F1) / k * x * polyLast1 - (k - F1) / k * polyLast2;
167 deriv = derivLast2 + (F2 * k - F1) * polyLast1;
168 polyLast2 = polyLast1;
169 polyLast1 = poly;
170 derivLast2 = derivLast1;
171 derivLast1 = deriv;
172 }
173
174 MFloat polyNp1, derivNp1;
175 MInt k = Nmax + 1;
176
177 polyNp1 = (F2 * k - F1) / k * x * poly - (k - F1) / k * polyLast2;
178 derivNp1 = derivLast2 + (F2 * k - F1) * polyLast1;
179
180 q = polyNp1 - polyLast2;
181 qDeriv = derivNp1 - derivLast2;
182}
183
184
199 TRACE();
200 // Gauss-Lobatto only valid for degree >= 1
201 ASSERT(Nmax > 0, "Number of nodes must be greater than zero!");
202
203 // Reset nodes and weights
204 const MInt noNodes = Nmax + 1;
205 std::fill_n(&nodes[0], noNodes, F0);
206 std::fill_n(&wInt[0], noNodes, F0);
207
208 // Return values for polynomial and derivative
209 MFloat q, qDeriv, poly;
210
211 // Set tolerance and number of iterations. According to Kopriva09,
212 // 1.0E-15 and 10 should be more than sufficient.
213 const MFloat tol = F4 * MFloatEps;
214 const MInt noIterations = 10;
215
216 // Catch simple cases before going into the full loop
217 if(Nmax == 1) {
218 nodes[0] = -F1;
219 wInt[0] = F1;
220 nodes[1] = F1;
221 wInt[1] = wInt[0];
222 } else {
223 nodes[0] = -F1;
224 wInt[0] = F2 / (Nmax * (Nmax + F1));
225 nodes[Nmax] = F1;
226 wInt[Nmax] = wInt[0];
227
228 for(MInt j = 1; j < (Nmax + 1) / 2; j++) {
229 // Calculate starting guess for Newton method
230 nodes[j] = -cos((j + F1B4) * PI / Nmax - F3B8 / Nmax / PI * F1 / (j + F1B4));
231
232 // Use Newton method to find root of Legendre polynomial
233 // -> this is also the integration node
234 for(MInt k = 0; k < noIterations; k++) {
235 calcQandL(Nmax, nodes[j], q, qDeriv, poly);
236 const MFloat delta = -q / qDeriv;
237 nodes[j] += delta;
238
239 // Stop iterations if error is small enough
240 if(fabs(delta) <= tol * fabs(nodes[j])) {
241 break;
242 }
243 }
244
245 // Calculate weight
246 calcQandL(Nmax, nodes[j], q, qDeriv, poly);
247 wInt[j] = F2 / (Nmax * (Nmax + F1) * poly * poly);
248
249 // Set nodes and weights according to symmetry properties
250 nodes[Nmax - j] = -nodes[j];
251 wInt[Nmax - j] = wInt[j];
252 }
253 }
254
255 // If odd number of nodes (noNodes = Nmax + 1), set center node toi
256 // origin (0.0) and calculate weight
257 if(Nmax % 2 == 0) {
258 calcQandL(Nmax, F0, q, qDeriv, poly);
259 nodes[Nmax / 2] = F0;
260 wInt[Nmax / 2] = F2 / (Nmax * (Nmax + F1) * poly * poly);
261 }
262}
263
277inline void calcBarycentricWeights(MInt Nmax, const MFloat* nodes, MFloat* weights) {
278 TRACE();
279
280 const MInt noNodes = Nmax + 1;
281 std::fill_n(&weights[0], noNodes, F1);
282
283 // Main iteration loop to calculate inverse weights
284 for(MInt j = 1; j < noNodes; j++) {
285 for(MInt k = 0; k < j; k++) {
286 weights[k] = weights[k] * (nodes[k] - nodes[j]);
287 weights[j] = weights[j] * (nodes[j] - nodes[k]);
288 }
289 }
290
291 // Invert previous results to get final weights
292 for(MInt j = 0; j < noNodes; j++) {
293 weights[j] = F1 / weights[j];
294 }
295}
296
297
315inline MFloat getLagrangeInterpolation(MFloat x, MInt Nmax, const MFloat* nodes, const MFloat* values,
316 const MFloat* wBary) {
317 // TRACE();
318
319 const MInt noNodes = Nmax + 1;
320 MFloat numerator = F0;
321 MFloat denominator = F0;
322
323 for(MInt j = 0; j < noNodes; j++) {
324 if(approx(x, nodes[j], MFloatEps)) {
325 return values[j];
326 }
327 MFloat t = wBary[j] / (x - nodes[j]);
328 numerator += t * values[j];
329 denominator += t;
330 }
331
332 return numerator / denominator;
333}
334
335
351inline void calcLagrangeInterpolatingPolynomials(const MFloat x, const MInt polyDeg, const MFloat* nodes,
352 const MFloat* wBary, MFloat* polynomials) {
353 // TRACE();
354 const MInt noNodes = polyDeg + 1;
355 std::fill_n(&polynomials[0], noNodes, F0);
356
357 // Catch situation where evaluation point is on node, which saves considerable
358 // computational time
359 for(MInt j = 0; j < noNodes; j++) {
360 if(approx(x, nodes[j], MFloatEps)) {
361 polynomials[j] = F1;
362 return;
363 }
364 }
365
366 // Otherwise calculate Lagrange interpolating polynomials according to
367 // Eq. (3.39) in Kopriva09
368 MFloat s = F0;
369 MFloat t = F0;
370 for(MInt j = 0; j < noNodes; j++) {
371 t = wBary[j] / (x - nodes[j]);
372 polynomials[j] = t;
373 s += t;
374 }
375 for(MInt j = 0; j < noNodes; j++) {
376 polynomials[j] = polynomials[j] / s;
377 }
378}
379
395inline void calcLhat(const MFloat x, const MInt polyDeg, const MFloat* nodes, const MFloat* wInt, const MFloat* wBary,
396 MFloat* Lhat) {
397 TRACE();
398 const MInt noNodes = polyDeg + 1;
399
400 // Calculate the Lagrange polynomials and evaluate them at x
401 calcLagrangeInterpolatingPolynomials(x, polyDeg, &nodes[0], &wBary[0], Lhat);
402 // Normalize by integration weights
403 for(MInt j = 0; j < noNodes; j++) {
404 Lhat[j] = Lhat[j] / wInt[j];
405 }
406}
407
408#ifdef CALC_POLY_DERIV_SORTING
409inline MBool ascendingAbsVal(MFloat i, MFloat j) { return (std::fabs(i) < std::fabs(j)); }
410#endif
411
412
426inline void calcPolynomialDerivativeMatrix(MInt Nmax, const MFloat* nodes, const MFloat* wBary, MFloat* derivMatrix) {
427 TRACE();
428
429#ifdef CALC_POLY_DERIV_SORTING
430 const MInt noNodes = Nmax + 1;
431 MFloatMatrix D(&derivMatrix[0], noNodes, noNodes);
432 std::vector<MFloat> column(noNodes);
433 D.set(F0);
434
435 // Iterate over all indices and calculate the D_ij according to Eq. (3.48).
436 // For i == j, use the negative sum trick.
437 for(MInt i = 0; i < noNodes; i++) {
438 for(MInt j = 0; j < noNodes; j++) {
439 if(j != i) {
440 D(i, j) = wBary[j] / wBary[i] * F1 / (nodes[i] - nodes[j]);
441 column[j] = D(i, j);
442 } else {
443 column[j] = F0;
444 }
445 }
446 std::sort(column.begin(), column.end(), ascendingAbsVal);
447 for(MInt j = 0; j < noNodes; j++) {
448 D(i, i) -= column[j];
449 }
450 }
451
452
453#else
454 const MInt noNodes = Nmax + 1;
455 MFloatMatrix D(&derivMatrix[0], noNodes, noNodes);
456 D.set(F0);
457
458 // Iterate over all indices and calculate the D_ij according to Eq. (3.48).
459 // For i == j, use the negative sum trick.
460 for(MInt i = 0; i < noNodes; i++) {
461 for(MInt j = 0; j < noNodes; j++) {
462 if(j != i) {
463 D(i, j) = wBary[j] / wBary[i] * F1 / (nodes[i] - nodes[j]);
464 D(i, i) -= D(i, j);
465 }
466 }
467 }
468#endif
469}
470
488inline void calcDhat(MInt Nmax, const MFloat* nodes, const MFloat* wInt, const MFloat* wBary, MFloat* dhatMatrix) {
489 TRACE();
490
491 // Get number of nodes and standard derivative matrix
492 const MInt noNodes = Nmax + 1;
493 MFloatMatrix Dhat(&dhatMatrix[0], noNodes, noNodes);
494 calcPolynomialDerivativeMatrix(Nmax, &nodes[0], &wBary[0], &Dhat[0]);
495
496 Dhat.transpose();
497
498 // Add normalization using integration weights
499 for(MInt j = 0; j < noNodes; j++) {
500 for(MInt n = 0; n < noNodes; n++) {
501 Dhat(j, n) = -Dhat(j, n) * wInt[n] / wInt[j];
502 }
503 }
504}
505
527template <MInt nDim, MInt noVariables>
528void prolongToFaceGauss(const MFloat* const source,
529 const MInt faceId,
530 const MInt noNodes1D,
531 const MFloat* const LFaceN,
532 const MFloat* const LFaceP,
533 MFloat* const destination) {
534 // TRACE();
535
536 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
537 const MFloatTensor src(const_cast<MFloat*>(source), noNodes1D, noNodes1D, noNodes1D3, noVariables);
538 MFloatTensor dest(destination, noNodes1D, noNodes1D3, noVariables);
539
540 // Reset destination to zero
541 std::fill_n(destination, noNodes1D * noNodes1D3 * noVariables, F0);
542
543 // Index for x-direction: i
544 // Index for y-direction: j
545 // Index for z-direction: k
546 // Index for variables: l
547 switch(faceId) {
548 case 0: // prolong to negative x-direction
549 for(MInt i = 0; i < noNodes1D; i++) {
550 for(MInt j = 0; j < noNodes1D; j++) {
551 for(MInt k = 0; k < noNodes1D3; k++) {
552 for(MInt l = 0; l < noVariables; l++) {
553 dest(j, k, l) += src(i, j, k, l) * LFaceN[i];
554 }
555 }
556 }
557 }
558 break;
559 case 1: // prolong to positive x-direction
560 for(MInt i = 0; i < noNodes1D; i++) {
561 for(MInt j = 0; j < noNodes1D; j++) {
562 for(MInt k = 0; k < noNodes1D3; k++) {
563 for(MInt l = 0; l < noVariables; l++) {
564 dest(j, k, l) += src(i, j, k, l) * LFaceP[i];
565 }
566 }
567 }
568 }
569 break;
570 case 2: // prolong to negative y-direction
571 for(MInt i = 0; i < noNodes1D; i++) {
572 for(MInt j = 0; j < noNodes1D; j++) {
573 for(MInt k = 0; k < noNodes1D3; k++) {
574 for(MInt l = 0; l < noVariables; l++) {
575 dest(i, k, l) += src(i, j, k, l) * LFaceN[j];
576 }
577 }
578 }
579 }
580 break;
581 case 3: // prolong to positive y-direction
582 for(MInt i = 0; i < noNodes1D; i++) {
583 for(MInt j = 0; j < noNodes1D; j++) {
584 for(MInt k = 0; k < noNodes1D3; k++) {
585 for(MInt l = 0; l < noVariables; l++) {
586 dest(i, k, l) += src(i, j, k, l) * LFaceP[j];
587 }
588 }
589 }
590 }
591 break;
592 case 4: // prolong to negative z-direction
593 for(MInt i = 0; i < noNodes1D; i++) {
594 for(MInt j = 0; j < noNodes1D; j++) {
595 for(MInt k = 0; k < noNodes1D; k++) {
596 for(MInt l = 0; l < noVariables; l++) {
597 dest(i, j, l) += src(i, j, k, l) * LFaceN[k];
598 }
599 }
600 }
601 }
602 break;
603 case 5: // prolong to positive z-direction
604 for(MInt i = 0; i < noNodes1D; i++) {
605 for(MInt j = 0; j < noNodes1D; j++) {
606 for(MInt k = 0; k < noNodes1D; k++) {
607 for(MInt l = 0; l < noVariables; l++) {
608 dest(i, j, l) += src(i, j, k, l) * LFaceP[k];
609 }
610 }
611 }
612 }
613 break;
614 default:
615 mTerm(1, AT_, "Bad face id.");
616 }
617}
618
619
639template <MInt nDim, MInt noVariables, class T, class U>
640void prolongToFaceGaussLobatto(const T source, const MInt faceId, const MInt noNodes1D, U destination) {
641 // TRACE();
642
643 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
644 const MFloatTensor src(&source[0], noNodes1D, noNodes1D, noNodes1D3, noVariables);
645 MFloatTensor dest(&destination[0], noNodes1D, noNodes1D3, noVariables);
646
647 // Index for x-direction: i
648 // Index for y-direction: j
649 // Index for z-direction: k
650 // Index for variables: l
651 switch(faceId) {
652 case 0: // prolong to negative x-direction
653 for(MInt j = 0; j < noNodes1D; j++) {
654 for(MInt k = 0; k < noNodes1D3; k++) {
655 for(MInt l = 0; l < noVariables; l++) {
656 dest(j, k, l) = src(0, j, k, l);
657 }
658 }
659 }
660 break;
661 case 1: // prolong to positive x-direction
662 for(MInt j = 0; j < noNodes1D; j++) {
663 for(MInt k = 0; k < noNodes1D3; k++) {
664 for(MInt l = 0; l < noVariables; l++) {
665 dest(j, k, l) = src(noNodes1D - 1, j, k, l);
666 }
667 }
668 }
669 break;
670 case 2: // prolong to negative y-direction
671 for(MInt i = 0; i < noNodes1D; i++) {
672 for(MInt k = 0; k < noNodes1D3; k++) {
673 for(MInt l = 0; l < noVariables; l++) {
674 dest(i, k, l) = src(i, 0, k, l);
675 }
676 }
677 }
678 break;
679 case 3: // prolong to positive y-direction
680 for(MInt i = 0; i < noNodes1D; i++) {
681 for(MInt k = 0; k < noNodes1D3; k++) {
682 for(MInt l = 0; l < noVariables; l++) {
683 dest(i, k, l) = src(i, noNodes1D - 1, k, l);
684 }
685 }
686 }
687 break;
688 case 4: // prolong to negative z-direction
689 for(MInt i = 0; i < noNodes1D; i++) {
690 for(MInt j = 0; j < noNodes1D; j++) {
691 for(MInt l = 0; l < noVariables; l++) {
692 dest(i, j, l) = src(i, j, 0, l);
693 }
694 }
695 }
696 break;
697 case 5: // prolong to positive z-direction
698 for(MInt i = 0; i < noNodes1D; i++) {
699 for(MInt j = 0; j < noNodes1D; j++) {
700 for(MInt l = 0; l < noVariables; l++) {
701 dest(i, j, l) = src(i, j, noNodes1D - 1, l);
702 }
703 }
704 }
705 break;
706 default:
707 mTerm(1, AT_, "Bad face id.");
708 }
709}
710
711
728template <class T, class U, class V, class W>
729void calcPolynomialInterpolationMatrix(MInt noNodesIn, const T nodesIn, MInt noNodesOut, const U nodesOut,
730 const V wBary, W vandermonde) {
731 TRACE();
732
733 MFloatMatrix vdm(&vandermonde[0], noNodesOut, noNodesIn);
734
735 for(MInt k = 0; k < noNodesOut; k++) {
736 MBool rowHasMatch = false;
737 for(MInt j = 0; j < noNodesIn; j++) {
738 vdm(k, j) = F0;
739 if(approx(nodesOut[k], nodesIn[j], MFloatEps)) {
740 rowHasMatch = true;
741 vdm(k, j) = F1;
742 }
743 }
744
745 if(rowHasMatch == false) {
746 MFloat s = 0;
747 for(MInt j = 0; j < noNodesIn; j++) {
748 MFloat t = wBary[j] / (nodesOut[k] - nodesIn[j]);
749 vdm(k, j) = t;
750 s += t;
751 }
752 for(MInt j = 0; j < noNodesIn; j++) {
753 vdm(k, j) = vdm(k, j) / s;
754 }
755 }
756 }
757}
758
759
776template <MInt nDim, class T, class U, class V>
777void interpolateNodes(const T source, U vandermonde, MInt noNodesIn, MInt noNodesOut, MInt noVariables, V destination) {
778 // TRACE();
779 const MInt noNodesIn1D = noNodesIn;
780 const MInt noNodesIn1D2 = (nDim == 2 || nDim == 3) ? noNodesIn1D : 1;
781 const MInt noNodesIn1D3 = (nDim == 3) ? noNodesIn1D : 1;
782 const MInt noNodesOut1D = noNodesOut;
783 const MInt noNodesOut1D2 = (nDim == 2 || nDim == 3) ? noNodesOut1D : 1;
784 const MInt noNodesOut1D3 = (nDim == 3) ? noNodesOut1D : 1;
785 const MFloatTensor src(&source[0], noNodesIn, noNodesIn1D2, noNodesIn1D3, noVariables);
786 MFloatTensor dest(&destination[0], noNodesOut, noNodesOut1D2, noNodesOut1D3, noVariables);
787 const MFloatMatrix vdm(&vandermonde[0], noNodesOut, noNodesIn);
788 dest.set(F0);
789
790 // Allocate buffers (if necessary) for intermediate results
791 MFloat* buf1Ptr = nullptr;
792 MFloat* buf2Ptr = nullptr;
793 MFloatTensor buffer1, buffer2;
794 switch(nDim) {
795 case 1: {
796 buf1Ptr = &destination[0];
797 buf2Ptr = nullptr;
798 } break;
799
800 case 2: {
801 buffer1.resize(noNodesOut, noNodesIn1D2, noNodesIn1D3, noVariables);
802 buf1Ptr = &buffer1[0];
803 buf2Ptr = &destination[0];
804 } break;
805
806 case 3: {
807 buffer1.resize(noNodesOut, noNodesIn1D2, noNodesIn1D3, noVariables);
808 buffer2.resize(noNodesOut, noNodesOut, noNodesIn, noVariables);
809 buf1Ptr = &buffer1[0];
810 buf2Ptr = &buffer2[0];
811 } break;
812
813 default:
814 mTerm(1, AT_, "Bad dimension - must be 1, 2 or 3.");
815 }
816 MFloatTensor buf1(buf1Ptr, noNodesOut, noNodesIn1D2, noNodesIn1D3, noVariables);
817 buf1.set(F0);
818
819 // x-direction
820 for(MInt i = 0; i < noNodesOut1D; i++) {
821 for(MInt j = 0; j < noNodesIn1D2; j++) {
822 for(MInt k = 0; k < noNodesIn1D3; k++) {
823 for(MInt ii = 0; ii < noNodesIn1D; ii++) {
824 for(MInt l = 0; l < noVariables; l++) {
825 buf1(i, j, k, l) += vdm(i, ii) * src(ii, j, k, l);
826 }
827 }
828 }
829 }
830 }
831
832 // Return here for 1D since buf2Ptr is a nullptr
833 IF_CONSTEXPR(nDim == 1) { return; }
834
835 MFloatTensor buf2(buf2Ptr, noNodesOut, noNodesOut1D2, noNodesIn1D3, noVariables);
836 buf2.set(F0);
837
838 // Interpolate in y-direction only for 2D & 3D
839 IF_CONSTEXPR(nDim == 2 || nDim == 3) {
840 // y-direction
841 for(MInt i = 0; i < noNodesOut1D; i++) {
842 for(MInt j = 0; j < noNodesOut1D; j++) {
843 for(MInt k = 0; k < noNodesIn1D3; k++) {
844 for(MInt jj = 0; jj < noNodesIn1D; jj++) {
845 for(MInt l = 0; l < noVariables; l++) {
846 buf2(i, j, k, l) += vdm(j, jj) * buf1(i, jj, k, l);
847 }
848 }
849 }
850 }
851 }
852 }
853
854 // Interpolate in z-direction only for 3D
855 IF_CONSTEXPR(nDim == 3) {
856 // z-direction
857 for(MInt i = 0; i < noNodesOut1D; i++) {
858 for(MInt j = 0; j < noNodesOut1D; j++) {
859 for(MInt k = 0; k < noNodesOut1D; k++) {
860 for(MInt kk = 0; kk < noNodesIn1D; kk++) {
861 for(MInt l = 0; l < noVariables; l++) {
862 dest(i, j, k, l) += vdm(k, kk) * buf2(i, j, kk, l);
863 }
864 }
865 }
866 }
867 }
868 }
869}
870
871} // namespace interpolation
872} // namespace dg
873} // namespace maia
874
875#endif /* DGINTERPOLATION_H_ */
Class stores precalculated values for interpolation & integration on the reference interval [-1,...
MFloatVector m_LhatFace[2]
~DgInterpolation()
Destructor clears all member variables.
void init(const MInt polyDeg, const DgPolynomialType polyType, const MInt noNodes, const DgIntegrationMethod intMethod, const MBool sbpMode, const MString sbpOperator)
Sets the member variables and calls the appropriate functions to calculate the nodes and weights etc.
DgInterpolation()
Default constructor only sets default values for member variables.
void initInterpolation(const MInt polyDeg, const DgPolynomialType polyType, const MInt noNodes, const DgIntegrationMethod intMethod, const MBool sbpMode, const MString sbpOperator)
Sets the member variables neccessary for the interpolation between sets of nodes.
void transpose()
Transposes the first two dimensions (i.e. acting as if the tensor is a matrix).
Definition: tensor.h:306
void set(const T &value)
Initializes tensor to constant value.
Definition: tensor.h:271
size_type resize(size_type n0, size_type n1=1, size_type n2=1, size_type n3=1, size_type n4=1)
Deletes the old data structure and creates a new one with the requested dimensions.
Definition: tensor.h:230
DgPolynomialType
Definition: enums.h:310
DgIntegrationMethod
Definition: enums.h:313
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
MBool approx(const T &, const U &, const T)
Definition: functions.h:272
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
void calcLegendreGaussLobattoNodesAndWeights(MInt Nmax, MFloat *nodes, MFloat *wInt)
Calculate the Gauss-Lobatto integration nodes and weight for the Legendre polynomials on the interval...
void calcQandL(MInt Nmax, MFloat x, MFloat &q, MFloat &qDeriv, MFloat &poly)
Auxiliary function (only used by calcLegendreGaussLobattoNodesAndWeights())
void calcLagrangeInterpolatingPolynomials(const MFloat x, const MInt polyDeg, const MFloat *nodes, const MFloat *wBary, MFloat *polynomials)
Calculates the values of the Lagrangian polynomials l_j for a given point x in [-1,...
void calcPolynomialInterpolationMatrix(MInt noNodesIn, const T nodesIn, MInt noNodesOut, const U nodesOut, const V wBary, W vandermonde)
Calculate the polynomial interpolation matrix (Vandermonde) to interpolate from one set of nodes to a...
MFloat getLagrangeInterpolation(MFloat x, MInt Nmax, const MFloat *nodes, const MFloat *values, const MFloat *wBary)
Calculates the interpolated value at point x given a set of nodes, values, and weights.
void calcBarycentricWeights(MInt Nmax, const MFloat *nodes, MFloat *weights)
Calculates the barycentric weights for Lagrange interpolation at thei specified nodes.
void calcLhat(const MFloat x, const MInt polyDeg, const MFloat *nodes, const MFloat *wInt, const MFloat *wBary, MFloat *Lhat)
Calculates the Lagrange polynomials evaluated at point x in [-1,1] and pre-divides them by the integr...
void calcPolynomialDerivativeMatrix(MInt Nmax, const MFloat *nodes, const MFloat *wBary, MFloat *derivMatrix)
Calculates the first derivative approximation matrix.
void calcLegendreGaussNodesAndWeights(MInt Nmax, MFloat *nodes, MFloat *wInt)
Calculate the Gauss integration nodes and weight for the Legendre polynomials on the interval [-1,...
void prolongToFaceGauss(const MFloat *const source, const MInt faceId, const MInt noNodes1D, const MFloat *const LFaceN, const MFloat *const LFaceP, MFloat *const destination)
Extrapolates ("prolongs") the Gauss node values of an element to a given face.
MBool ascendingAbsVal(MFloat i, MFloat j)
void calcDhat(MInt Nmax, const MFloat *nodes, const MFloat *wInt, const MFloat *wBary, MFloat *dhatMatrix)
Calculates the polynomial derivative matrix and normalizes it using the integration weights.
void prolongToFaceGaussLobatto(const T source, const MInt faceId, const MInt noNodes1D, U destination)
Extrapolates ("prolongs") the Gauss-Lobatto node values of an element to a given face.
void calcLegendrePolyAndDeriv(MInt Nmax, MFloat x, MFloat *polynomial, MFloat *derivative)
Evaluates the Legendre polynomial and its derivative of degree Nmax at point x.
void interpolateNodes(const T source, U vandermonde, MInt noNodesIn, MInt noNodesOut, MInt noVariables, V destination)
void calculateLegendrePolyAndDeriv(MInt Nmax, MFloat x, MFloat *polynomial, MFloat *derivative)
Evaluates the Legendre polynomial and its derivative of degree Nmax at point x.
Definition: maiamath.h:754
void calculateLegendreGaussNodesAndWeights(MInt Nmax, MFloat *nodes, MFloat *wInt)
Calculate the Gauss integration nodes and weight for the Legendre polynomials on the interval [-1,...
Definition: maiamath.h:806
Namespace for auxiliary functions/classes.