Source code for biosteam.exceptions

# -*- coding: utf-8 -*-
# BioSTEAM: The Biorefinery Simulation and Techno-Economic Analysis Modules
# Copyright (C) 2020-2023, Yoel Cortes-Pena <yoelcortes@gmail.com>
# 
# This module is under the UIUC open-source license. See 
# github.com/BioSTEAMDevelopmentGroup/biosteam/blob/master/LICENSE.txt
# for license details.
"""
"""
from thermosteam import exceptions
from thermosteam.exceptions import *
from warnings import warn

__all__ = (
    'DesignError', 
    'FailedEvaluation',
    'Converged',
    'UnitWarning',
    'DesignWarning', 
    'CostWarning',
    'lb_warning',
    'ub_warning',
    'bounds_warning',
    *exceptions.__all__)
del exceptions

# %% Biosteam errors

[docs] class DesignError(RuntimeError): """RuntimeError regarding unit design."""
[docs] class FailedEvaluation(RuntimeWarning): """RuntimeWarning regarding failed model evaluation."""
[docs] class Converged(Exception): """Exception to stop iteration early."""
# %% BioSTEAM warnings
[docs] class UnitWarning(Warning): """Warning regarding unit operations."""
[docs] @classmethod def from_source(cls, source, msg): """Return a DesignWarning object with source description.""" msg= message_with_object_stamp(source, msg) return cls(msg)
[docs] class DesignWarning(UnitWarning): """Warning regarding design constraints."""
[docs] class CostWarning(UnitWarning): """Warning regarding design constraints."""
# %% Bounds checking def design_warning_with_source(source, msg): # pragma: no cover """Return a DesignWarning object with source description.""" msg= message_with_object_stamp(source, msg) return DesignWarning(msg) def lb_warning(source, key, value, units, lb, stacklevel=2): # pragma: no cover units = ' ' + units if units else '' try: msg = f"{key} ({value:.4g}{units}) is out of bounds (minimum {lb:.4g}{units})." except: # Handle format errors msg = f"{key} ({value:.4g}{units}) is out of bounds (minimum {lb}{units})." warn(DesignWarning.from_source(source, msg), stacklevel=stacklevel) def ub_warning(source, key, value, units, ub, stacklevel=2): # pragma: no cover units = ' ' + units if units else '' try: msg = f"{key} ({value:.4g}{units}) is out of bounds (maximum {ub:.4g}{units})." except: # Handle format errors msg = f"{key} ({value:.4g}{units}) is out of bounds (maximum {ub}{units})." warn(DesignWarning.from_source(source, msg), stacklevel=stacklevel)
[docs] def bounds_warning(source, key, value, units, bounds, kind='design'): # pragma: no cover """Issue a warning if value is out of bounds. Parameters ---------- source : Unit Unit where the warning is issued key : str Name of value. value : float units : str Units of value bounds : Iterable[float, float] Upper and lower bounds. """ # Warn when value is out of bounds lb, ub = bounds if not (lb <= value <= ub): units = ' ' + units if units else '' try: msg = f"{key} ({value:.4g}{units}) is out of bounds ({lb:.4g} to {ub:.4g}{units})" except: # Handle format errors msg = f"{key} ({value:.4g}{units}) is out of bounds ({lb} to {ub}{units})" if kind == 'design': Warning = DesignWarning msg += ' for design algorithm' elif kind == 'cost': msg += ' for cost correlation' Warning = CostWarning else: raise ValueError(f"kind must be either 'design' or 'cost', not {repr(kind)}") warning = Warning.from_source(source, msg) warn(warning, stacklevel=3)