TNO Intern

Commit 8ebbb2f1 authored by Florian Knappers's avatar Florian Knappers
Browse files

added all up to doubletcalc

parent 6584d1f2
Loading
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ from dataclasses import dataclass

from pythermogis.workflow.utc.utc_properties import UTCConfiguration
from pythermogis.workflow.utc.doublet_utils import calculate_injection_temp_with_heat_pump
from pythermogis.workflow.utc.pressure import calculate_max_pressure


@dataclass
@@ -36,7 +37,7 @@ class DoubletOutput:
    production_temp: float
    injection_temp: float

def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput) -> DoubletOutput:
def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput) -> DoubletOutput | None:
    well_distance = (
        (props.optim_dist_well_dist_min + props.optim_dist_well_dist_max) / 2
        if props.optim_well_dist
@@ -61,6 +62,17 @@ def calculate_doublet_performance(props: UTCConfiguration, input: DoubletInput)
            props.hp_minimum_injection_temperature
        )

    drawdown_pressure = calculate_max_pressure(
        props,
        input,
        False,
        well_distance,
        injection_temperature,
    )

    if drawdown_pressure == 0:
        return None

    return DoubletOutput(
        power=0.0,
        hppower=0.0,
+24 −1
Original line number Diff line number Diff line
@@ -33,3 +33,26 @@ def calculate_injection_temp_with_heat_pump(
        needed_injection_temp,
        max(reservoir_temp - max_cooling_temp_range, hp_minimum_injection_temperature)
    )

@njit
def get_orc_efficiency(Tx: float, Ts: float, etarel: float) -> float:
    return etarel * (Tx - Ts) / (Tx + Ts + 2 * 273.1)

@njit
def get_cop_carnot(eta: float, Tout: float, Tin: float) -> float:
    if Tout < 0.0 or Tin < 0.0:
        return 0.0

    if eta < 0.0 or eta > 1.0:
        return 0.0

    if Tout < Tin:
        return 0.0

    DHP = 3.0
    TKELVIN = 273.15

    Tcond = Tout + DHP
    Tevap = Tin - DHP

    return eta * (Tcond + TKELVIN) / (Tcond - Tevap)
 No newline at end of file
+21 −0
Original line number Diff line number Diff line
from dataclasses import dataclass
from pythermogis.workflow.utc.utc_properties import UTCConfiguration
from pythermogis.workflow.utc.doublet import DoubletInput

@dataclass
class Doublet1DResults:
    geothermal_powers: float
    cop: float
    flowrate: float
    pump_power_required: float
    production_temp: float
    heat_power_produced: list[float]

def doubletcalc(
        props: UTCConfiguration,
        input: DoubletInput,
        drawdown_pressure: float,
        well_distance: float,
        injection_temp: float,
) -> Doublet1DResults:
    ...
 No newline at end of file
+105 −0
Original line number Diff line number Diff line
from dataclasses import dataclass

from pythermogis.workflow.utc.heatpump import calculate_heat_pump_performance
from pythermogis.workflow.utc.doublet_utils import get_orc_efficiency
from pythermogis.workflow.utc.doubletcalc import doubletcalc

@dataclass
class VolumetricFlowResults:
    hp_cop: float
    hp_added_power: float
    heat_power_per_doublet: float
    cop: float
    flowrate: float
    pump_power_required: float
    production_temp: float
    heat_power_produced: list[float]


def calculate_volumetric_flow(
    props,
    input_data,
    original_pressure: float,
    well_distance: float,
    injection_temp: float
):
    STEPS = [0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6]
    BAR_SI = 1e5  # Units.BAR_SI
    hp_cop = 3.0
    hp_added_power = 0.0

    d1d_results = None
    iter_index = 0

    while d1d_results is None and iter_index < len(STEPS):
        drawdown_pressure = original_pressure + STEPS[iter_index] * BAR_SI

        d1d_results = doubletcalc(
            props, input_data, drawdown_pressure, well_distance, injection_temp
        )
        iter_index += 1

    if d1d_results is None:
        return None

    geothermal_powers = d1d_results.geothermal_powers
    cop = d1d_results.cop
    flowrate = d1d_results.flowrate
    pump_power_required = d1d_results.pump_power_required
    production_temp = d1d_results.production_temp
    heat_power_produced = d1d_results.heat_power_produced

    he2 = props.heat_exchanger_efficiency

    if props.use_orc:
        Ts = props.heat_exchanger_basetemp
        he2 = get_orc_efficiency(
            production_temp, Ts, props.heat_exchanger_efficiency
        )

    heat_power_per_doublet = max(1e-6, geothermal_powers * he2)

    for i in range(len(heat_power_produced)):
        heat_power_produced[i] = max(1e-6, heat_power_produced[i] * he2)

    ignore_subsurface = (
        props.well_cost_scaling
        + props.well_cost_const
        + props.well_cost_z
        + props.well_cost_z2
    ) < 1e-3

    if ignore_subsurface:
        cop = 1e4
        pump_power_required = 0.0

    power_consumption = ((heat_power_per_doublet / he2) / cop) + \
                        (heat_power_per_doublet * props.heat_exchanger_parasitic)

    if props.use_orc:
        heat_power_per_doublet -= power_consumption

    cop = heat_power_per_doublet / power_consumption

    if props.use_heat_pump:
        hp_results = calculate_heat_pump_performance(
            props,
            input_data,
            production_temp,
            injection_temp,
            flowrate
        )

        hp_cop = hp_results.hp_cop
        hp_added_power = hp_results.hp_added_power

    return VolumetricFlowResults(
        hp_cop,
        hp_added_power,
        heat_power_per_doublet,
        cop,
        flowrate,
        pump_power_required,
        production_temp,
        heat_power_produced
    )
 No newline at end of file
+75 −0
Original line number Diff line number Diff line
from dataclasses import dataclass

from pythermogis.workflow.utc.doublet_utils import get_cop_carnot
from pythermogis.workflow.utc.water import get_hydrostatic_pressure, get_salinity, density, heat_capacity

@dataclass
class HeatPumpPerformanceResults:
    hp_cop: float
    hp_added_power: float


def calculate_heat_pump_performance(
    props,
    input_data,
    production_temp: float,
    injection_temp: float,
    flowrate: float,
) -> HeatPumpPerformanceResults:
    ETA_CARNOT = 0.6


    heat_pump_start_temp = calculate_heat_pump_start_temp(
        props, production_temp, injection_temp
    )

    hydrostatic_pressure = get_hydrostatic_pressure(0)

    salinity = get_salinity(
        props.salinity_surface,
        props.salinity_gradient,
        input_data.depth,
    )

    rho_water = density(
        hydrostatic_pressure, props.surface_temperature, salinity
    )

    cp_water = heat_capacity(
        hydrostatic_pressure, props.surface_temperature, salinity
    )

    if props.hp_calc_cop:
        Tout = props.hp_direct_heat_input_temp
        Tin = min(injection_temp, props.dh_return_temp)
        hp_cop = get_cop_carnot(ETA_CARNOT, Tout, Tin)
    else:
        hp_cop = props.hp_capex

    waste_temp = min(heat_pump_start_temp, props.dh_return_temp)
    delta_temp = max(0.0, waste_temp - injection_temp)

    hp_added_power = (flowrate / 3600.0) * delta_temp * rho_water * cp_water * 1e-6

    if hp_added_power == 0:
        hp_cop = 0.0

    return HeatPumpPerformanceResults(
        hp_cop=hp_cop,
        hp_added_power=hp_added_power,
    )


def calculate_heat_pump_start_temp(props, production_temp: float, injection_temp: float) -> float:
    """
    Python version of calculateHeatPumpStartTemp(...)
    """

    delta_temp_geothermal = production_temp - injection_temp
    delta_temp_for_hex = 0.0

    if props.hp_application_mode and production_temp > props.dh_return_temp:
        delta_temp_for_hex = production_temp - props.dh_return_temp
        delta_temp_for_hex = max(0.0, min(delta_temp_for_hex, delta_temp_geothermal))

    return production_temp - delta_temp_for_hex
 No newline at end of file
Loading