Source code for cosapp.ports.mode_variable
"""This module defines the basic class encapsulating mode variable attributes."""
from __future__ import annotations
import copy
from typing import Any, Optional, TYPE_CHECKING
from cosapp.ports.enum import Scope
from cosapp.ports.variable import BaseVariable, Types
from cosapp.utils.helpers import check_arg
if TYPE_CHECKING:
from cosapp.core.eval_str import EvalString
from cosapp.ports.port import BasePort, ModeVarPort
import logging
logger = logging.getLogger(__name__)
[docs]
class ModeVariable(BaseVariable):
"""Container for mode variables.
Parameters
----------
name : str
Variable name
port : ModeVarPort, optional
Port to which the variable belongs
value : Any
Variable value
unit : str, optional
Variable unit; default empty string (i.e. dimensionless)
dtype : type or iterable of type, optional
Variable type; default None (i.e. type of initial value)
desc : str, optional
Variable description; default ''
init : Any, optional
Value imposed at the beginning of time simulations, if
variable is an output (unused otherwise).
If unspecified (default), the variable remains untouched.
scope : Scope {PRIVATE, PROTECTED, PUBLIC}, optional
Variable visibility; default PRIVATE
"""
__slots__ = (
"_init",
)
def __init__(
self,
name: str,
port: ModeVarPort,
value: Optional[Any] = None,
unit: str = "",
dtype: Types = None,
desc: str = "",
init: Optional[Any] = None,
scope: Scope = Scope.PRIVATE,
):
from cosapp.ports import ModeVarPort
from cosapp.core.eval_str import EvalString
check_arg(port, "port", ModeVarPort)
init = EvalString(init, port.owner)
init_value = init.eval()
if value is None:
value = init_value
elif init_value is not None:
if not isinstance(init_value, type(value)):
raise TypeError(
f"Initial value {init!r} appears to be inconsistent with arg value={value!r}."
)
super().__init__(name, port, value, unit, dtype, desc, scope)
self._init = init # type: EvalString
def _repr_markdown_(self) -> str:
"""Returns the representation of this variable in Markdown format.
Returns
-------
str
Markdown formatted representation
"""
msg = self._markdown_data()
return (
"{name}{scope}: {value!s}{unit}"
"{description}".format(**msg)
)
@property
def init_expr(self) -> EvalString:
"""EvalString : expression of initial value"""
return self._init
[docs]
def init_value(self) -> Any:
"""Evaluate and return initial value"""
return self._init.eval()
[docs]
def initialize(self) -> None:
"""Set mode variable to its prescribed initial value."""
value = self.init_value()
if value is not None:
try:
setattr(self._port, self._name, value)
except AttributeError:
pass
[docs]
def copy(self, port: BasePort, name: Optional[str] = None) -> ModeVariable:
if name is None:
name = self.name
return ModeVariable(
name,
value = copy.copy(self.value),
port = port,
unit = self._unit,
dtype = copy.copy(self._dtype),
desc = self._desc,
scope = self._scope,
)