Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
facb914417 | ||
|
|
c5b85f5354 |
No files matched your search
+42
-18
@@ -11,15 +11,27 @@ from .components import (
|
|||||||
)
|
)
|
||||||
from .cycles import BraytonCycle
|
from .cycles import BraytonCycle
|
||||||
from .mass_models import (
|
from .mass_models import (
|
||||||
apply_component_mass,
|
PCHEGeometry,
|
||||||
calculate_component_mass,
|
PCHEMaterial,
|
||||||
condenser_radiator_mass,
|
PCHEDesignOptions,
|
||||||
has_default_mass_model,
|
PCHE_STATE_UNIT_CONVENTION,
|
||||||
heater_reactor_mass,
|
calculate_condenser_mass,
|
||||||
initialize_recuperator_segments,
|
calculate_heater_mass,
|
||||||
recuperator_pche_mass,
|
calculate_turbine_mass,
|
||||||
RecuperatorPCHEMassModel,
|
calculate_water_outlet_temperature,
|
||||||
turbine_tac_mass,
|
flow_velocity,
|
||||||
|
friction_factor,
|
||||||
|
gnielinski_f_star,
|
||||||
|
heat_transfer_coefficient,
|
||||||
|
nusselt_number,
|
||||||
|
overall_heat_transfer_coefficient,
|
||||||
|
pche_channel_flow_area,
|
||||||
|
pche_channel_wetted_perimeter,
|
||||||
|
pche_equivalent_diameter,
|
||||||
|
prandtl_number,
|
||||||
|
pressure_drop_pa,
|
||||||
|
reynolds_number,
|
||||||
|
validate_pche_state,
|
||||||
)
|
)
|
||||||
from .optimization import (
|
from .optimization import (
|
||||||
optimize_rc_fixed_param,
|
optimize_rc_fixed_param,
|
||||||
@@ -44,24 +56,36 @@ __all__ = [
|
|||||||
"Concentrator",
|
"Concentrator",
|
||||||
"Condenser",
|
"Condenser",
|
||||||
"Heater",
|
"Heater",
|
||||||
|
"PCHEGeometry",
|
||||||
|
"PCHEMaterial",
|
||||||
|
"PCHEDesignOptions",
|
||||||
|
"PCHE_STATE_UNIT_CONVENTION",
|
||||||
"Recuperator",
|
"Recuperator",
|
||||||
"RecuperatorPCHEMassModel",
|
|
||||||
"Turbine",
|
"Turbine",
|
||||||
"apply_component_mass",
|
"calculate_condenser_mass",
|
||||||
"calculate_component_mass",
|
"calculate_heater_mass",
|
||||||
"condenser_radiator_mass",
|
"calculate_turbine_mass",
|
||||||
|
"calculate_water_outlet_temperature",
|
||||||
|
"flow_velocity",
|
||||||
|
"friction_factor",
|
||||||
|
"gnielinski_f_star",
|
||||||
|
"heat_transfer_coefficient",
|
||||||
"evaluate_rc_efficiency",
|
"evaluate_rc_efficiency",
|
||||||
"has_default_mass_model",
|
|
||||||
"heater_reactor_mass",
|
|
||||||
"initialize_recuperator_segments",
|
|
||||||
"local_rc_component_performance_sensitivity",
|
"local_rc_component_performance_sensitivity",
|
||||||
"local_rc_design_sensitivity",
|
"local_rc_design_sensitivity",
|
||||||
|
"nusselt_number",
|
||||||
"optimize_rc_fixed_param",
|
"optimize_rc_fixed_param",
|
||||||
"optimize_rc_param",
|
"optimize_rc_param",
|
||||||
|
"overall_heat_transfer_coefficient",
|
||||||
|
"pche_channel_flow_area",
|
||||||
|
"pche_channel_wetted_perimeter",
|
||||||
|
"pche_equivalent_diameter",
|
||||||
"plot_optimization_landscape",
|
"plot_optimization_landscape",
|
||||||
"plot_sweep_optimization_results",
|
"plot_sweep_optimization_results",
|
||||||
"recuperator_pche_mass",
|
"prandtl_number",
|
||||||
|
"pressure_drop_pa",
|
||||||
|
"reynolds_number",
|
||||||
"scan_rc_efficiency",
|
"scan_rc_efficiency",
|
||||||
"sweep_and_optimize_rc",
|
"sweep_and_optimize_rc",
|
||||||
"turbine_tac_mass",
|
"validate_pche_state",
|
||||||
]
|
]
|
||||||
+90
-18
@@ -1,9 +1,15 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""Component models used by Brayton cycle simulations."""
|
"""Component models used by Brayton cycle simulations."""
|
||||||
|
|
||||||
|
from .mass_models import (
|
||||||
|
calculate_condenser_mass,
|
||||||
|
calculate_heater_mass,
|
||||||
|
calculate_turbine_mass,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ComponentMassMixin:
|
class ComponentMassMixin:
|
||||||
"""Shared mass-result storage interface for cycle components."""
|
"""Shared mass-calculation interface for cycle components."""
|
||||||
|
|
||||||
component_type = "component"
|
component_type = "component"
|
||||||
|
|
||||||
@@ -11,16 +17,43 @@ class ComponentMassMixin:
|
|||||||
self.mass = None
|
self.mass = None
|
||||||
self.mass_variables = None
|
self.mass_variables = None
|
||||||
|
|
||||||
def set_mass_result(self, result):
|
def calculate_mass(self, mass_model=None, **kwargs):
|
||||||
"""Store a mass-model result on this component.
|
"""Calculate and store component mass.
|
||||||
|
|
||||||
Mass formulas live in ``brayton_cycle.mass_models``. Components only
|
The future mass model can be provided as either a callable accepting
|
||||||
keep the result after their thermodynamic calculator has populated
|
``(component, **kwargs)`` or an object exposing ``calculate_mass`` or
|
||||||
``variables``.
|
``calculate_<component_type>_mass``.
|
||||||
"""
|
"""
|
||||||
if self.variables is None:
|
if self.variables is None:
|
||||||
raise ValueError("Run component calculator before storing mass")
|
raise ValueError("Run component calculator before mass calculation")
|
||||||
|
|
||||||
|
if mass_model is None:
|
||||||
|
result = self._calculate_mass(**kwargs)
|
||||||
|
else:
|
||||||
|
result = self._run_external_mass_model(mass_model, **kwargs)
|
||||||
|
|
||||||
|
return self._store_mass_result(result)
|
||||||
|
|
||||||
|
def mass_calculator(self, mass_model=None, **kwargs):
|
||||||
|
return self.calculate_mass(mass_model=mass_model, **kwargs)
|
||||||
|
|
||||||
|
def _calculate_mass(self, **kwargs):
|
||||||
|
raise NotImplementedError(
|
||||||
|
f"{self.__class__.__name__} mass model is not implemented yet. "
|
||||||
|
"Pass a mass_model or override _calculate_mass()."
|
||||||
|
)
|
||||||
|
|
||||||
|
def _run_external_mass_model(self, mass_model, **kwargs):
|
||||||
|
method_name = f"calculate_{self.component_type}_mass"
|
||||||
|
if hasattr(mass_model, method_name):
|
||||||
|
return getattr(mass_model, method_name)(self, **kwargs)
|
||||||
|
if hasattr(mass_model, "calculate_mass"):
|
||||||
|
return mass_model.calculate_mass(self, **kwargs)
|
||||||
|
if callable(mass_model):
|
||||||
|
return mass_model(self, **kwargs)
|
||||||
|
raise TypeError("mass_model must be callable or expose a supported method")
|
||||||
|
|
||||||
|
def _store_mass_result(self, result):
|
||||||
if isinstance(result, dict):
|
if isinstance(result, dict):
|
||||||
if "mass" in result:
|
if "mass" in result:
|
||||||
mass = result["mass"]
|
mass = result["mass"]
|
||||||
@@ -39,17 +72,8 @@ class ComponentMassMixin:
|
|||||||
self.variables["mass_variables"] = self.mass_variables
|
self.variables["mass_variables"] = self.mass_variables
|
||||||
return self.mass
|
return self.mass
|
||||||
|
|
||||||
def clear_mass_result(self):
|
class Compressor():
|
||||||
self.mass = None
|
|
||||||
self.mass_variables = None
|
|
||||||
if self.variables is not None:
|
|
||||||
self.variables.pop("mass", None)
|
|
||||||
self.variables.pop("mass_variables", None)
|
|
||||||
|
|
||||||
class Compressor(ComponentMassMixin):
|
|
||||||
"""压缩机类"""
|
"""压缩机类"""
|
||||||
component_type = "compressor"
|
|
||||||
|
|
||||||
def __init__(self, name, eff):
|
def __init__(self, name, eff):
|
||||||
"""
|
"""
|
||||||
初始化参数
|
初始化参数
|
||||||
@@ -65,7 +89,6 @@ class Compressor(ComponentMassMixin):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.eff = eff
|
self.eff = eff
|
||||||
self.variables = None
|
self.variables = None
|
||||||
self._init_mass_interface()
|
|
||||||
|
|
||||||
def calculator(self, p_in, T_in, p_out, property_calculator):
|
def calculator(self, p_in, T_in, p_out, property_calculator):
|
||||||
# 先计算熵值
|
# 先计算熵值
|
||||||
@@ -144,6 +167,9 @@ class Turbine(ComponentMassMixin):
|
|||||||
'pi': p_in / p_out
|
'pi': p_in / p_out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _calculate_mass(self, Pe=None, A=0.5, **kwargs):
|
||||||
|
return calculate_turbine_mass(self, Pe=Pe, A=A, **kwargs)
|
||||||
|
|
||||||
class Recuperator(ComponentMassMixin):
|
class Recuperator(ComponentMassMixin):
|
||||||
"""换热器类"""
|
"""换热器类"""
|
||||||
component_type = "recuperator"
|
component_type = "recuperator"
|
||||||
@@ -334,6 +360,23 @@ class Heater(ComponentMassMixin):
|
|||||||
'Q_in': Q_input,
|
'Q_in': Q_input,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _calculate_mass(
|
||||||
|
self,
|
||||||
|
P_heat_mwt=None,
|
||||||
|
mass_flow_rate=None,
|
||||||
|
shielding_mass_ton=2.8,
|
||||||
|
include_shielding=True,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
return calculate_heater_mass(
|
||||||
|
self,
|
||||||
|
P_heat_mwt=P_heat_mwt,
|
||||||
|
mass_flow_rate=mass_flow_rate,
|
||||||
|
shielding_mass_ton=shielding_mass_ton,
|
||||||
|
include_shielding=include_shielding,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
class Condenser(ComponentMassMixin):
|
class Condenser(ComponentMassMixin):
|
||||||
"""冷凝器类"""
|
"""冷凝器类"""
|
||||||
component_type = "condenser"
|
component_type = "condenser"
|
||||||
@@ -362,6 +405,35 @@ class Condenser(ComponentMassMixin):
|
|||||||
'Q_out': Q_output,
|
'Q_out': Q_output,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _calculate_mass(
|
||||||
|
self,
|
||||||
|
Qc_kw=None,
|
||||||
|
co2_mass_flow_rate=None,
|
||||||
|
coolant_outlet_T=None,
|
||||||
|
water_inlet_T=None,
|
||||||
|
water_mass_flow_rate=None,
|
||||||
|
water_pressure_kpa=101.325,
|
||||||
|
refprop_path="C:/Program Files (x86)/REFPROP 10.0+/REFPROP",
|
||||||
|
emissivity=0.92,
|
||||||
|
surface_temperature=210.15,
|
||||||
|
area_density=6.75,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
|
return calculate_condenser_mass(
|
||||||
|
self,
|
||||||
|
Qc_kw=Qc_kw,
|
||||||
|
co2_mass_flow_rate=co2_mass_flow_rate,
|
||||||
|
coolant_outlet_T=coolant_outlet_T,
|
||||||
|
water_inlet_T=water_inlet_T,
|
||||||
|
water_mass_flow_rate=water_mass_flow_rate,
|
||||||
|
water_pressure_kpa=water_pressure_kpa,
|
||||||
|
refprop_path=refprop_path,
|
||||||
|
emissivity=emissivity,
|
||||||
|
surface_temperature=surface_temperature,
|
||||||
|
area_density=area_density,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
class Concentrator(ComponentMassMixin):
|
class Concentrator(ComponentMassMixin):
|
||||||
"""汇流组件"""
|
"""汇流组件"""
|
||||||
component_type = "concentrator"
|
component_type = "concentrator"
|
||||||
|
|||||||
+6
-30
@@ -9,7 +9,6 @@ from .components import (
|
|||||||
Recuperator,
|
Recuperator,
|
||||||
Turbine,
|
Turbine,
|
||||||
)
|
)
|
||||||
from .mass_models import apply_component_mass, has_default_mass_model
|
|
||||||
from .properties import CO2PropertyCalculator
|
from .properties import CO2PropertyCalculator
|
||||||
|
|
||||||
|
|
||||||
@@ -58,31 +57,13 @@ class BraytonCycle:
|
|||||||
else:
|
else:
|
||||||
yield value
|
yield value
|
||||||
|
|
||||||
def calculate_component_masses(self, mass_model=None, strict=False, **kwargs):
|
def calculate_component_masses(self, mass_model=None, **kwargs):
|
||||||
"""Calculate mass for each initialized component."""
|
"""Calculate mass for each initialized component."""
|
||||||
component_masses = {}
|
component_masses = {}
|
||||||
for component in self.iter_components():
|
for component in self.iter_components():
|
||||||
if not hasattr(component, "set_mass_result"):
|
if not hasattr(component, "calculate_mass"):
|
||||||
continue
|
continue
|
||||||
if mass_model is None and not has_default_mass_model(component):
|
mass = component.calculate_mass(mass_model=mass_model, **kwargs)
|
||||||
if strict:
|
|
||||||
raise NotImplementedError(
|
|
||||||
f"No default mass model for component type "
|
|
||||||
f"{component.component_type!r}."
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
mass = apply_component_mass(
|
|
||||||
component,
|
|
||||||
mass_model=mass_model,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
except NotImplementedError:
|
|
||||||
if strict:
|
|
||||||
raise
|
|
||||||
continue
|
|
||||||
|
|
||||||
key = component.variables.get("name", component.name)
|
key = component.variables.get("name", component.name)
|
||||||
component_masses[key] = {
|
component_masses[key] = {
|
||||||
"component_type": component.component_type,
|
"component_type": component.component_type,
|
||||||
@@ -93,23 +74,18 @@ class BraytonCycle:
|
|||||||
self.component_masses = component_masses
|
self.component_masses = component_masses
|
||||||
return self.component_masses
|
return self.component_masses
|
||||||
|
|
||||||
def cycle_mass_calculator(self, mass_model=None, strict=False, **kwargs):
|
def cycle_mass_calculator(self, mass_model=None, **kwargs):
|
||||||
"""Calculate and return total cycle component mass."""
|
"""Calculate and return total cycle component mass."""
|
||||||
component_masses = self.calculate_component_masses(
|
component_masses = self.calculate_component_masses(
|
||||||
mass_model=mass_model,
|
mass_model=mass_model,
|
||||||
strict=strict,
|
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
self.total_mass = sum(item["mass"] for item in component_masses.values())
|
self.total_mass = sum(item["mass"] for item in component_masses.values())
|
||||||
return self.total_mass
|
return self.total_mass
|
||||||
|
|
||||||
def calculate_total_mass(self, mass_model=None, strict=False, **kwargs):
|
def calculate_total_mass(self, mass_model=None, **kwargs):
|
||||||
"""Compatibility alias for cycle_mass_calculator."""
|
"""Compatibility alias for cycle_mass_calculator."""
|
||||||
return self.cycle_mass_calculator(
|
return self.cycle_mass_calculator(mass_model=mass_model, **kwargs)
|
||||||
mass_model=mass_model,
|
|
||||||
strict=strict,
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
def SC(self, T_low, T_high, p_low, p_high, param=None):
|
def SC(self, T_low, T_high, p_low, p_high, param=None):
|
||||||
"""Simple Brayton cycle."""
|
"""Simple Brayton cycle."""
|
||||||
|
|||||||
+309
-686
File diff suppressed because it is too large.
Load diff
+28
-11
@@ -15,7 +15,7 @@ class CO2PropertyCalculator():
|
|||||||
self.rp.SETUPdll(2, 'SI', 'SI', 'DEF')
|
self.rp.SETUPdll(2, 'SI', 'SI', 'DEF')
|
||||||
self.z = [1.0]
|
self.z = [1.0]
|
||||||
self.mw = self.rp.WMOLdll(self.z)
|
self.mw = self.rp.WMOLdll(self.z)
|
||||||
def calculate_properties(self, T=None, P=None, h=None, s=None):
|
def calculate_properties(self, T=None, P=None, h=None, s=None, include_transport=False):
|
||||||
"""计算二氧化碳物性"""
|
"""计算二氧化碳物性"""
|
||||||
if T is not None and P is not None:
|
if T is not None and P is not None:
|
||||||
# 已知Tp
|
# 已知Tp
|
||||||
@@ -60,15 +60,32 @@ class CO2PropertyCalculator():
|
|||||||
|
|
||||||
# 补充提取的物性,这里由于后续还要使用,不进行参数变换
|
# 补充提取的物性,这里由于后续还要使用,不进行参数变换
|
||||||
properties['D'] = result.D
|
properties['D'] = result.D
|
||||||
properties['density_kg_m3'] = result.D * self.mw
|
|
||||||
properties['cp'] = result.Cp
|
properties['cp'] = result.Cp
|
||||||
properties['cp_j_kg_k'] = result.Cp / self.mw * 1000
|
properties['cv'] = result.Cv,
|
||||||
properties['cv'] = result.Cv
|
properties['rho'] = result.D * self.mw
|
||||||
properties['cv_j_kg_k'] = result.Cv / self.mw * 1000
|
properties['cp_mass'] = result.Cp / self.mw * 1000.0
|
||||||
|
properties['cv_mass'] = result.Cv / self.mw * 1000.0
|
||||||
transport = self.rp.TRNPRPdll(result.T, result.D, self.z)
|
if include_transport:
|
||||||
if transport.ierr > 0:
|
self._add_transport_properties(properties, result)
|
||||||
raise ValueError(f"REFPROP transport calculation error:{transport.ierr}")
|
|
||||||
properties['viscosity_pa_s'] = transport.eta * 1e-6
|
|
||||||
properties['thermal_conductivity_w_m_k'] = transport.tcx
|
|
||||||
return properties
|
return properties
|
||||||
|
|
||||||
|
def _add_transport_properties(self, properties, result):
|
||||||
|
"""Add CO2 transport properties needed by PCHE correlations."""
|
||||||
|
transport = self.rp.TRNPRPdll(properties['T'], result.D, self.z)
|
||||||
|
if getattr(transport, 'ierr', 0) > 0:
|
||||||
|
raise ValueError(f"REFPROP transport calculation error:{transport.ierr}")
|
||||||
|
|
||||||
|
viscosity_micro_pa_s = getattr(transport, 'eta', None)
|
||||||
|
thermal_conductivity = getattr(transport, 'tcx', None)
|
||||||
|
if viscosity_micro_pa_s is None:
|
||||||
|
viscosity_micro_pa_s = getattr(transport, 'visc', None)
|
||||||
|
if thermal_conductivity is None:
|
||||||
|
thermal_conductivity = getattr(transport, 'tcond', None)
|
||||||
|
if viscosity_micro_pa_s is None or thermal_conductivity is None:
|
||||||
|
raise ValueError("REFPROP transport result missing viscosity or conductivity")
|
||||||
|
|
||||||
|
viscosity_pa_s = viscosity_micro_pa_s * 1.0e-6
|
||||||
|
properties['mu'] = viscosity_pa_s
|
||||||
|
properties['viscosity'] = viscosity_pa_s
|
||||||
|
properties['lambda'] = thermal_conductivity
|
||||||
|
properties['thermal_conductivity'] = thermal_conductivity
|
||||||
Reference in new issue
Block a user