Skip to content
Snippets Groups Projects
Commit 8feca170 authored by Laura Christine Kühle's avatar Laura Christine Kühle
Browse files

Added documentation to 'Troubled_Cell_Detector'.

parent 95622687
Branches
No related tags found
No related merge requests found
......@@ -4,6 +4,8 @@
TODO: Adjust TCs for wavelet detectors (sliding window over all cells instead of every second)
TODO: Adjust Boxplot approach (adjacent cells, outer fence, etc.)
TODO: Give detailed description of wavelet detection
TODO: Load ANN state and config in reset
"""
import numpy as np
......@@ -21,8 +23,58 @@ z = Symbol('z')
class TroubledCellDetector(object):
"""Class for troubled-cell detection.
Detects troubled cells, i.e., cells in the mesh containing instabilities.
Attributes
----------
interval_len : float
Length of the interval between left and right boundary.
cell_len : float
Length of a cell in mesh.
Methods
-------
get_name()
Returns string of class name.
get_cells(projection)
Calculates troubled cells in a given projection.
calculate_cell_average_and_reconstructions(projection, stencil_length)
Calculates cell averages and reconstructions for a given projection.
plot_results(projection, troubled_cell_history, time_history)
Plots results and troubled cells of a projection given its evaluation history.
"""
def __init__(self, config, mesh, wave_speed, polynomial_degree, num_grid_cells, final_time,
left_bound, right_bound, basis, init_cond, quadrature):
"""Initializes TroubledCellDetector.
Parameters
----------
mesh : array
List of mesh valuation points.
wave_speed : float
Speed of wave in rightward direction.
polynomial_degree : int
Polynomial degree.
num_grid_cells : int
Number of cells in the mesh. Usually exponential of 2.
final_time : float
Final time for which approximation is calculated.
left_bound : float
Left boundary of interval.
right_bound : float
Right boundary of interval. Default: 1.
Additional parameters for detector object. Default: {}.
basis : Basis object
Basis for calculation.
init_cond : InitialCondition object
Initial condition for evaluation.
quadrature : Quadrature object
Quadrature for evaluation.
"""
self._mesh = mesh
self._wave_speed = wave_speed
self._polynomial_degree = polynomial_degree
......@@ -43,24 +95,58 @@ class TroubledCellDetector(object):
self._reset(config)
def _check_colors(self):
"""Checks plot colors.
Checks whether colors for plots were given and sets them if required.
"""
self._colors['exact'] = self._colors.get('exact', 'k-')
self._colors['approx'] = self._colors.get('approx', 'y')
def _reset(self, config):
"""Resets instance variables.
Parameters
----------
config : dict
Additional parameters for detector.
"""
sns.set()
def get_name(self):
"""Returns string of class name."""
return self.__class__.__name__
def get_cells(self, projection):
"""Calculates troubled cells in a given projection.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
"""
pass
def calculate_cell_average_and_reconstructions(self, projection, stencil_length):
"""
"""Calculates cell averages and reconstructions for a given projection.
Calculate the cell averages of all cells in a projection. Reconstructions are only
calculated for the middle cell and added left and right to it, respectively.
Here come some parameter.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
stencil_length : int
Size of data array.
Returns
-------
np.array
Matrix containing cell averages and reconstructions for initial projection.
"""
cell_averages = calculate_approximate_solution(
projection, [0], 0, self._basis.get_basis_vector())
......@@ -74,6 +160,18 @@ class TroubledCellDetector(object):
right_reconstructions[:, middle_idx], cell_averages[:, middle_idx+1:]))))
def plot_results(self, projection, troubled_cell_history, time_history):
"""Plots results and troubled cells of a projection given its evaluation history.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
troubled_cell_history : list
List of detected troubled cells for each time step.
time_history:
List of value of each time step.
"""
plot_shock_tube(self._num_grid_cells, troubled_cell_history, time_history)
max_error = self._plot_mesh(projection)
......@@ -82,6 +180,19 @@ class TroubledCellDetector(object):
print('maximum error =', max_error)
def _plot_mesh(self, projection):
"""Plots exact and approximate solution as well as errors.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
max_error
Maximum error between exact and approximate solution.
"""
grid, exact = calculate_exact_solution(
self._mesh[2:-2], self._cell_len, self._wave_speed, self._final_time,
self._interval_len, self._quadrature, self._init_cond)
......@@ -101,12 +212,52 @@ class TroubledCellDetector(object):
class NoDetection(TroubledCellDetector):
"""Class without any troubled_cell detection.
Methods
-------
get_cells(projection)
Returns no troubled cells.
"""
def get_cells(self, projection):
"""Returns no troubled cells.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
"""
return []
class ArtificialNeuralNetwork(TroubledCellDetector):
"""Class for troubled-cell detection using ANNs.
Attributes
----------
stencil_length : int
Size of input data array.
model : ANNModel object
ANN model instance for evaluation.
Methods
-------
get_cells(projection)
Calculates troubled cells in a given projection.
"""
def _reset(self, config):
"""Resets instance variables.
Parameters
----------
config : dict
Additional parameters for detector.
"""
super()._reset(config)
self._stencil_len = config.pop('stencil_len', 3)
......@@ -122,6 +273,19 @@ class ArtificialNeuralNetwork(TroubledCellDetector):
self._model = getattr(ANN_Model, self._model)(self._model_config)
def get_cells(self, projection):
"""Calculates troubled cells in a given projection.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
list
List of indices for all troubled cells.
"""
# Reset ghost cells to adjust for stencil length
num_ghost_cells = self._stencil_len//2
projection = projection[:, 1:-1]
......@@ -145,13 +309,31 @@ class ArtificialNeuralNetwork(TroubledCellDetector):
class WaveletDetector(TroubledCellDetector):
"""Class for troubled-cell detection based on wavelet coefficients.
???
"""
def _check_colors(self):
"""Checks plot colors.
Checks whether colors for plots were given and sets them if required.
"""
self._colors['fine_exact'] = self._colors.get('fine_exact', 'k-.')
self._colors['fine_approx'] = self._colors.get('fine_approx', 'b-.')
self._colors['coarse_exact'] = self._colors.get('coarse_exact', 'k-')
self._colors['coarse_approx'] = self._colors.get('coarse_approx', 'y')
def _reset(self, config):
"""Resets instance variables.
Parameters
----------
config : dict
Additional parameters for detector.
"""
super()._reset(config)
# Set additional necessary parameter
......@@ -160,10 +342,36 @@ class WaveletDetector(TroubledCellDetector):
= self._basis.get_multiwavelet_projections()
def get_cells(self, projection):
"""Calculates troubled cells in a given projection.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
list
List of indices for all troubled cells.
"""
multiwavelet_coeffs = self._calculate_wavelet_coeffs(projection[:, 1: -1])
return self._get_cells(multiwavelet_coeffs, projection)
def _calculate_wavelet_coeffs(self, projection):
"""Calculates wavelet coefficients used for projection to coarser grid.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
np.array
Matrix of wavelet coefficients.
"""
output_matrix = []
for i in range(self._num_coarse_grid_cells):
new_entry = 0.5*(projection[:, 2*i] @ self._wavelet_projection_left
......@@ -172,9 +380,38 @@ class WaveletDetector(TroubledCellDetector):
return np.transpose(np.array(output_matrix))
def _get_cells(self, multiwavelet_coeffs, projection):
"""Calculates troubled cells using multiwavelet coefficients.
Parameters
----------
multiwavelet_coeffs : np.array
Matrix of multiwavelet coefficients.
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
list
List of indices for all troubled cells.
"""
return []
def plot_results(self, projection, troubled_cell_history, time_history):
"""Plots results and troubled cells of a projection given its evaluation history.
Plots results on coarse and fine grid, errors, troubled cells, and coefficient details.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
troubled_cell_history : list
List of detected troubled cells for each time step.
time_history:
List of value of each time step.
"""
multiwavelet_coeffs = self._calculate_wavelet_coeffs(projection)
coarse_projection = self._calculate_coarse_projection(projection)
plot_details(projection[:, 1:-1], self._mesh[2:-2], coarse_projection,
......@@ -184,6 +421,19 @@ class WaveletDetector(TroubledCellDetector):
super().plot_results(projection, troubled_cell_history, time_history)
def _calculate_coarse_projection(self, projection):
"""Calculates coarse projection.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
np.array
Matrix of projection on coarse grid for each polynomial degree.
"""
basis_projection_left, basis_projection_right = self._basis.get_basis_projections()
# Remove ghost cells
......@@ -200,6 +450,20 @@ class WaveletDetector(TroubledCellDetector):
return coarse_projection
def _plot_mesh(self, projection):
"""Plots exact and approximate solution as well as errors.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
max_error
Maximum error between exact and approximate solution.
"""
grid, exact = calculate_exact_solution(
self._mesh[2:-2], self._cell_len, self._wave_speed, self._final_time,
self._interval_len, self._quadrature, self._init_cond)
......@@ -220,6 +484,14 @@ class WaveletDetector(TroubledCellDetector):
return max_error
def _plot_coarse_mesh(self, projection):
"""Plots exact and approximate solution as well as errors for a coarse projection.
Parameters
----------
projection : np.array
Matrix of projection for each polynomial degree.
"""
coarse_cell_len = 2*self._cell_len
coarse_mesh = np.arange(self._left_bound - (0.5*coarse_cell_len),
self._right_bound + (1.5*coarse_cell_len),
......@@ -239,7 +511,25 @@ class WaveletDetector(TroubledCellDetector):
class Boxplot(WaveletDetector):
"""Class for troubled-cell detection based on Boxplots.
Attributes
----------
fold_len : int
Length of folds considered in one Boxplot.
whisker_len : int
Length of Boxplot whiskers.
"""
def _reset(self, config):
"""Resets instance variables.
Parameters
----------
config : dict
Additional parameters for detector.
"""
super()._reset(config)
# Unpack necessary configurations
......@@ -247,6 +537,21 @@ class Boxplot(WaveletDetector):
self._whisker_len = config.pop('whisker_len', 3)
def _get_cells(self, multiwavelet_coeffs, projection):
"""Calculates troubled cells using multiwavelet coefficients.
Parameters
----------
multiwavelet_coeffs : np.array
Matrix of multiwavelet coefficients.
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
list
List of indices for all troubled cells.
"""
indexed_coeffs = [[multiwavelet_coeffs[0, i], i]for i in range(self._num_coarse_grid_cells)]
if self._num_coarse_grid_cells < self._fold_len:
......@@ -287,7 +592,16 @@ class Boxplot(WaveletDetector):
class Theoretical(WaveletDetector):
""""Class for troubled-cell detection based on the projection averages and a cutoff factor.
Attributes
----------
cutoff_factor : float
Cutoff factor above which a cell is considered troubled.
"""
def _reset(self, config):
"""Resets instance variables."""
super()._reset(config)
# Unpack necessary configurations
......@@ -295,6 +609,21 @@ class Theoretical(WaveletDetector):
# comment to line above: or 2 or 3
def _get_cells(self, multiwavelet_coeffs, projection):
"""Calculates troubled cells using multiwavelet coefficients.
Parameters
----------
multiwavelet_coeffs : np.array
Matrix of multiwavelet coefficients.
projection : np.array
Matrix of projection for each polynomial degree.
Returns
-------
list
List of indices for all troubled cells.
"""
troubled_cells = []
max_avg = np.sqrt(0.5) * max(1, max(abs(projection[0][cell+1])
for cell in range(self._num_coarse_grid_cells)))
......@@ -306,6 +635,23 @@ class Theoretical(WaveletDetector):
return troubled_cells
def _is_troubled_cell(self, multiwavelet_coeffs, cell, max_avg):
"""Checks whether a cell is troubled.
Parameters
----------
multiwavelet_coeffs : np.array
Matrix of multiwavelet coefficients.
cell
Index of cell.
max_avg
Maximum average of projection.
Returns
-------
boolean
Flag whether cell is troubled.
"""
max_value = max(abs(multiwavelet_coeffs[degree][cell])
for degree in range(self._polynomial_degree+1))/max_avg
eps = self._cutoff_factor / (self._cell_len*self._num_coarse_grid_cells*2)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment