Spaces:
Running
Running
File size: 4,832 Bytes
c993983 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | """
Analysis request/response models for pinch analysis, HPI, and status quo comparison.
"""
from __future__ import annotations
from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel, Field
# ---------------------------------------------------------------------------
# Pinch Analysis
# ---------------------------------------------------------------------------
class PinchStream(BaseModel):
"""A single stream for pinch analysis input."""
name: str = ""
CP: float # Heat capacity rate (kW/°C)
T_supply: float # Supply temperature (°C)
T_target: float # Target temperature (°C)
class PinchRequest(BaseModel):
"""Input to the pinch analysis endpoint."""
streams: List[PinchStream]
T_min: float # Minimum temperature difference (°C)
class CompositeDiagramData(BaseModel):
"""H-T data for hot and cold composite curves."""
hot: Dict[str, List[float]] = Field(default_factory=lambda: {"H": [], "T": []})
cold: Dict[str, List[float]] = Field(default_factory=lambda: {"H": [], "T": []})
class PinchResult(BaseModel):
"""Full output of pinch analysis."""
pinch_temperature: float
hot_utility: float # Minimum hot utility (kW)
cold_utility: float # Minimum cold utility (kW)
T_min: float
temperatures: List[float] # Sorted shifted temperature intervals
# Problem table
problem_table: List[Dict[str, float]]
# Heat cascade
heat_cascade: List[Dict[str, float]]
unfeasible_heat_cascade: List[Dict[str, float]]
# Diagrams (lists of H, T values for plotting)
shifted_composite_diagram: CompositeDiagramData = Field(default_factory=CompositeDiagramData)
composite_diagram: CompositeDiagramData = Field(default_factory=CompositeDiagramData)
grand_composite_curve: Dict[str, List[float]] = Field(default_factory=lambda: {"H": [], "T": []})
# Stream info for labelling charts
streams_data: List[Dict[str, Any]] = Field(default_factory=list)
# ---------------------------------------------------------------------------
# Heat Pump Integration
# ---------------------------------------------------------------------------
class HeatPumpEntry(BaseModel):
"""Detailed summary of an available heat pump."""
name: str
cop: Optional[float] = None
t_source: Optional[float] = None
t_sink: Optional[float] = None
q_source: Optional[float] = None
q_sink: Optional[float] = None
coverage: Optional[float] = None
available: bool = True
reason: str = ""
class HPIRequest(BaseModel):
"""Input to the HPI endpoint."""
pinch_result: PinchResult
hp_types: List[str] = Field(
default_factory=lambda: [
"Prototypical Stirling",
"VHTHP (HFC/HFO)",
"SHP and HTHPs (HFC/HFO)",
"SHP and HTHPs (R717)",
]
)
class HPIntegrationResult(BaseModel):
"""Result for a single heat pump type."""
hp_type: str
COP: Optional[float] = None
Q_ko: Optional[float] = None # Condenser heat (kW)
Q_ev: Optional[float] = None # Evaporator heat (kW)
T_source: Optional[float] = None
T_sink: Optional[float] = None
delta_T: Optional[float] = None
feasible: bool = False
# GCC integration points for charting
source_points: Dict[str, List[float]] = Field(default_factory=lambda: {"H": [], "T": []})
sink_points: Dict[str, List[float]] = Field(default_factory=lambda: {"H": [], "T": []})
class HPIResult(BaseModel):
"""Output of HPI analysis — one entry per HP type evaluated."""
integrations: List[HPIntegrationResult] = Field(default_factory=list)
heat_pumps: List[HeatPumpEntry] = Field(default_factory=list)
excluded_heat_pumps: List[HeatPumpEntry] = Field(default_factory=list)
gcc_data: Dict[str, List[float]] = Field(default_factory=lambda: {"H": [], "T": []})
# ---------------------------------------------------------------------------
# Status Quo Comparison
# ---------------------------------------------------------------------------
class EnergyDemand(BaseModel):
"""Current energy demand for one stream (user-entered)."""
stream_name: str = ""
heating_kW: float = 0.0
cooling_kW: float = 0.0
class StatusQuoRequest(BaseModel):
"""Input to the status quo comparison endpoint."""
current_demands: List[EnergyDemand]
pinch_hot_utility: float
pinch_cold_utility: float
class StatusQuoResult(BaseModel):
"""Comparison of current vs pinch-optimal demands."""
total_current_heating: float
total_current_cooling: float
pinch_hot_utility: float
pinch_cold_utility: float
heating_savings_kW: float
cooling_savings_kW: float
heating_savings_pct: float
cooling_savings_pct: float
|