# -*- coding: utf-8 -*- """ @author: Laura C. Kühle """ from abc import ABC, abstractmethod import time from .Equation import Equation class UpdateScheme(ABC): """Abstract class for updating projections at a time step. Methods ------- get_name() Returns string of class name. step(projection, cfl_number) Performs time step. """ def __init__(self, detector, limiter, equation): """Initializes UpdateScheme. Parameters ---------- detector : TroubledCellDetector object Troubled cell detector for evaluation. limiter : Limiter object Limiter for evaluation. equation: Equation Equation. """ # Unpack positional arguments self._detector = detector self._limiter = limiter self._equation = equation self._reset() def _reset(self): """Resets instance variables.""" def get_name(self): """Returns string of class name.""" return self.__class__.__name__ def step(self, projection, cfl_number): """Performs time step. Parameters ---------- projection : ndarray Matrix of projection for each polynomial degree. cfl_number : float CFL number to ensure stability. Returns ------- current_projection : ndarray Matrix of projection of current update step for each polynomial degree. troubled_cells : list List of indices for all detected troubled cells. """ current_projection, troubled_cells = self._apply_stability_method( projection, cfl_number) return current_projection, troubled_cells @abstractmethod def _apply_stability_method(self, projection, cfl_number): """Applies stability method. Parameters ---------- projection : ndarray Matrix of projection for each polynomial degree. cfl_number : float CFL number to ensure stability. Returns ------- current_projection : ndarray Matrix of projection of current update step for each polynomial degree. troubled_cells : list List of indices for all detected troubled cells. """ pass def _apply_limiter(self, current_projection): """Applies limiter on troubled cells. Parameters ---------- current_projection : ndarray Matrix of projection of current update step for each polynomial degree. Returns ------- new_projection : ndarray Matrix of updated projection for each polynomial degree. troubled_cells : list List of indices for all detected troubled cells. """ troubled_cells = self._detector.get_cells(current_projection) new_projection = self._limiter.apply(current_projection, troubled_cells) return new_projection, troubled_cells class SSPRK3(UpdateScheme): """Class for strong stability-preserving Runge Kutta of order 3. Notes ----- Reference (?) """ # Override method of superclass def _apply_stability_method(self, projection, cfl_number): """Applies stability method. Parameters ---------- projection : ndarray Matrix of projection for each polynomial degree. cfl_number : float CFL number to ensure stability. Returns ------- current_projection : ndarray Matrix of projection of current update step for each polynomial degree. troubled_cells : list List of indices for all detected troubled cells. """ original_projection = projection current_projection = self._apply_first_step(original_projection, cfl_number) current_projection, __ = self._apply_limiter(current_projection) current_projection = self._apply_second_step(original_projection, current_projection, cfl_number) current_projection, __ = self._apply_limiter(current_projection) current_projection = self._apply_third_step(original_projection, current_projection, cfl_number) current_projection, troubled_cells = self._apply_limiter( current_projection) return current_projection, troubled_cells def _apply_first_step(self, original_projection, cfl_number): """Applies first step of SSPRK3. Parameters ---------- original_projection : ndarray Matrix of original projection for each polynomial degree. cfl_number : float CFL number to ensure stability. Returns ------- ndarray Matrix of updated projection for each polynomial degree. """ right_hand_side = self._equation.update_right_hand_side( original_projection) return original_projection + (cfl_number*right_hand_side) def _apply_second_step(self, original_projection, current_projection, cfl_number): """Applies second step of SSPRK3. Parameters ---------- original_projection : ndarray Matrix of original projection for each polynomial degree. current_projection : ndarray Matrix of projection of current update step for each polynomial degree. cfl_number : float CFL number to ensure stability. Returns ------- ndarray Matrix of updated projection for each polynomial degree. """ right_hand_side = self._equation.update_right_hand_side( current_projection) return 1/4 * (3*original_projection + (current_projection + cfl_number*right_hand_side)) def _apply_third_step(self, original_projection, current_projection, cfl_number): """Applies third step of SSPRK3. Parameter --------- original_projection : ndarray Matrix of original projection for each polynomial degree. current_projection : ndarray Matrix of projection of current update step for each polynomial degree. cfl_number : float CFL number to ensure stability. Returns ------- ndarray Matrix of updated projection for each polynomial degree. """ right_hand_side = self._equation.update_right_hand_side( current_projection) return 1/3 * (original_projection + 2*(current_projection + cfl_number*right_hand_side))