From 191ea91840b8cd361929eabba90fa320f2ced086 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, 27 Sep 2022 16:27:28 +0200
Subject: [PATCH] Added mesh as argument for '_get_point()'.

---
 DG_Approximation.py  | 20 ++++++++++++---
 Initial_Condition.py | 58 ++++++++++++++++++++++++++++++--------------
 projection_utils.py  |  8 ++++++
 3 files changed, 65 insertions(+), 21 deletions(-)

diff --git a/DG_Approximation.py b/DG_Approximation.py
index 76d0cbe..8409437 100644
--- a/DG_Approximation.py
+++ b/DG_Approximation.py
@@ -20,9 +20,23 @@ TODO: Discuss descriptions (matrices, cfl number, right-hand side,
     limiting slope, basis, wavelet, etc.)
 TODO: Discuss referencing info on SSPRK3
 
+TODO: Discuss why the left_factor is not subtracted for the second
+    discontinuity for the two-sided Heaviside
+TODO: Discuss order of addends for two-sided Heaviside
+TODO: Discuss whether to enforce positive shift in the two-sided Heaviside
+TODO: Discuss reasoning behind minimum mesh size of 2^5 instead of 2^3 for
+    training data
+TODO: Discuss why basis degree can be as high as 6 if it is only defined up
+    to 4 so far (alternative calculation?)
+TODO: Discuss whether domain other than [-1, 1] is in any way useful for
+    training
+
 Urgent:
-TODO: Introduce middle_factor for two-sided Heaviside
-TODO: Adjust polynomial degree for ANN Data Generator
+TODO: Introduce middle_factor for two-sided Heaviside -> Done
+TODO: Adjust mesh exponent for ANN Data Generator -> Done
+TODO: Fix index issue for mesh selection during training -> Done
+TODO: Add mesh as argument for _get_point() -> Done
+TODO: Replace induce_adjustment() with margin
 TODO: Rename 'adjustment' to 'shift'
 TODO: Induce shift in IC class
 TODO: Move plot_approximation_results() into plotting script
@@ -335,7 +349,7 @@ def do_initial_projection(initial_condition, mesh, basis, quadrature,
         for degree in range(basis.polynomial_degree + 1):
             new_row.append(np.float64(sum(initial_condition.calculate(
                 x=eval_point + mesh.cell_len/2
-                * quadrature.nodes[point] - adjustment)
+                * quadrature.nodes[point] - adjustment, mesh=mesh)
                 * basis.basis[degree].subs(
                     x, quadrature.nodes[point])
                 * quadrature.weights[point]
diff --git a/Initial_Condition.py b/Initial_Condition.py
index 8f23cde..39a8f3c 100644
--- a/Initial_Condition.py
+++ b/Initial_Condition.py
@@ -98,18 +98,18 @@ class InitialCondition(ABC):
         """
         pass
 
-    def calculate(self, x, mesh=None):
+    def calculate(self, x, mesh):
         """Evaluates function at given x-value.
 
-        If a mesh is given, the x-value is projected into its periodic
-        interval before evaluating the function.
+        In evaluation (not training) mode, the x-value is projected
+        into its periodic interval before evaluating the function.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
-        mesh : Mesh, optional
-            Mesh for calculation. Default: None.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -117,22 +117,24 @@ class InitialCondition(ABC):
             Value of function evaluates at x-value.
 
         """
-        if mesh is not None:
+        if mesh.mode is 'evaluation':
             left_bound, right_bound = mesh.bounds
             while x < left_bound:
                 x += mesh.interval_len
             while x > right_bound:
                 x -= mesh.interval_len
-        return self._get_point(x)
+        return self._get_point(x, mesh)
 
     @abstractmethod
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -185,13 +187,15 @@ class Sine(InitialCondition):
         config = {'factor': factor}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -215,13 +219,15 @@ class Box(InitialCondition):
         """Returns flag that function is not smooth."""
         return False
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -286,13 +292,15 @@ class FourPeakWave(InitialCondition):
         """Returns flag that function is not smooth."""
         return False
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -392,13 +400,15 @@ class Linear(InitialCondition):
         config = {'factor': factor}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -456,13 +466,15 @@ class LinearAbsolute(InitialCondition):
         config = {'factor': factor}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -511,13 +523,15 @@ class DiscontinuousConstant(InitialCondition):
         """Returns flag that function is not smooth."""
         return False
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -574,13 +588,15 @@ class Polynomial(InitialCondition):
         config = {'factor': factor, 'exponential': exponential}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -632,13 +648,15 @@ class Continuous(InitialCondition):
         config = {'factor': factor}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -702,13 +720,15 @@ class HeavisideOneSided(InitialCondition):
                   'discontinuity_position': self._discontinuity_position}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
@@ -799,13 +819,15 @@ class HeavisideTwoSided(InitialCondition):
                   'right_factor': right_factor, 'adjustment': adjustment}
         self._reset(config)
 
-    def _get_point(self, x):
+    def _get_point(self, x, mesh):
         """Evaluates function at given x-value.
 
         Parameters
         ----------
         x : float
             Evaluation point of function.
+        mesh : Mesh
+            Mesh for calculation.
 
         Returns
         -------
diff --git a/projection_utils.py b/projection_utils.py
index 91ba273..9a0553d 100644
--- a/projection_utils.py
+++ b/projection_utils.py
@@ -26,6 +26,8 @@ class Mesh:
 
     Attributes
     ----------
+    mode : str
+        Mode for mesh use. Either 'training' or 'evaluation'.
     num_grid_cells : int
         Number of cells in the mesh (ghost cells notwithstanding). Usually
         exponential of 2.
@@ -62,6 +64,7 @@ class Mesh:
 
         """
         self._num_grid_cells = num_grid_cells
+        self._mode = 'training' if training_data_mode else 'evaluation'
         if not training_data_mode:
             if not math.log(self._num_grid_cells, 2).is_integer():
                 raise ValueError('The number of cells in the mesh has to be '
@@ -70,6 +73,11 @@ class Mesh:
         self._left_bound = left_bound
         self._right_bound = right_bound
 
+    @property
+    def mode(self) -> str:
+        """Return mode ('training' or 'evaluation')."""
+        return self._mode
+
     @property
     def num_grid_cells(self) -> int:
         """Return number of grid cells."""
-- 
GitLab