friction_loss.solver

  1import io
  2from typing import Dict, Union
  3
  4import numpy as np
  5from polyplan_pvt.pvt_parser import read_pvt_from_bytesio
  6from polypres.data_preparation import split_wrapper, hydrostatic_wrapper, recarr_to_a_tuple
  7from polypres.global_variables import test_pvt_interp_points_count
  8from polypres.pressure_utils import pressure_at_depth
  9
 10from friction_loss.utils.plugin_dataclasses import TransientData
 11from friction_loss.utils.const import PA_TO_BAR
 12
 13
 14def find_pressure(pvt_bytes: bytes, well_points, transients_data: np.ndarray, is_producer: np.ndarray,
 15                  report_flag: bool, depth: float) -> Dict[str, Union[TransientData, np.ndarray, None]]:
 16    """
 17    Parameters
 18    ----------
 19    pvt_bytes: bytes
 20        Bytes of json file with PVT table data
 21    well_points : np.ndarray(DepthSortedWellPointsKeeper)
 22        Structure of the elements of the Polypres library well construction.
 23    transients_data : np.ndarray(dict[int, TransientData])
 24        keys : Number of transient.
 25        value : Pressure and rate data by phase for this transient.
 26    is_producer : np.ndarray(bool)
 27        Flag of producer wells (True - producer wells; False - injection wells).
 28    report_flag : bool
 29        Flag of generation web-report.
 30    depth: float
 31        Dictionary with referenced depth
 32
 33    Returns
 34    -------
 35    dict
 36        'downhole_pressure' : np.ndarray(float)
 37            Recalculated pressure.
 38        'data' : PDCTransientData
 39            Pressure and flow rate data for each time point
 40    """
 41    pvt_stream = io.BytesIO(pvt_bytes)
 42    pvt = read_pvt_from_bytesio(pvt_stream, test_pvt_interp_points_count, True)
 43
 44    # Number of wells
 45    n = len(well_points)
 46    depth_pressure = np.empty(n, np.ndarray)
 47    out_data = np.empty(n, object)
 48
 49    # TODO: распараллелить все!!!
 50    for i in range(n):
 51        depth_pressure[i], out_data[i] = _calc_p_in_well(pvt, well_points[i], transients_data[i],
 52                                                         is_producer[i], report_flag, depth)
 53    if not report_flag:
 54        out_data = None
 55    return {'downhole_pressure': depth_pressure,
 56            'data': out_data}
 57
 58
 59def _calc_p_in_well(pvt: np.recarray, well_points, transients_data: Dict[int, TransientData],
 60                    is_producer: bool, report_flag: bool, depth: float) -> (np.ndarray, TransientData):
 61    # Geometry of the well.
 62    vlp_inputs = well_points.unique_points
 63
 64    qo_arr = np.concatenate(
 65        [np.full(len(transients_data[j].pressure), transients_data[j].qo) for j in range(len(transients_data))])
 66    qw_arr = np.concatenate(
 67        [np.full(len(transients_data[j].pressure), transients_data[j].qw) for j in range(len(transients_data))])
 68    qg_arr = np.concatenate(
 69        [np.full(len(transients_data[j].pressure), transients_data[j].qg) for j in range(len(transients_data))])
 70    p_arr = np.concatenate(
 71        [transients_data[j].pressure for j in range(len(transients_data))])
 72
 73    vlp_inputs['qzi_g'] = [qg_arr for i in vlp_inputs]
 74    vlp_inputs['qzi_o'] = [qo_arr for i in vlp_inputs]
 75    vlp_inputs['qzi_w'] = [qw_arr for i in vlp_inputs]
 76
 77    params_rows, pogw, n = recarr_to_a_tuple(vlp_inputs)
 78    idx = [i for i, val in enumerate(pogw) if np.all(~np.isnan(val[:n]))][0]
 79    pogw[idx][:n] = p_arr
 80    result_rates, vlp_arr, pressure_log, up_cond = split_wrapper(pvt, params_rows, pogw, n, is_producer)
 81
 82    vlp_arr, pressure_log, _ = hydrostatic_wrapper(vlp_inputs, params_rows, n, up_cond, p_arr,
 83                                                   pogw, pvt, vlp_arr, pressure_log)
 84    if np.isnan(depth):
 85        depth_pressure = vlp_arr * PA_TO_BAR
 86    else:
 87        depth_pressure = np.array([pressure_at_depth(pressure_log, depth, i) for i in range(len(p_arr))])
 88
 89    out_data = None
 90    if report_flag:
 91        x = np.array([np.array(i) for i, _ in pressure_log])
 92        y = np.array([np.array(i) for _, i in pressure_log])
 93        out_data = TransientData(pressure=[x, y],
 94                                 qo=qo_arr,
 95                                 qg=qg_arr,
 96                                 qw=qw_arr,
 97                                 pressure_unit='Pa',
 98                                 qo_unit='m^3/sec',
 99                                 qg_unit='m^3/sec',
100                                 qw_unit='m^3/sec')
101
102    return depth_pressure, out_data
def find_pressure( pvt_bytes: bytes, well_points, transients_data: numpy.ndarray, is_producer: numpy.ndarray, report_flag: bool, depth: float) -> Dict[str, Union[friction_loss.utils.plugin_dataclasses.TransientData, numpy.ndarray, NoneType]]:
15def find_pressure(pvt_bytes: bytes, well_points, transients_data: np.ndarray, is_producer: np.ndarray,
16                  report_flag: bool, depth: float) -> Dict[str, Union[TransientData, np.ndarray, None]]:
17    """
18    Parameters
19    ----------
20    pvt_bytes: bytes
21        Bytes of json file with PVT table data
22    well_points : np.ndarray(DepthSortedWellPointsKeeper)
23        Structure of the elements of the Polypres library well construction.
24    transients_data : np.ndarray(dict[int, TransientData])
25        keys : Number of transient.
26        value : Pressure and rate data by phase for this transient.
27    is_producer : np.ndarray(bool)
28        Flag of producer wells (True - producer wells; False - injection wells).
29    report_flag : bool
30        Flag of generation web-report.
31    depth: float
32        Dictionary with referenced depth
33
34    Returns
35    -------
36    dict
37        'downhole_pressure' : np.ndarray(float)
38            Recalculated pressure.
39        'data' : PDCTransientData
40            Pressure and flow rate data for each time point
41    """
42    pvt_stream = io.BytesIO(pvt_bytes)
43    pvt = read_pvt_from_bytesio(pvt_stream, test_pvt_interp_points_count, True)
44
45    # Number of wells
46    n = len(well_points)
47    depth_pressure = np.empty(n, np.ndarray)
48    out_data = np.empty(n, object)
49
50    # TODO: распараллелить все!!!
51    for i in range(n):
52        depth_pressure[i], out_data[i] = _calc_p_in_well(pvt, well_points[i], transients_data[i],
53                                                         is_producer[i], report_flag, depth)
54    if not report_flag:
55        out_data = None
56    return {'downhole_pressure': depth_pressure,
57            'data': out_data}

Parameters

pvt_bytes: bytes Bytes of json file with PVT table data well_points : np.ndarray(DepthSortedWellPointsKeeper) Structure of the elements of the Polypres library well construction. transients_data : np.ndarray(dict[int, TransientData]) keys : Number of transient. value : Pressure and rate data by phase for this transient. is_producer : np.ndarray(bool) Flag of producer wells (True - producer wells; False - injection wells). report_flag : bool Flag of generation web-report. depth: float Dictionary with referenced depth

Returns

dict 'downhole_pressure' : np.ndarray(float) Recalculated pressure. 'data' : PDCTransientData Pressure and flow rate data for each time point