完成求解器雅可比矩阵首轮优化,增加更新目录,整理了文档文件夹,增加了服务启动脚本
This commit is contained in:
1 parent
6bb0591d32
commit
16a7eb2d6c
48 files changed
+8172
-217
No files matched your search
@@ -1,7 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Protocol
|
||||
from math import isfinite
|
||||
from typing import Protocol, Sequence
|
||||
|
||||
from app.simulation.core.errors import RecoverableTrialStateError
|
||||
from app.simulation.performance import profile_property
|
||||
@@ -16,6 +17,36 @@ class ThermodynamicProperties:
|
||||
h: float
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ThermodynamicPropertyTangents:
|
||||
"""Directional derivatives of a recovered thermodynamic state."""
|
||||
|
||||
p: tuple[float, ...]
|
||||
T: tuple[float, ...]
|
||||
rho: tuple[float, ...]
|
||||
u: tuple[float, ...]
|
||||
h: tuple[float, ...]
|
||||
|
||||
@property
|
||||
def width(self) -> int:
|
||||
return len(self.p)
|
||||
|
||||
@classmethod
|
||||
def zeros(cls, width: int) -> "ThermodynamicPropertyTangents":
|
||||
values = (0.0,) * width
|
||||
return cls(p=values, T=values, rho=values, u=values, h=values)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ThermodynamicPropertiesLinearization:
|
||||
"""Primal properties and a validity-checked directional linearization."""
|
||||
|
||||
properties: ThermodynamicProperties
|
||||
tangents: ThermodynamicPropertyTangents
|
||||
valid: bool = True
|
||||
reason: str | None = None
|
||||
|
||||
|
||||
class GasMedium(Protocol):
|
||||
"""Thermodynamic contract required by pneumatic components.
|
||||
|
||||
@@ -75,6 +106,18 @@ class GasMedium(Protocol):
|
||||
V: float,
|
||||
) -> ThermodynamicProperties: ...
|
||||
|
||||
def linearize_properties_from_mU(
|
||||
self,
|
||||
m: float,
|
||||
U: float,
|
||||
V: float,
|
||||
dm: Sequence[float],
|
||||
dU: Sequence[float],
|
||||
dV: Sequence[float],
|
||||
*,
|
||||
properties: ThermodynamicProperties | None = None,
|
||||
) -> ThermodynamicPropertiesLinearization: ...
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class IdealGasMedium:
|
||||
@@ -224,3 +267,100 @@ class IdealGasMedium:
|
||||
u = U / m
|
||||
h = self.specific_enthalpy(T)
|
||||
return ThermodynamicProperties(p=p, T=T, rho=rho, u=u, h=h)
|
||||
|
||||
def linearize_properties_from_mU(
|
||||
self,
|
||||
m: float,
|
||||
U: float,
|
||||
V: float,
|
||||
dm: Sequence[float],
|
||||
dU: Sequence[float],
|
||||
dV: Sequence[float],
|
||||
*,
|
||||
properties: ThermodynamicProperties | None = None,
|
||||
) -> ThermodynamicPropertiesLinearization:
|
||||
"""Linearize properties_from_mU for several seed directions."""
|
||||
|
||||
dm_values = tuple(float(value) for value in dm)
|
||||
dU_values = tuple(float(value) for value in dU)
|
||||
dV_values = tuple(float(value) for value in dV)
|
||||
if not (len(dm_values) == len(dU_values) == len(dV_values)):
|
||||
raise ValueError("Thermodynamic tangent vectors must have equal lengths.")
|
||||
props = properties or self.properties_from_mU(m, U, V)
|
||||
width = len(dm_values)
|
||||
expected_density = m / V
|
||||
expected_internal_energy = U / m
|
||||
if (
|
||||
abs(props.rho - expected_density)
|
||||
> 1.0e-12 * max(abs(expected_density), 1.0)
|
||||
or abs(props.u - expected_internal_energy)
|
||||
> 1.0e-12 * max(abs(expected_internal_energy), 1.0)
|
||||
):
|
||||
return ThermodynamicPropertiesLinearization(
|
||||
properties=props,
|
||||
tangents=ThermodynamicPropertyTangents.zeros(width),
|
||||
valid=False,
|
||||
reason="properties_primal_mismatch",
|
||||
)
|
||||
if not all(
|
||||
isfinite(value)
|
||||
for values in (dm_values, dU_values, dV_values)
|
||||
for value in values
|
||||
):
|
||||
return ThermodynamicPropertiesLinearization(
|
||||
properties=props,
|
||||
tangents=ThermodynamicPropertyTangents.zeros(width),
|
||||
valid=False,
|
||||
reason="non_finite_tangent_input",
|
||||
)
|
||||
|
||||
cv = self.cv_at_temperature(props.T)
|
||||
cp = self.cp_at_temperature(props.T)
|
||||
if not isfinite(cv) or not isfinite(cp) or cv <= 0.0 or cp <= 0.0:
|
||||
return ThermodynamicPropertiesLinearization(
|
||||
properties=props,
|
||||
tangents=ThermodynamicPropertyTangents.zeros(width),
|
||||
valid=False,
|
||||
reason="non_positive_heat_capacity",
|
||||
)
|
||||
|
||||
drho: list[float] = []
|
||||
du: list[float] = []
|
||||
dT: list[float] = []
|
||||
dp: list[float] = []
|
||||
dh: list[float] = []
|
||||
for mass_tangent, energy_tangent, volume_tangent in zip(
|
||||
dm_values,
|
||||
dU_values,
|
||||
dV_values,
|
||||
strict=True,
|
||||
):
|
||||
density_tangent = mass_tangent / V - m * volume_tangent / (V * V)
|
||||
internal_energy_tangent = (
|
||||
energy_tangent / m - U * mass_tangent / (m * m)
|
||||
)
|
||||
temperature_tangent = internal_energy_tangent / cv
|
||||
pressure_tangent = self.R_gas * (
|
||||
props.T * density_tangent + props.rho * temperature_tangent
|
||||
)
|
||||
enthalpy_tangent = cp * temperature_tangent
|
||||
drho.append(density_tangent)
|
||||
du.append(internal_energy_tangent)
|
||||
dT.append(temperature_tangent)
|
||||
dp.append(pressure_tangent)
|
||||
dh.append(enthalpy_tangent)
|
||||
|
||||
tangent_values = (*drho, *du, *dT, *dp, *dh)
|
||||
valid = all(isfinite(value) for value in tangent_values)
|
||||
return ThermodynamicPropertiesLinearization(
|
||||
properties=props,
|
||||
tangents=ThermodynamicPropertyTangents(
|
||||
p=tuple(dp),
|
||||
T=tuple(dT),
|
||||
rho=tuple(drho),
|
||||
u=tuple(du),
|
||||
h=tuple(dh),
|
||||
),
|
||||
valid=valid,
|
||||
reason=None if valid else "non_finite_property_tangent",
|
||||
)
|
||||
Reference in new issue
Block a user