# Migration Guide: Boundary Conditions

## Overview

The `FlowSource` and `FlowSink` types have been replaced with typed alternatives that provide better type safety and more explicit fluid handling:

| Old Type | New Type | Use Case |
|----------|----------|----------|
| `FlowSource` | `RefrigerantSource` | Refrigerants (R410A, R134a, CO₂, etc.) |
| `FlowSource` | `BrineSource` | Liquid heat transfer fluids (water, glycol, brine) |
| `FlowSource` | `AirSource` | Humid air (HVAC applications) |
| `FlowSink` | `RefrigerantSink` | Refrigerants |
| `FlowSink` | `BrineSink` | Liquid heat transfer fluids |
| `FlowSink` | `AirSink` | Humid air |

## Deprecation Timeline

| Version | Status |
|---------|--------|
| 0.2.0 | Deprecation warnings added |
| 0.3.0 | Old types hidden behind feature flag |
| 1.0.0 | Complete removal of old types |

## Migration Examples

### Water Source

**Before (deprecated):**
```rust
use entropyk_components::FlowSource;

let source = FlowSource::incompressible("Water", 3.0e5, 63_000.0, port)?;
```

**After:**
```rust
use entropyk_components::BrineSource;
use entropyk_core::{Pressure, Temperature, Concentration};
use entropyk_fluids::CoolPropBackend;
use std::sync::Arc;

let backend = Arc::new(CoolPropBackend::new());

let source = BrineSource::new(
    "Water",                                    // Fluid name
    Pressure::from_pascals(3.0e5),             // Pressure
    Temperature::from_celsius(15.0),           // Temperature
    Concentration::zero(),                      // No glycol
    backend.clone(),
    port
)?;
```

### Glycol Mixture Source

**Before (deprecated):**
```rust
use entropyk_components::FlowSource;

// MEG at 30% concentration, 3 bar, -5°C
let source = FlowSource::incompressible("MEG", 3.0e5, 20_000.0, port)?;
```

**After:**
```rust
use entropyk_components::BrineSource;
use entropyk_core::{Pressure, Temperature, Concentration};
use entropyk_fluids::CoolPropBackend;
use std::sync::Arc;

let backend = Arc::new(CoolPropBackend::new());

let source = BrineSource::new(
    "MEG",                                      // Fluid name
    Pressure::from_pascals(3.0e5),             // Pressure
    Temperature::from_celsius(-5.0),           // Temperature
    Concentration::from_percent(30.0),         // 30% glycol concentration
    backend.clone(),
    port
)?;
```

### Refrigerant Source

**Before (deprecated):**
```rust
use entropyk_components::FlowSource;

// R410A at 10 bar, enthalpy 280 kJ/kg
let source = FlowSource::compressible("R410A", 10.0e5, 280_000.0, port)?;
```

**After:**
```rust
use entropyk_components::RefrigerantSource;
use entropyk_core::{Pressure, VaporQuality};
use entropyk_fluids::CoolPropBackend;
use std::sync::Arc;

let backend = Arc::new(CoolPropBackend::new());

// Option 1: Using pressure and vapor quality
let source = RefrigerantSource::new(
    "R410A",
    Pressure::from_pascals(10.0e5),
    VaporQuality::from_fraction(0.5),          // 50% vapor quality
    backend.clone(),
    port
)?;

// Option 2: Using saturated vapor (quality = 1)
let source = RefrigerantSource::new(
    "R410A",
    Pressure::from_pascals(10.0e5),
    VaporQuality::saturated_vapor(),
    backend.clone(),
    port
)?;
```

### Air Source

**Before (deprecated):**
```rust
// Air sources were not available in the old API
```

**After:**
```rust
use entropyk_components::AirSource;
use entropyk_core::{Pressure, Temperature, RelativeHumidity};

// Option 1: From dry-bulb temperature and relative humidity
let source = AirSource::from_dry_bulb_rh(
    Temperature::from_celsius(35.0),           // Dry-bulb temperature
    RelativeHumidity::from_percent(50.0),      // 50% relative humidity
    Pressure::from_pascals(101_325.0),         // Atmospheric pressure
    port
)?;

// Option 2: From dry-bulb and wet-bulb temperatures
let source = AirSource::from_dry_and_wet_bulb(
    Temperature::from_celsius(35.0),           // Dry-bulb temperature
    Temperature::from_celsius(25.0),           // Wet-bulb temperature
    Pressure::from_pascals(101_325.0),         // Atmospheric pressure
    port
)?;
```

### Water Sink

**Before (deprecated):**
```rust
use entropyk_components::FlowSink;

// Return header: 1.5 bar back-pressure
let sink = FlowSink::incompressible("Water", 1.5e5, None, port)?;
```

**After:**
```rust
use entropyk_components::BrineSink;
use entropyk_core::{Pressure, Concentration};
use entropyk_fluids::CoolPropBackend;
use std::sync::Arc;

let backend = Arc::new(CoolPropBackend::new());

let sink = BrineSink::new(
    "Water",
    Pressure::from_pascals(1.5e5),             // Back-pressure
    None,                                       // No fixed temperature (free enthalpy)
    None,                                       // No concentration needed when temp is None
    backend.clone(),
    port
)?;
```

### Refrigerant Sink

**Before (deprecated):**
```rust
use entropyk_components::FlowSink;

// R410A low-side: 8.5 bar
let sink = FlowSink::compressible("R410A", 8.5e5, None, port)?;
```

**After:**
```rust
use entropyk_components::RefrigerantSink;
use entropyk_core::Pressure;
use entropyk_fluids::CoolPropBackend;
use std::sync::Arc;

let backend = Arc::new(CoolPropBackend::new());

let sink = RefrigerantSink::new(
    "R410A",
    Pressure::from_pascals(8.5e5),             // Back-pressure
    None,                                       // No fixed vapor quality (free enthalpy)
    backend.clone(),
    port
)?;
```

### Air Sink

**Before (deprecated):**
```rust
// Air sinks were not available in the old API
```

**After:**
```rust
use entropyk_components::AirSink;
use entropyk_core::Pressure;

// Simple back-pressure sink (free enthalpy)
let sink = AirSink::new(
    Pressure::from_pascals(101_325.0),         // Atmospheric pressure
    port
)?;

// Or with fixed return temperature:
let mut sink = AirSink::new(Pressure::from_pascals(101_325.0), port)?;
sink.set_return_temperature(
    Temperature::from_celsius(25.0),
    RelativeHumidity::from_percent(50.0)
)?;
```

## Benefits of New Types

### 1. Type Safety

The fluid type is now explicit in the type name, making code more self-documenting:

```rust
// Old: Unclear what type of fluid this is
let source = FlowSource::incompressible("Water", ...);

// New: Clear that this is a brine/water source
let source = BrineSource::new("Water", ...);
```

### 2. Concentration Support

`BrineSource` supports glycol concentration natively:

```rust
let source = BrineSource::new(
    "MEG",
    Pressure::from_pascals(3.0e5),
    Temperature::from_celsius(-10.0),
    Concentration::from_percent(40.0),  // 40% MEG
    backend.clone(),
    port
)?;
```

### 3. Vapor Quality Input

`RefrigerantSource` supports vapor quality input instead of raw enthalpy:

```rust
// Saturated vapor at condenser outlet
let source = RefrigerantSource::new(
    "R410A",
    Pressure::from_pascals(24.0e5),
    VaporQuality::saturated_vapor(),
    backend.clone(),
    port
)?;

// Two-phase mixture
let source = RefrigerantSource::new(
    "R410A",
    Pressure::from_pascals(8.5e5),
    VaporQuality::from_fraction(0.3),  // 30% vapor
    backend.clone(),
    port
)?;
```

### 4. Psychrometrics

`AirSource` supports psychrometric calculations:

```rust
// Outdoor air with humidity
let source = AirSource::from_dry_bulb_rh(
    Temperature::from_celsius(35.0),
    RelativeHumidity::from_percent(50.0),
    Pressure::from_pascals(101_325.0),
    port
)?;
```

## Type Aliases Also Deprecated

The following type aliases are also deprecated:

| Old Alias | Replacement |
|-----------|-------------|
| `IncompressibleSource` | `BrineSource` |
| `CompressibleSource` | `RefrigerantSource` |
| `IncompressibleSink` | `BrineSink` |
| `CompressibleSink` | `RefrigerantSink` |

**Note:** `AirSource` and `AirSink` are new types with no deprecated aliases.

## Need Help?

If you encounter issues during migration:

1. Check the API documentation for the new types
2. Review the examples in the `examples/` directory
3. Open an issue on GitHub with the `migration` label
