Source code for mtnlion.deprecated_engine

"""Equation solver."""
import logging
from typing import Callable, Dict, List, Union

import munch
import numpy as np

from mtnlion.tools import ldp

LOGGER = logging.getLogger(__name__)


[docs]def rmse(estimated: np.ndarray, true: np.ndarray) -> Union[np.ndarray, None]: """ Calculate the root-mean-squared error between two arrays. :param estimated: estimated solution :param true: 'true' solution :return: root-mean-squared error """ return np.sqrt(((estimated - true) ** 2).mean(axis=1))
[docs]def fetch_params(filename: str) -> Union[Dict[str, Dict[str, float]], None, munch.DefaultMunch]: """TODO: read template from config file.""" print("Loading Cell Parameters") params = {} sheet = ldp.read_excel(filename, 0) (ncol, pcol) = (2, 3) params["const"] = ldp.load_params(sheet, range(7, 15), ncol, pcol) params["neg"] = ldp.load_params(sheet, range(18, 43), ncol, pcol) params["sep"] = ldp.load_params(sheet, range(47, 52), ncol, pcol) params["pos"] = ldp.load_params(sheet, range(55, 75), ncol, pcol) return munch.DefaultMunch.fromDict(params)
[docs]def find_ind(data: np.ndarray, value: Union[List[int], List[float]]) -> np.ndarray: """ Find the indices of the values given in the data. :param data: data to find indices in :param value: values to find indices with :return: indices of value in data """ return np.nonzero(np.in1d(data, value))[0]
[docs]def find_ind_near(data: np.ndarray, value: Union[List[int], List[float]]) -> np.ndarray: """ Find the indices of the closest values given in the data. :param data: data to find indices in :param value: values to find indices with :return: indices of value in data """ return np.array([(np.abs(data - v)).argmin() for v in value])
# TODO: move subdomain logic here
[docs]class Mountain: """Container for holding n-variable n-dimensional data in space and time.""" def __init__( self, mesh: np.ndarray, time_mesh: np.ndarray, boundaries: Union[np.ndarray, List[float]], **kwargs: np.ndarray ) -> None: """ Store the solutions to each given parameter. :param mesh: Solution mesh :param boundaries: internal boundaries in the mesh :param kwargs: arrays for each solution """ LOGGER.info("Initializing solution data...") self.data = munch.Munch(kwargs) self.mesh = mesh self.time_mesh = time_mesh self.boundaries = boundaries
[docs] def to_dict(self) -> Dict[str, np.ndarray]: """ Retrieve dictionary of Mountain to serialize. :return: data dictionary """ domain = {"mesh": self.mesh, "time_mesh": self.time_mesh, "boundaries": self.boundaries} return dict(domain, **self.data)
[docs] @classmethod def from_dict(cls, data: Dict[str, np.ndarray]) -> "Mountain": """ Convert dictionary to SolutionData. :param data: dictionary of formatted data :return: consolidated simulation data """ return cls(data.pop("mesh"), data.pop("time_mesh"), data.pop("boundaries"), **data)
[docs] def filter(self, index: List, func: Callable = lambda x: x) -> Dict[str, np.ndarray]: """ Filter through dictionary to collect sections of the contained ndarrays. :param index: subset of arrays to collect :param func: function to call on every variable in data :return: dictionary of reduced arrays """ return {k: func(v[index]) for k, v in self.data.items() if not np.isscalar(v)}
[docs] def filter_time(self, index: List, func: Callable = lambda x: x) -> "Mountain": """ Filter the Mountain for a subset of time indices. For example:: solution.filter_time(slice(0,5)) solution.filter_time([0, 3, 5]) solution.filter_time(slice(step=-1)) solution.filter_time(numpy.where(solution.time_mesh == time) # time could be [1, 2, 3] seconds will return the solutions from time index [0, 4], [0, 3, 5], reverse time, and fetch specific times respectively. :param index: indices or slices of time to retrieve :param func: function to call on every variable in data :return: time filtered Mountain """ return type(self)(self.mesh, func(self.time_mesh[index]), self.boundaries, **self.filter(index, func=func))
[docs] def filter_space(self, index: List, func: Callable = lambda x: x) -> "Mountain": """ Filter the Mountain for a subset of space indices. For example:: solution.filter_time([slice(0,5), 4]) # for 2D space solution.filter_time([0, 3, 5]) solution.filter_time(slice(step=-1)) will return the solutions from in space where x=[0, 5] and y=5, and x=[0, 3, 5], even reverse the first dimension respectively. :param index: indices or slices of space to retrieve :param func: function to call on every variable in data :return: space filtered Mountain """ # TODO: FIXME, shouldn't know anything about cs solid_concentration = self.data.cs tmp = type(self)( func(self.mesh[index]), self.time_mesh, self.boundaries, **self.filter([...] + index, func=func) ) tmp.data.cs = solid_concentration return tmp