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