""" 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