49 lines
4.9 KiB
Python
49 lines
4.9 KiB
Python
"""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
|
|
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', nominal_role='bidirectional'), 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'})
|