Source code for watertap.core.control_volume_isothermal

#################################################################################
# WaterTAP Copyright (c) 2020-2024, The Regents of the University of California,
# through Lawrence Berkeley National Laboratory, Oak Ridge National Laboratory,
# National Renewable Energy Laboratory, and National Energy Technology
# Laboratory (subject to receipt of any required approvals from the U.S. Dept.
# of Energy). All rights reserved.
#
# Please see the files COPYRIGHT.md and LICENSE.md for full copyright and license
# information, respectively. These files are also available online at the URL
# "https://github.com/watertap-org/watertap/"
#################################################################################

from pyomo.environ import Constraint

from idaes.core import declare_process_block_class, EnergyBalanceType
from idaes.core.base.control_volume_base import ControlVolumeBlockData as _CV
from idaes.core.base.control_volume0d import ControlVolume0DBlockData as _CV0D
from idaes.core.base.control_volume1d import ControlVolume1DBlockData as _CV1D
from idaes.core.util.exceptions import ConfigurationError

import idaes.core.util.scaling as iscale


class _IsothermalEnergyBalanceCheckerMixin:
    def _validate_isothermal_energy_balance_compatibility(self):
        if self._constructed_energy_balance_type is not EnergyBalanceType.none:
            raise ConfigurationError(
                "When using the isothermal assumption, the EnergyBalanceType must be EnergyBalanceType.none"
            )

    def add_energy_balances(self, balance_type=EnergyBalanceType.useDefault, **kwargs):
        super().add_energy_balances(balance_type=balance_type, **kwargs)
        if hasattr(self, "isothermal_assumption_eq"):
            self._validate_isothermal_energy_balance_compatibility()

    def add_isothermal_assumption(self):
        if hasattr(self, "_constructed_energy_balance_type"):
            self._validate_isothermal_energy_balance_compatibility()


# put the usual docstring on add_energy_balances
_IsothermalEnergyBalanceCheckerMixin.add_energy_balances.__doc__ = (
    _CV.add_energy_balances.__doc__
)


[docs]@declare_process_block_class("ControlVolume0DBlock") class ControlVolume0DBlockData(_IsothermalEnergyBalanceCheckerMixin, _CV0D): def add_isothermal_assumption(self): super().add_isothermal_assumption() @self.Constraint( self.flowsheet().time, doc="Isothermal assumption for 0D control volume", ) def isothermal_assumption_eq(b, t): return b.properties_out[t].temperature == b.properties_in[t].temperature def calculate_scaling_factors(self): super().calculate_scaling_factors() if hasattr(self, "isothermal_assumption_eq"): for t, c in self.isothermal_assumption_eq.items(): sf = iscale.get_scaling_factor( self.properties_in[t].temperature, default=1e-2, warning=True ) iscale.constraint_scaling_transform(c, sf, overwrite=False)
[docs]@declare_process_block_class("ControlVolume1DBlock") class ControlVolume1DBlockData(_IsothermalEnergyBalanceCheckerMixin, _CV1D): def add_isothermal_assumption(self): super().add_isothermal_assumption() @self.Constraint( self.flowsheet().time, self.length_domain, doc="Isothermal assumption for 1D control volume", ) def isothermal_assumption_eq(b, t, x): if x == b.length_domain.first(): return Constraint.Skip return ( b.properties[t, b.length_domain.first()].temperature == b.properties[t, x].temperature ) def calculate_scaling_factors(self): super().calculate_scaling_factors() if hasattr(self, "isothermal_assumption_eq"): for (t, x), c in self.isothermal_assumption_eq.items(): sf = iscale.get_scaling_factor( self.properties[t, x].temperature, default=1e-2, warning=True ) iscale.constraint_scaling_transform(c, sf, overwrite=False)