TNO Intern

Commit 82438826 authored by Florian Knappers's avatar Florian Knappers
Browse files

debugzzz

parent 90ed71e5
Loading
Loading
Loading
Loading
Loading
+56 −0
Original line number Diff line number Diff line
from pythermogis.workflow.utc.flow import calculate_volumetric_flow


def calculate_cooling_temperature(
    props,
    input,
    drawdown_pressure: float,
    well_distance: float,
    injection_temp: float
) -> float:

    results = calculate_volumetric_flow(
        props=props,
        input_data=input,
        original_pressure=drawdown_pressure,
        well_distance=well_distance,
        injection_temp=injection_temp,
    )

    flowrate = min(results.flowrate, props.max_flow)

    cooling_frac_min = 0.0
    cooling_frac_max = 0.5
    cooling_frac = 0.5 * (cooling_frac_min + cooling_frac_max)

    for _ in range(1000):
        if abs(cooling_frac_max - cooling_frac_min) <= 0.001:
            break

        cooling_frac = 0.5 * (cooling_frac_min + cooling_frac_max)

        lifetime = calc_lifetime(
            well_distance=well_distance,
            thickness=input.thickness * input.ntg,
            delta_temp_fraction=cooling_frac,
            porosity=input.porosity,
            flowrate=flowrate,
            depth=input.depth,
            reservoir_temp=input.temperature,
            salinity_surface=props.salinity_surface,
            salinity_gradient=props.salinity_gradient,
            cp_rock=props.optim_dist_cp_rock,
            rho_rock=props.optim_dist_rho_rock,
        )

        if lifetime < props.optim_dist_lifetime:
            cooling_frac_min = cooling_frac
        else:
            cooling_frac_max = cooling_frac

    if (not props.is_ates) and cooling_frac > 0.3:
        raise RuntimeError(
            f"Large cooling factor ({cooling_frac}) could result in less reliable calculation"
        )

    return cooling_frac * (input.temperature - injection_temp)
+3 −1
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_utils import optimize_well_distance, calculate_injection_temp_with_heat_pump, calculate_cooling_temperature, \
from pythermogis.workflow.utc.doublet_utils import calculate_injection_temp_with_heat_pump, \
    calc_lifetime
from pythermogis.workflow.utc.pressure import calculate_max_pressure, optimize_pressure
from pythermogis.workflow.utc.cooling_temp import calculate_cooling_temperature
from pythermogis.workflow.utc.well_distance import optimize_well_distance

EUR_PER_CT_PER_KWH = 0.36
NPV_SCALE = 1e-6
+0 −111
Original line number Diff line number Diff line
import math
from numba import njit
from pythermogis.workflow.utc.flow import calculate_volumetric_flow
from pythermogis.workflow.utc.water import density, heat_capacity, get_salinity, get_hydrostatic_pressure

@njit
@@ -61,61 +60,6 @@ def get_cop_carnot(eta: float, Tout: float, Tin: float) -> float:
    return eta * (Tcond + TKELVIN) / (Tcond - Tevap)


def calculate_cooling_temperature(
    props,
    input,
    drawdown_pressure: float,
    well_distance: float,
    injection_temp: float
) -> float:

    results = calculate_volumetric_flow(
        props=props,
        input_data=input,
        original_pressure=drawdown_pressure,
        well_distance=well_distance,
        injection_temp=injection_temp,
    )

    flowrate = min(results.flowrate, props.max_flow)

    cooling_frac_min = 0.0
    cooling_frac_max = 0.5
    cooling_frac = 0.5 * (cooling_frac_min + cooling_frac_max)

    for _ in range(1000):
        if abs(cooling_frac_max - cooling_frac_min) <= 0.001:
            break

        cooling_frac = 0.5 * (cooling_frac_min + cooling_frac_max)

        lifetime = calc_lifetime(
            well_distance=well_distance,
            thickness=input.thickness * input.ntg,
            delta_temp_fraction=cooling_frac,
            porosity=input.porosity,
            flowrate=flowrate,
            depth=input.depth,
            reservoir_temp=input.temperature,
            salinity_surface=props.salinity_surface,
            salinity_gradient=props.salinity_gradient,
            cp_rock=props.optim_dist_cp_rock,
            rho_rock=props.optim_dist_rho_rock,
        )

        if lifetime < props.optim_dist_lifetime:
            cooling_frac_min = cooling_frac
        else:
            cooling_frac_max = cooling_frac

    if (not props.is_ates) and cooling_frac > 0.3:
        raise RuntimeError(
            f"Large cooling factor ({cooling_frac}) could result in less reliable calculation"
        )

    return cooling_frac * (input.temperature - injection_temp)


def calc_lifetime(
    well_distance: float,
    thickness: float,
@@ -169,61 +113,6 @@ def calc_lifetime(
    return Eseg / Eflowseg


def optimize_well_distance(
    props,
    input,
    drawdown_pressure: float,
    injection_temp: float,
) -> float:

    dist_min = props.optim_dist_well_dist_min
    dist_max = props.optim_dist_well_dist_max
    dist = 0.5 * (dist_min + dist_max)

    for iter_count in range(1000):
        if abs(dist_max - dist_min) <= 10.0:
            break

        dist = 0.5 * (dist_min + dist_max)

        # --- Compute flow for this distance ---
        results = calculate_volumetric_flow(
            props=props,
            input_data=input,
            original_pressure=drawdown_pressure,
            well_distance=dist,
            injection_temp=injection_temp,
        )

        flowrate = min(results.flowrate, props.max_flow)

        # --- Compute lifetime for this distance ---
        lifetime = calc_lifetime(
            well_distance=dist,
            thickness=input.thickness * input.ntg,
            delta_temp_fraction=props.optim_dist_cooling_fraction,
            porosity=input.porosity,
            flowrate=flowrate,
            depth=input.depth,
            reservoir_temp=input.temperature,
            salinity_surface=props.salinity_surface,
            salinity_gradient=props.salinity_gradient,
            cp_rock=props.optim_dist_cp_rock,
            rho_rock=props.optim_dist_rho_rock,
        )

        # --- Bisection rule ---
        if lifetime < props.optim_dist_lifetime:
            dist_min = dist
        else:
            dist_max = dist

    # If no convergence in 1000 iterations
    else:
        print(f"WARNING: Well distance optimization failed to converge. Final dist={dist}")

    return dist


def get_along_hole_length(
    true_vertical_depth: float,
+13 −16
Original line number Diff line number Diff line
import math
from typing import TYPE_CHECKING

from dataclasses import dataclass
from pythermogis.workflow.utc.utc_properties import UTCConfiguration
@@ -7,8 +6,6 @@ from pydoubletcalc import Aquifer, Doublet, Well, WellPipeSegment
from pythermogis.workflow.utc.water import get_salinity
from pythermogis.workflow.utc.rock import get_geothermal_gradient

if TYPE_CHECKING:
    from pythermogis.workflow.utc.doublet import DoubletInput

INCH_SI = 0.0254

@@ -23,7 +20,7 @@ class Doublet1DResults:

def doubletcalc(
        props: UTCConfiguration,
        input: DoubletInput,
        input,
        drawdown_pressure: float,
        well_distance: float,
        injection_temp: float,
@@ -45,12 +42,12 @@ def doubletcalc(
    injector = Well(
        aquifer=aquifer,
        well_type="injector",
        pipe_segments=WellPipeSegment(
        pipe_segments=[WellPipeSegment(
            ah_depth=input.depth,
            tv_depth=get_along_hole_length(input.depth, well_distance, props.well_curv_scaling, props.max_tvd_stepout_factor),
            inner_diameter=props.inner_diameter * INCH_SI,
            rougness=props.roughness * 1e-3 * INCH_SI
        ),
            roughness=props.roughness * 1e-3 * INCH_SI
        )],
        aquifer_top_depth=input.depth,
        pipe_scaling=0,
        target_segment_length=props.segment_length,
@@ -67,12 +64,12 @@ def doubletcalc(
    producer = Well(
        aquifer=aquifer,
        well_type="producer",
        pipe_segments=WellPipeSegment(
        pipe_segments=[WellPipeSegment(
            ah_depth=input.depth,
            tv_depth=get_along_hole_length(input.depth, well_distance, props.well_curv_scaling, props.max_tvd_stepout_factor),
            inner_diameter=props.inner_diameter * INCH_SI,
            rougness=props.roughness * 1e-3 * INCH_SI
        ),
            roughness=props.roughness * 1e-3 * INCH_SI
        )],
        aquifer_top_depth=input.depth,
        pipe_scaling=0,
        target_segment_length=props.segment_length,
@@ -109,23 +106,23 @@ def doubletcalc(
    )

def get_total_skin_injection(props, input):
    if (not props.use_stimulation()) or (input.transmissivity_with_ntg() > props.stim_kh_max()):
    if (not props.use_stimulation) or (input.transmissivity_with_ntg > props.stim_kh_max):
        stim_add_skin_inj = 0.0
    else:
        stim_add_skin_inj = props.stim_add_skin_inj()

    return props.skin_injector() + stim_add_skin_inj
    return props.skin_injector + stim_add_skin_inj

def get_total_skin_production(props, input):
    if (not props.use_stimulation()) or (input.transmissivity_with_ntg() > props.stim_kh_max()):
    if (not props.use_stimulation) or (input.transmissivity_with_ntg > props.stim_kh_max):
        stim_add_skin_prod = 0.0
    else:
        stim_add_skin_prod = props.stim_add_skin_prod()
        stim_add_skin_prod = props.stim_add_skin_prod

    return props.skin_producer() + stim_add_skin_prod
    return props.skin_producer + stim_add_skin_prod

def get_pump_production_depth(props, depth: float) -> float:
    return min(props.pump_depth(), depth / 2)
    return min(props.pump_depth, depth / 2)

def get_along_hole_length(
    true_vertical_depth: float,
+58 −0
Original line number Diff line number Diff line
from pythermogis.workflow.utc.doublet_utils import calc_lifetime
from pythermogis.workflow.utc.flow import calculate_volumetric_flow


def optimize_well_distance(
    props,
    input,
    drawdown_pressure: float,
    injection_temp: float,
) -> float:

    dist_min = props.optim_dist_well_dist_min
    dist_max = props.optim_dist_well_dist_max
    dist = 0.5 * (dist_min + dist_max)

    for iter_count in range(1000):
        if abs(dist_max - dist_min) <= 10.0:
            break

        dist = 0.5 * (dist_min + dist_max)

        # --- Compute flow for this distance ---
        results = calculate_volumetric_flow(
            props=props,
            input_data=input,
            original_pressure=drawdown_pressure,
            well_distance=dist,
            injection_temp=injection_temp,
        )

        flowrate = min(results.flowrate, props.max_flow)

        # --- Compute lifetime for this distance ---
        lifetime = calc_lifetime(
            well_distance=dist,
            thickness=input.thickness * input.ntg,
            delta_temp_fraction=props.optim_dist_cooling_fraction,
            porosity=input.porosity,
            flowrate=flowrate,
            depth=input.depth,
            reservoir_temp=input.temperature,
            salinity_surface=props.salinity_surface,
            salinity_gradient=props.salinity_gradient,
            cp_rock=props.optim_dist_cp_rock,
            rho_rock=props.optim_dist_rho_rock,
        )

        # --- Bisection rule ---
        if lifetime < props.optim_dist_lifetime:
            dist_min = dist
        else:
            dist_max = dist

    # If no convergence in 1000 iterations
    else:
        print(f"WARNING: Well distance optimization failed to converge. Final dist={dist}")

    return dist
Loading