From ae52db8f1bcff5477daa55f9d7287515a951350e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=BChle=2C=20Laura=20Christine=20=28lakue103=29?=
 <laura.kuehle@uni-duesseldorf.de>
Date: Tue, 26 Apr 2022 13:38:19 +0200
Subject: [PATCH] Hard-coded simplification of cell average and reconstruction
 calculations for OrthonormalLegendre.

---
 Basis_Function.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/Basis_Function.py b/Basis_Function.py
index 43fba03..1563cf8 100644
--- a/Basis_Function.py
+++ b/Basis_Function.py
@@ -412,3 +412,82 @@ class OrthonormalLegendre(Legendre):
                 row.append(np.float64(entry))
             matrix.append(row)
         return matrix
+
+    def calculate_cell_average(self, projection, stencil_length,
+                               add_reconstructions=True):
+        """Calculate cell averages for a given projection.
+
+        Calculate the cell averages of all cells in a projection.
+        If desired, reconstructions are calculated for the middle cell
+        and added left and right to it, respectively.
+
+        Notes
+        -----
+            To increase speed. this function uses a simplified calculation
+            specific to the orthonormal Legendre polynomial basis.
+
+        Parameters
+        ----------
+        projection : ndarray
+            Matrix of projection for each polynomial degree.
+        stencil_length : int
+            Size of data array.
+        add_reconstructions: bool, optional
+            Flag whether reconstructions of the middle cell are included.
+            Default: True.
+
+        Returns
+        -------
+        ndarray
+            Matrix containing cell averages (and reconstructions) for given
+            projection.
+
+        """
+
+        cell_averages = np.array([projection[0] / np.sqrt(2)])
+
+        if add_reconstructions:
+            middle_idx = stencil_length // 2
+            left_reconstructions, right_reconstructions = \
+                self._calculate_reconstructions(
+                    projection[:, middle_idx:middle_idx+1])
+            return np.array(list(map(
+                np.float64, zip(cell_averages[:, :middle_idx],
+                                left_reconstructions,
+                                cell_averages[:, middle_idx],
+                                right_reconstructions,
+                                cell_averages[:, middle_idx+1:]))))
+        return np.array(list(map(np.float64, cell_averages)))
+
+    def _calculate_reconstructions(self, projection):
+        """Calculate left and right reconstructions for a given projection.
+
+        Notes
+        -----
+            To increase speed. this function uses a simplified calculation
+            specific to the orthonormal Legendre polynomial basis.
+
+        Parameters
+        ----------
+        projection : ndarray
+            Matrix of projection for each polynomial degree.
+
+        Returns
+        -------
+        left_reconstruction: list
+            List containing left reconstructions for given projection.
+        right_reconstruction: list
+            List containing right reconstructions for given projection.
+
+        """
+
+        left_reconstructions = [
+            sum(projection[degree][cell] * (-1)**degree
+                * np.sqrt(degree + 0.5)
+                for degree in range(self._polynomial_degree+1))
+            for cell in range(len(projection[0]))]
+        right_reconstructions = [
+            sum(projection[degree][cell] * np.sqrt(degree + 0.5)
+                for degree in range(self._polynomial_degree+1))
+            for cell in range(len(projection[0]))]
+        return left_reconstructions, right_reconstructions
-- 
GitLab