Source code for pypint.plugins.plotters.reduction_residual_plotter

# coding=utf-8
"""

.. moduleauthor:: Torbjörn Klatt <[email protected]>
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import is_interactive

from pypint.plugins.plotters.i_plotter import IPlotter
from pypint.solvers.i_iterative_time_solver import IIterativeTimeSolver
from pypint.solvers.states import ISolverState
from pypint.solvers.diagnosis.norms import supremum_norm
from pypint.utilities import assert_is_instance, assert_condition, assert_named_argument
from pypint.utilities.logging import LOG


[docs]class ReductionResidualPlotter(IPlotter): """Plotts residual and reduction of multiple solutions of an iterative time solver See Also -------- :py:class:`.IPlotter` : overridden class """ _colors = np.array(['b', 'g', 'r', 'c', 'm', 'y', 'k']) _styles = np.array(['o', 'v', '^', '<', '>', 's', 'p', '*', '+', 'x', 'D']) def __init__(self, *args, **kwargs): super(ReductionResidualPlotter, self).__init__(args, **kwargs) self._solvers = None self._states = None self._nodes = None self.__reduction_limits = [0.0, 0.0] self.__residual_limits = [0.0, 0.0]
[docs] def plot(self, *args, **kwargs): """Plots the solution and optional also the error for each iteration. If ``file_name`` has been specified on initialization (see :py:meth:`.IPlotter.__init__`) the plot is stored there. Otherwise an interactive plotting session is started. Parameters ---------- solvers : :py:class:`.IIterativeTimeSolver` solver instances used to calculate the solutions states : :py:class:`.ISolverState` states of the solvers Raises ------ ValueError * if ``solvers`` is not given or is not a :py:class:`numpy.ndarray` of :py:class:`.IIterativeTimeSolver` * if ``states`` is not given or is not a :py:class:`numpy.ndarray` of :py:class:`.ISolverState` * if ``states`` has more than 7 states * if the size of ``states`` does not equal the size of ``solvers`` """ super(ReductionResidualPlotter, self).plot(args, **kwargs) assert_named_argument('solvers', kwargs, types=np.ndarray, descriptor="Solver", checking_obj=self) [assert_is_instance(_solver, IIterativeTimeSolver, descriptor="All Solvers", checking_obj=self) for _solver in kwargs['solvers']] self._solvers = kwargs['solvers'] assert_named_argument('states', kwargs, types=np.ndarray, descriptor="States", checking_obj=self) assert_condition(kwargs['states'].size <= 7, ValueError, "Can only handle up to 7 solutions: %d" % kwargs['states'].size, self) [assert_is_instance(_state, ISolverState, descriptor="All States", checking_obj=self) for _state in kwargs['states']] self._states = kwargs['states'] assert_condition(self._solvers.size == self._states.size, ValueError, message="Number of solvers must equal number of states: %d != %d" % (self._solvers.size, self._states.size), checking_obj=self) self._nodes = self._states[0].first.time_points if self._solvers[0].problem.time_start != self._nodes[0]: self._nodes = np.concatenate(([self._solvers[0].problem.time_start], self._nodes)) if self._solvers[0].problem.time_end != self._nodes[-1]: self._nodes = np.concatenate((self._nodes, [self._solvers[0].problem.time_end])) plt.title("Residuals and Reduction per Iteration for different Lambdas") self._plot_residuals_reductions() if self._file_name is not None: fig = plt.gcf() fig.set_dpi(300) fig.set_size_inches((15., 15.)) LOG.debug("Plotting figure with size (w,h) {:s} inches and {:d} DPI." .format(fig.get_size_inches(), fig.get_dpi())) fig.savefig(self._file_name) if is_interactive(): plt.show(block=True) else: plt.close('all')
def _plot_residuals_reductions(self): plt.hold(True) for _state in range(0, self._states.size): self._add_solution_plot(_state) LOG.debug("Plotting within {:s} x {:s}".format(self.__residual_limits, self.__reduction_limits)) _limits = [0.0, 0.0] _limits[0] = min(self.__residual_limits[0], self.__reduction_limits[0]) _limits[1] = max(self.__residual_limits[0], self.__reduction_limits[1]) plt.xlabel("residual") plt.xlim(_limits) plt.ylabel("reduction") plt.ylim(_limits) #plt.legend(loc=4) plt.grid(True) def _add_solution_plot(self, index): _res = np.zeros(len(self._states[index]) - 1) _red = np.zeros(len(self._states[index]) - 1) for i in range(1, len(self._states[index])): _res[i - 1] = supremum_norm(self._states[index][i].solution.residuals[-1].value) _red[i - 1] = supremum_norm(self._states[index].solution.solution_reduction(i)) if _res.min() < self.__residual_limits[0]: self.__residual_limits[0] = _res.min() if _res.max() > self.__residual_limits[1]: self.__residual_limits[1] = _res.max() if _red.min() < self.__reduction_limits[0]: self.__reduction_limits[0] = _red.min() if _red.max() > self.__reduction_limits[1]: self.__reduction_limits[1] = _red.max() plt.loglog(_res, _red, color=ReductionResidualPlotter._colors[index])