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