Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • update-goal-generator
  • add-overrides==4.1.2
  • eval-v1
  • eval-v2
  • dev
6 results

README.md

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    Update_Scheme.py 6.94 KiB
    # -*- 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))