diagram_ph/app/models/properties.py

201 lines
7.6 KiB
Python

"""
Modeles pour les calculs de proprietes thermodynamiques
"""
from typing import Optional, Literal
from pydantic import BaseModel, Field, field_validator
class PropertyCalculationRequest(BaseModel):
"""Requete pour calculer des proprietes thermodynamiques"""
refrigerant: str = Field(
...,
description="Nom du refrigerant",
example="R134a"
)
calculation_type: Literal["px", "pT", "ph", "Tx"] = Field(
...,
description="Type de calcul: px (pression-qualite), pT (pression-temperature), ph (pression-enthalpie), Tx (temperature-qualite)",
example="px"
)
# Parametres d'entree selon le type
pressure: Optional[float] = Field(
None,
description="Pression en Pa",
gt=0,
example=500000
)
temperature: Optional[float] = Field(
None,
description="Temperature en K",
gt=0,
example=280.0
)
quality: Optional[float] = Field(
None,
description="Qualite (titre) entre 0 et 1",
ge=0,
le=1,
example=0.5
)
enthalpy: Optional[float] = Field(
None,
description="Enthalpie en J/kg",
example=250000
)
@field_validator('pressure')
@classmethod
def validate_pressure(cls, v, info):
calc_type = info.data.get('calculation_type')
if calc_type in ['px', 'pT', 'ph'] and v is None:
raise ValueError(f"Pression requise pour le calcul {calc_type}")
return v
@field_validator('temperature')
@classmethod
def validate_temperature(cls, v, info):
calc_type = info.data.get('calculation_type')
if calc_type in ['pT', 'Tx'] and v is None:
raise ValueError(f"Temperature requise pour le calcul {calc_type}")
return v
@field_validator('quality')
@classmethod
def validate_quality(cls, v, info):
calc_type = info.data.get('calculation_type')
if calc_type in ['px', 'Tx'] and v is None:
raise ValueError(f"Qualite requise pour le calcul {calc_type}")
return v
@field_validator('enthalpy')
@classmethod
def validate_enthalpy(cls, v, info):
calc_type = info.data.get('calculation_type')
if calc_type == 'ph' and v is None:
raise ValueError("Enthalpie requise pour le calcul ph")
return v
class Config:
json_schema_extra = {
"examples": [
{
"refrigerant": "R134a",
"calculation_type": "px",
"pressure": 500000,
"quality": 0.5
},
{
"refrigerant": "R410A",
"calculation_type": "pT",
"pressure": 800000,
"temperature": 280.0
},
{
"refrigerant": "R744",
"calculation_type": "ph",
"pressure": 3000000,
"enthalpy": 400000
}
]
}
class SaturationRequest(BaseModel):
"""Requete pour obtenir les proprietes de saturation"""
refrigerant: str = Field(
...,
description="Nom du refrigerant",
example="R134a"
)
pressure: float = Field(
...,
description="Pression en Pa",
gt=0,
example=500000
)
class Config:
json_schema_extra = {
"example": {
"refrigerant": "R134a",
"pressure": 500000
}
}
class PropertyInputs(BaseModel):
"""Parametres d'entree du calcul"""
pressure: Optional[float] = Field(None, description="Pression (Pa)")
pressure_bar: Optional[float] = Field(None, description="Pression (bar)")
temperature: Optional[float] = Field(None, description="Temperature (K)")
temperature_celsius: Optional[float] = Field(None, description="Temperature (°C)")
quality: Optional[float] = Field(None, description="Qualite (0-1)")
enthalpy: Optional[float] = Field(None, description="Enthalpie (J/kg)")
class ThermodynamicPropertiesDetailed(BaseModel):
"""Proprietes thermodynamiques detaillees"""
temperature: float = Field(..., description="Temperature (K)")
temperature_celsius: float = Field(..., description="Temperature (°C)")
enthalpy: float = Field(..., description="Enthalpie (J/kg)")
enthalpy_kj_kg: float = Field(..., description="Enthalpie (kJ/kg)")
entropy: float = Field(..., description="Entropie (J/kg.K)")
entropy_kj_kgK: float = Field(..., description="Entropie (kJ/kg.K)")
density: float = Field(..., description="Masse volumique (kg/m³)")
specific_volume: Optional[float] = Field(None, description="Volume specifique (m³/kg)")
quality: Optional[float] = Field(None, description="Qualite (0-1)")
class SaturationPropertiesDetailed(BaseModel):
"""Proprietes de saturation detaillees"""
temperature: float = Field(..., description="Temperature de saturation (K)")
temperature_celsius: float = Field(..., description="Temperature de saturation (°C)")
enthalpy_liquid: float = Field(..., description="Enthalpie liquide (J/kg)")
enthalpy_liquid_kj_kg: float = Field(..., description="Enthalpie liquide (kJ/kg)")
enthalpy_vapor: float = Field(..., description="Enthalpie vapeur (J/kg)")
enthalpy_vapor_kj_kg: float = Field(..., description="Enthalpie vapeur (kJ/kg)")
density_liquid: float = Field(..., description="Masse volumique liquide (kg/m³)")
density_vapor: float = Field(..., description="Masse volumique vapeur (kg/m³)")
latent_heat: float = Field(..., description="Chaleur latente (J/kg)")
latent_heat_kj_kg: float = Field(..., description="Chaleur latente (kJ/kg)")
class PropertyCalculationResponse(BaseModel):
"""Reponse complete d'un calcul de proprietes"""
refrigerant: str = Field(..., description="Nom du refrigerant")
inputs: PropertyInputs = Field(..., description="Parametres d'entree")
properties: ThermodynamicPropertiesDetailed = Field(..., description="Proprietes calculees")
saturation: SaturationPropertiesDetailed = Field(..., description="Proprietes de saturation")
note: Optional[str] = Field(None, description="Note informative")
class PhaseProperties(BaseModel):
"""Proprietes d'une phase (liquide ou vapeur)"""
enthalpy: float = Field(..., description="Enthalpie (J/kg)")
enthalpy_kj_kg: float = Field(..., description="Enthalpie (kJ/kg)")
density: float = Field(..., description="Masse volumique (kg/m³)")
specific_volume: Optional[float] = Field(None, description="Volume specifique (m³/kg)")
entropy: float = Field(..., description="Entropie (J/kg.K)")
entropy_kj_kgK: float = Field(..., description="Entropie (kJ/kg.K)")
class SaturationResponse(BaseModel):
"""Reponse pour les proprietes de saturation"""
refrigerant: str = Field(..., description="Nom du refrigerant")
pressure: float = Field(..., description="Pression (Pa)")
pressure_bar: float = Field(..., description="Pression (bar)")
temperature_saturation: float = Field(..., description="Temperature de saturation (K)")
temperature_saturation_celsius: float = Field(..., description="Temperature de saturation (°C)")
liquid: PhaseProperties = Field(..., description="Proprietes du liquide sature")
vapor: PhaseProperties = Field(..., description="Proprietes de la vapeur saturee")
latent_heat: float = Field(..., description="Chaleur latente (J/kg)")
latent_heat_kj_kg: float = Field(..., description="Chaleur latente (kJ/kg)")