Files
SystemSimulationApp/app/simulation/components/amesim/storage/chambers.py
T

81 lines
9.7 KiB
Python

"""Component parameters, ports and output definitions; numerical equations execute in C."""
from __future__ import annotations
from collections.abc import Mapping
from app.simulation.components.amesim.gases import AMESIM_GAS_INDEX_PARAMETER, normalize_amesim_gas_index
from app.simulation.core.base import ThermodynamicVolumeComponent
from app.simulation.core.catalog import ComponentDisplaySpec, PortDisplaySpec
from app.simulation.core.metadata import ParameterDefinition, ResultVariableDefinition, THERMODYNAMIC_VOLUME_RESULT_VARIABLES
from app.simulation.core.medium import GasMedium
from app.simulation.core.ports import PortDefinition
class AmesimPnch023(ThermodynamicVolumeComponent):
"""AMESim PNCH023 simple pneumatic chamber with heat exchange.
The AMESim submodel owns pressure and temperature states and exposes two
pneumatic flow ports. This public component maps those states onto the
framework's mass/internal-energy volume state and keeps the AMESim
heat-transfer contract `kth * sth * (extemp - T)`.
"""
MODEL_TYPE = 'amesim_pnch023'
MODEL_VERSION = '0.1.0'
PORTS = (PortDefinition.pneumatic('port_1', nominal_role='bidirectional'), PortDefinition.pneumatic('port_2', nominal_role='bidirectional'))
PARAMETERS = (AMESIM_GAS_INDEX_PARAMETER, ParameterDefinition('cvol', 0.057, label='气室容积', quantity='volume', unit='m3', minimum=0.0, minimum_exclusive=True, description='气室内部用于储存气体的固定有效容积。'), ParameterDefinition('kth', 0.0, label='换热系数', quantity='heat_transfer_coefficient', unit='W/(m2*K)', minimum=0.0, description='气室与环境之间的对流换热系数,与换热面积共同决定换热功率。'), ParameterDefinition('sth', 0.1, label='换热面积', quantity='area', unit='m2', minimum=0.0, description='气室与环境进行热交换的有效表面积。'), ParameterDefinition('extemp', 293.15, label='外部温度', quantity='temperature', unit='K', minimum=0.0, minimum_exclusive=True, description='气室外部环境的绝对温度,用于计算气体与环境之间的换热。'), ParameterDefinition('p0', 100000.0, label='初始压力', quantity='pressure', unit='Pa', minimum=0.0, minimum_exclusive=True, description='仿真开始时气室内气体的绝对压力。'), ParameterDefinition('T0', 293.15, label='初始温度', quantity='temperature', unit='K', minimum=0.0, minimum_exclusive=True, description='仿真开始时气室内气体的绝对温度。'))
RESULT_VARIABLES = THERMODYNAMIC_VOLUME_RESULT_VARIABLES
DISPLAY = ComponentDisplaySpec(label='PNCH023 固定容积气室', library_id='amesim', category_id='storage', symbol='amesim_pnch023', ports=(PortDisplaySpec('port_1', 'left', order=10), PortDisplaySpec('port_2', 'right', order=20)), order=10)
def __init__(self, name: str, medium: GasMedium, *, cvol: float=0.057, kth: float=0.0, sth: float=0.1, extemp: float=293.15, gi: float=1.0, p0: float=100000.0, T0: float=293.15) -> None:
super().__init__(name=name)
self.set_parameter_values({'cvol': cvol, 'kth': kth, 'sth': sth, 'extemp': extemp, 'gi': gi, 'p0': p0, 'T0': T0})
self.medium = medium
self.cvol = float(cvol)
self.kth = float(kth)
self.sth = float(sth)
self.extemp = float(extemp)
self.gi = normalize_amesim_gas_index(gi)
self.p0 = float(p0)
self.T0 = float(T0)
self.port_1 = self.register_declared_port('port_1')
self.port_2 = self.register_declared_port('port_2')
@classmethod
def create(cls, *, name: str, medium: GasMedium, parameters: Mapping[str, float]) -> AmesimPnch023:
return cls(name=name, medium=medium, cvol=parameters['cvol'], kth=parameters['kth'], sth=parameters['sth'], extemp=parameters['extemp'], gi=parameters['gi'], p0=parameters['p0'], T0=parameters['T0'])
EQUATIONS = ({'id': '__MODEL__:port_1_pressure_state', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'state', 'variables': ['__MODEL__.port_1.p', '__MODEL__.state'], 'role': 'effort'}, {'id': '__MODEL__:port_2_pressure_state', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'state', 'variables': ['__MODEL__.port_2.p', '__MODEL__.state'], 'role': 'effort'})
class AmesimPnch012(ThermodynamicVolumeComponent):
"""AMESim PNCH012 variable-volume pneumatic chamber.
AMESim supplies four external volume and volume-rate inputs through the
chamber ports. Fixed/prescribed contributions remain available as SI
parameters, while connected moving-boundary components can now add live
volume and volume-rate values through the pneumatic connector contract.
"""
MODEL_TYPE = 'amesim_pnch012'
MODEL_VERSION = '0.1.0'
PORTS = (PortDefinition.pneumatic('port_1', nominal_role='bidirectional'), PortDefinition.pneumatic('port_2', nominal_role='bidirectional'), PortDefinition.pneumatic('port_3', nominal_role='bidirectional'), PortDefinition.pneumatic('port_4', nominal_role='bidirectional'))
PARAMETERS = (AMESIM_GAS_INDEX_PARAMETER, ParameterDefinition('cvol0', 0.015, label='死容积', quantity='volume', unit='m3', minimum=0.0, minimum_exclusive=True, description='变容气室在所有外部容积为零时仍保留的基础容积。'), ParameterDefinition('kth', 0.0, label='换热系数', quantity='heat_transfer_coefficient', unit='W/(m2*K)', minimum=0.0, description='气室与环境之间的对流换热系数,与换热面积共同决定换热功率。'), ParameterDefinition('sth', 0.1, label='换热面积', quantity='area', unit='m2', minimum=0.0, description='气室与环境进行热交换的有效表面积。'), ParameterDefinition('extemp', 293.15, label='外部温度', quantity='temperature', unit='K', minimum=0.0, minimum_exclusive=True, description='气室外部环境的绝对温度,用于计算气体与环境之间的换热。'), ParameterDefinition('p0', 100000.0, label='初始压力', quantity='pressure', unit='Pa', minimum=0.0, minimum_exclusive=True, description='仿真开始时气室内气体的绝对压力。'), ParameterDefinition('T0', 293.15, label='初始温度', quantity='temperature', unit='K', minimum=0.0, minimum_exclusive=True, description='仿真开始时气室内气体的绝对温度。'), ParameterDefinition('vol1', 0.0, label='端口 1 外部容积', quantity='volume', unit='m3'), ParameterDefinition('vol2', 0.0, label='端口 2 外部容积', quantity='volume', unit='m3'), ParameterDefinition('vol3', 0.0, label='端口 3 外部容积', quantity='volume', unit='m3'), ParameterDefinition('vol4', 0.0, label='端口 4 外部容积', quantity='volume', unit='m3'), ParameterDefinition('dvol1', 0.0, label='端口 1 容积变化率', quantity='volume_flow', unit='m3/s'), ParameterDefinition('dvol2', 0.0, label='端口 2 容积变化率', quantity='volume_flow', unit='m3/s'), ParameterDefinition('dvol3', 0.0, label='端口 3 容积变化率', quantity='volume_flow', unit='m3/s'), ParameterDefinition('dvol4', 0.0, label='端口 4 容积变化率', quantity='volume_flow', unit='m3/s'))
RESULT_VARIABLES = THERMODYNAMIC_VOLUME_RESULT_VARIABLES + (ResultVariableDefinition('vol', '气室总容积', 'volume', 'm3', 'derived', 100), ResultVariableDefinition('dvol', '总容积变化率', 'volume_flow', 'm3/s', 'derived', 110))
DISPLAY = ComponentDisplaySpec(label='PNCH012 变容气室', library_id='amesim', category_id='storage', symbol='amesim_pnch012', ports=(PortDisplaySpec('port_1', 'left', order=10), PortDisplaySpec('port_2', 'right', order=20), PortDisplaySpec('port_3', 'left', order=30), PortDisplaySpec('port_4', 'right', order=40)), order=20)
def __init__(self, name: str, medium: GasMedium, *, cvol0: float=0.015, kth: float=0.0, sth: float=0.1, extemp: float=293.15, gi: float=1.0, p0: float=100000.0, T0: float=293.15, vol1: float=0.0, vol2: float=0.0, vol3: float=0.0, vol4: float=0.0, dvol1: float=0.0, dvol2: float=0.0, dvol3: float=0.0, dvol4: float=0.0) -> None:
super().__init__(name=name)
self.set_parameter_values({'cvol0': cvol0, 'kth': kth, 'sth': sth, 'extemp': extemp, 'gi': gi, 'p0': p0, 'T0': T0, 'vol1': vol1, 'vol2': vol2, 'vol3': vol3, 'vol4': vol4, 'dvol1': dvol1, 'dvol2': dvol2, 'dvol3': dvol3, 'dvol4': dvol4})
self.medium = medium
self.cvol0 = float(cvol0)
self.kth = float(kth)
self.sth = float(sth)
self.extemp = float(extemp)
self.gi = normalize_amesim_gas_index(gi)
self.p0 = float(p0)
self.T0 = float(T0)
self.external_volumes = {'port_1': float(vol1), 'port_2': float(vol2), 'port_3': float(vol3), 'port_4': float(vol4)}
self.external_volume_rates = {'port_1': float(dvol1), 'port_2': float(dvol2), 'port_3': float(dvol3), 'port_4': float(dvol4)}
for port_name in ('port_1', 'port_2', 'port_3', 'port_4'):
port = self.register_declared_port(port_name)
setattr(self, port_name, port)
@classmethod
def create(cls, *, name: str, medium: GasMedium, parameters: Mapping[str, float]) -> 'AmesimPnch012':
return cls(name=name, medium=medium, **dict(parameters))
EQUATIONS = ({'id': '__MODEL__:port_1_pressure_state', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'state', 'variables': ['__MODEL__.port_1.p', '__MODEL__.state'], 'role': 'effort'}, {'id': '__MODEL__:port_2_pressure_state', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'state', 'variables': ['__MODEL__.port_2.p', '__MODEL__.state'], 'role': 'effort'}, {'id': '__MODEL__:port_3_pressure_state', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'state', 'variables': ['__MODEL__.port_3.p', '__MODEL__.state'], 'role': 'effort'}, {'id': '__MODEL__:port_4_pressure_state', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'state', 'variables': ['__MODEL__.port_4.p', '__MODEL__.state'], 'role': 'effort'})