"""Component parameters, ports and output definitions; numerical equations execute in C.""" from __future__ import annotations from collections.abc import Mapping from math import pi from app.simulation.components.amesim.gases import AMESIM_GAS_INDEX_PARAMETER, normalize_amesim_gas_index from app.simulation.core.base import AlgebraicComponent from app.simulation.core.catalog import ComponentDisplaySpec, PortDisplaySpec from app.simulation.core.metadata import ParameterDefinition, ResultVariableDefinition from app.simulation.core.medium import GasMedium from app.simulation.core.ports import PortDefinition from app.simulation.core.port_computation import FLOW_SUPPLY AMESIM_REFERENCE_PRESSURE_PA = 101300.0 class AmesimPnrp17(AlgebraicComponent): """AMESim PNRP17 pneumatic piston with two mechanical faces. Mechanical ports 2/5 share the piston-side motion and ports 3/4 share the cylinder-side motion. The pneumatic port contributes its swept volume and volume rate to the connected variable-volume chamber. """ MODEL_TYPE = 'amesim_pnrp17' MODEL_VERSION = '0.1.0' PORTS = (PortDefinition.pneumatic('port_1', computation=FLOW_SUPPLY), PortDefinition.mechanical_translational('port_2'), PortDefinition.mechanical_translational('port_3'), PortDefinition.mechanical_translational('port_4'), PortDefinition.mechanical_translational('port_5')) PARAMETERS = (AMESIM_GAS_INDEX_PARAMETER, ParameterDefinition('dp', 0.2, label='活塞直径', quantity='length', unit='m', minimum=0.0, minimum_exclusive=True, description='活塞外径;与活塞杆直径共同确定有效受压面积。'), ParameterDefinition('dr', 0.001, label='活塞杆直径', quantity='length', unit='m', minimum=0.0, description='穿过气室一侧的活塞杆直径,必须不大于活塞直径。'), ParameterDefinition('x0', 0.0, label='初始腔长', quantity='length', unit='m', description='机械端位移均为零时的气动腔长度。')) RESULT_VARIABLES = (ResultVariableDefinition('volume', '扫掠容积', 'volume', 'm3', 'derived', 10), ResultVariableDefinition('volume_flow', '扫掠容积变化率', 'volume_flow', 'm3/s', 'derived', 20), ResultVariableDefinition('length', '气动腔长度', 'length', 'm', 'derived', 30), ResultVariableDefinition('pressure_force', '气压力', 'force', 'N', 'derived', 40)) DISPLAY = ComponentDisplaySpec(label='PNRP17 气动活塞', library_id='amesim', category_id='mechanical', symbol='amesim_pnrp17', ports=(PortDisplaySpec('port_1', 'left', order=10), PortDisplaySpec('port_3', 'left', order=20), PortDisplaySpec('port_2', 'left', order=30), PortDisplaySpec('port_4', 'right', order=40), PortDisplaySpec('port_5', 'right', order=50)), order=60) def __init__(self, name: str, medium: GasMedium, *, gi: float=0.0, dp: float=0.2, dr: float=0.001, x0: float=0.0) -> None: super().__init__(name=name) self.set_parameter_values({'gi': gi, 'dp': dp, 'dr': dr, 'x0': x0}) self.medium = medium self.gi = normalize_amesim_gas_index(gi) self.dp = float(dp) self.dr = float(dr) self.x0 = float(x0) if self.dr > self.dp: raise ValueError('PNRP17 rod diameter dr must not exceed piston diameter dp.') for definition in self.PORTS: port = self.register_declared_port(definition.name) setattr(self, definition.name, port) @classmethod def create(cls, *, name: str, medium: GasMedium, parameters: Mapping[str, float]) -> 'AmesimPnrp17': return cls(name=name, medium=medium, **dict(parameters)) @property def effective_area(self) -> float: return pi * (self.dp * self.dp - self.dr * self.dr) / 4.0 EQUATIONS = ({'id': '__MODEL__:pneumatic_zero_mass_flow', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'constitutive', 'variables': ['__MODEL__.port_1.m_flow'], 'role': 'flow'}, {'id': '__MODEL__:port_2_port_5_x_equal', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'equal', 'variables': ['__MODEL__.port_2.x', '__MODEL__.port_5.x'], 'role': 'effort'}, {'id': '__MODEL__:port_2_port_5_v_equal', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'equal', 'variables': ['__MODEL__.port_2.v', '__MODEL__.port_5.v'], 'role': 'effort'}, {'id': '__MODEL__:port_3_port_4_x_equal', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'equal', 'variables': ['__MODEL__.port_3.x', '__MODEL__.port_4.x'], 'role': 'effort'}, {'id': '__MODEL__:port_3_port_4_v_equal', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'equal', 'variables': ['__MODEL__.port_3.v', '__MODEL__.port_4.v'], 'role': 'effort'}, {'id': '__MODEL__:piston_side_force_balance', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'constitutive', 'variables': ['__MODEL__.port_2.f', '__MODEL__.port_5.f', '__MODEL__.port_1.p'], 'role': 'flow'}, {'id': '__MODEL__:cylinder_side_force_balance', 'owner': 'component', 'ownerId': '__MODEL__', 'relation': 'constitutive', 'variables': ['__MODEL__.port_3.f', '__MODEL__.port_4.f', '__MODEL__.port_1.p'], 'role': 'flow'})