module bo_fl_types
implicit none
real(8), parameter, public :: OGlimit = 100.0d0 ! bbl/MMSCF limit for gas enthalpy calc
real(8), parameter, public :: t_basis = 298.15 ! basis temperature for enthalpy, K
real(8), parameter, public :: p_basis = 101325.0 ! basis pressure for enthalpy, Pa
real(8), parameter, public :: runset = -1e31
integer, parameter, public :: iunset = -383838383
integer, parameter, public :: s_names = 256
type, public :: t_meas
sequence
real(8) :: val = runset ! measured value, i.e. measurement supplied by the user
real(8) :: wgt = runset ! weight
real(8) :: calc = runset ! calculated value, i.e. result from the simulation
end type
type, public :: t_measurement
sequence
character(s_names) :: name = ' ' ! name of measurement point
integer :: branch_num = iunset ! branch number where measurement is associated
integer :: location = iunset ! location wrt the branch. can be:
! -1 start of branch
! -2 end of branch
! -3 in the upstream branch
! +ve an element number of the pipe position arrays
real(8) :: ref_temp = runset ! temperature reference for the measurement, used to correct the
! measured value from 288.73 K to the reference value
type(t_meas) :: pressure ! measured value and weight
type(t_meas) :: temperature ! measured value and weight
type(t_meas) :: vfgas ! measured value and weight, Volume Fraction of Gas
type(t_meas) :: vfoil ! measured value and weight
type(t_meas) :: vfwat ! measured value and weight
type(t_meas) :: mfgas ! measured value and weight, Mass Fraction of Gas
type(t_meas) :: mfoil ! measured value and weight
type(t_meas) :: mfwat ! measured value and weight
type(t_meas) :: watcut ! measured value and weight
type(t_meas) :: Qgas ! measured value and weight
type(t_meas) :: Qoil ! measured value and weight
type(t_meas) :: Qliq ! measured value and weight
type(t_meas) :: Qwat ! measured value and weight
type(t_meas) :: STGas ! measured value and weight
type(t_meas) :: STOil ! measured value and weight
type(t_meas) :: STLiq ! measured value and weight
type(t_meas) :: STWat ! measured value and weight
type(t_meas) :: STGOR ! measured value and weight
type(t_meas) :: STWCUT ! measured value and weight
type(t_meas) :: Velgas ! measured value and weight
type(t_meas) :: Velliq ! measured value and weight
type(t_meas) :: mixdensity ! measured value and weight
type(t_meas) :: mass_rate ! calculated value and weight, see bo_fluids_mod for calculation
integer(8) :: end_mark = 54321 ! last element for checksum
character(:), allocatable :: pos_statement ! text of position statement where measurement should be taken
end type
type, public :: t_multipoint_calib_1_result
sequence
real(8), allocatable :: calc(:) ! individual calculated results
real(8), allocatable :: errs(:) ! individual measurement errors
real(8) :: errf = 0. ! sum of squares of errors
end type
type, public :: t_multipoint_calib_results
sequence
type (t_multipoint_calib_1_result) :: Rs ! error in each Rs measurement
type (t_multipoint_calib_1_result) :: Rv ! error in each Rv measurement
type (t_multipoint_calib_1_result) :: sod ! error in each SOD/FVF measurement
type (t_multipoint_calib_1_result) :: uod ! error in each UOD
type (t_multipoint_calib_1_result) :: sov ! error in each SOV mesurement
type (t_multipoint_calib_1_result) :: uov ! error in each SOV mesurement
type (t_multipoint_calib_1_result) :: gz ! error in each Gas Z mesurement
type (t_multipoint_calib_1_result) :: gv ! error in each Gas vis mesurement
end type
!-----BLACK OIL fluids-------------------------------------------------------------------------------------------------
type, public :: t_calib
sequence
character(12) :: correlation = ' ' ! name of corelation
character(4) :: padding = 'abcd' ! to make it all a multiple of 8 bytes
real(8) :: pressure = runset ! pressure of this calibration point
real(8) :: temperature = runset !
real(8) :: bppressure = runset ! bubble point pressure for arrays below
real(8) :: measurement = runset ! measured value of quantity at above P & T
real(8) :: factor = runset ! correlation adjustment factor resulting from the tuning calc
real(8) :: untuned_value = runset ! untuned value of quantity
character(4) :: type = ' ' ! additional info that distinguishes the type of quantity being
logical :: fix_stocktank = .false. ! for multipoint calibration, enables correction of stocktank
! value to match measured value
logical :: choose_best_fit_corr = .false. ! if we need to reset the correlation to the best fitting one
logical :: st_adjust = .false. ! for all calls, adjust the correlation so it goes through the
! "correct" value at stock-tank P & T. For Rs this is zero; for
! FVF this is 1; not sure any other quantities have such a
! "correct" value, but anyway, lets see...
real(8), allocatable :: apres(:) ! array or pressures for matching
real(8), allocatable :: ameas(:) ! array of measured values for matching
real(8), allocatable :: afac (:) ! array of factors calculated from matching
end type
type, public :: t_bergsut_data
sequence
real(8) :: Blin = runset
real(8) :: Alin = runset
end type
type, public :: t_dovcalib
sequence
character(12) :: correlation = 'GLASO' ! name of correlation
character(4) :: padding = 'abcd' ! to make it all a multiple of 8 bytes
real(8) , allocatable :: temps(:) ! temperature points (K)
real(8) , allocatable :: viscs(:) ! viscosity points (Pa.S)
type (t_bergsut_data), allocatable :: bergsut_data ! data for bergman & sutton DOV correlation
end type
type, public :: t_bo_fluid
sequence
character(16) :: preamble = 'ABCDEFGHIJKLMNOP'
type (t_calib) :: rs_calib = t_calib('STANDING') ! Rs correlation and calibration point (vol/vol)
type (t_calib) :: rv_calib = t_calib('NONE' ) ! Rv correlation and calibration point (vol/vol)
type (t_calib) :: sod_calib = t_calib('STANDING') ! Saturated Oil Density data (kg/m3)
type (t_calib) :: uod_calib = t_calib('STANDING') ! Unsaturated oil density data (kg/m3)
type (t_calib) :: sov_calib = t_calib('BEGROB' ) ! Saturated Oil Viscosity data (Pa.sec)
type (t_calib) :: uov_calib = t_calib('VAZBEG' ) ! Unsaturated oil viscosity data (Pa.sec)
type (t_calib) :: gz_calib = t_calib('STANDING') ! Gas Z factor data (unitless)
type (t_calib) :: gv_calib = t_calib('LEE' ) ! Gas Viscosity data (Pa.sec)
type (t_dovcalib) :: dov_calib ! Dead oil Viscosity correlation and calib data, for temperature dependence
!!! type (t_emulcalib) :: emul_calib ! Emulsion Viscosity correlation and calib data
logical :: valid = .false. ! only set true by finish_fluid_definition
character(4) :: padding = 'abcd' ! to make it all a multiple of 8 bytes
real(8) :: st_od = runset ! 750. ! stock-tank (dead) oil density (kg/m3)
real(8) :: WatsonK = runset ! Watson K-factor of the oil, if known
real(8) :: st_wd = runset ! 1024. ! stock-tank water density (kg/m3)
real(8) :: st_gd = runset ! 0.8 ! stock-tank gas density (kg/m3)
real(8) :: st_vfg = runset ! stock-tank volume fraction gas
real(8) :: st_vfo = runset ! stock-tank volume fraction oil
real(8) :: st_vfw = runset ! stock-tank volume fraction water
real(8) :: st_mfg = runset ! stock-tank mass fraction of gas
real(8) :: st_mfo = runset ! stock-tank mass fraction of oil
real(8) :: st_mfw = runset ! stock-tank mass fraction of water
character(8) :: st_frac_type = 'volume' ! 'mass' or 'volume' to specify which of the above are set by the user
character(12) :: sten_go_corr = 'ABDULMAJEED' ! correlation for gas-oil surface tension
character(12) :: sten_gw_corr = 'ACF' ! correlation for gas-water surface tension
character(12) :: sten_ow_corr = 'xxx' ! correlation for oil-water surface tension
character(12) :: gas_pcpt_corr = 'STANDING' ! correlation for Gas Pseudo-Critical Pressure & Temperature
character(12) :: wd_corr = 'MCCAIN' ! correlation for water density, FVF, compressibility
character(12) :: wv_corr = 'MCCAIN' ! correlation for water viscosity
! Thermal data, for enthalpy calculation
real(8) :: gas_cp = 0.7 ! J/kg/K, == 0.7 BTU/lbF
real(8) :: oil_cp = 0.5 ! J/kg/k, == 0.5 BTU/lbF
real(8) :: wat_cp = 1.0 ! J/kg/K, == 1 BTU/lbF
real(8) :: gas_hvap = 140. ! J/Kg, == 140 BTU/lb
real(8) :: gas_jt = 0.07 ! K/Pa, == 0.07 F/psia, AGA approximation (www.aga.org/Kc/glossary/Pages/J.aspx, needs user login). also 4.655e-6.
real(8) :: oil_jt = -5d-7 ! K/Pa, Q's guess
real(8) :: wat_jt = -2.5d-7 ! K/Pa, Q's guess
logical :: taper_gas_hvap = .false. ! apply reduction to HVAP based on ratio of gas & oil densities
logical :: taper_gas_jt = .true. ! apply reduction to gas JT as pressure increases
character(12) :: enth_model = 'MAXEUR' ! correlation for enthalpy
integer :: enth_model_sub = 0 ! "sub" corr for MAXEUR: 1='ACFGAS', 2='ACFOIL' or 3='BLEND'
!!! real(8) :: illegality_fraction = 0. ! assigned during a mix; represents the portion of this fluid, that
! originated from an "illegal fluid" (i.e. one that was invented at
! a sink acting as a source, or a junction with no feed branch)
real(8) :: mfCO2 = 0.0 ! mole fraction Carbon Dioxide; N.B. Was mass fraction !
real(8) :: mfH2S = 0.0 ! mole fraction Hydrogen Sulphide
real(8) :: mfN2 = 0.0 ! mole fraction Nitrogen
! Corrosion data
real(8) :: pHact = runset ! fluid pH (-)
character(12) :: gtype = '****' ! type of gas ratio: GLR, GOR, OGR or LGR
character(12) :: wtype = '****' ! type of water ratio: WCUT, WGR, or GWR
real(8) :: gratio = runset ! value of gratio
real(8) :: wratio = runset ! value of wratio
! following BP data provides an alternative to specifying the
! GRATIO.
real(8) :: BPpressure = runset ! bubble poiont pressure (Pa)
real(8) :: BPtemperature = runset ! bubble poiont temperature (K)
logical :: bubble_point_set = .false. ! signals the need to convert these to a GOR
logical :: calibration_needs_doing = .false. ! signals the need to call the calibration code.
! This gets set when any calibration data is changed,
! or correlations changed, or gassg or api changed.
character(12) :: calibration_type = 'NONE' ! can be SINGLE, MULTI, or FACTORS, depending on input data supplied
character(4) :: more_padding = 'abcd' ! to make it all a multiple of 8 bytes
! Derived values... these are calculated in routine finish_bo_fluid_definition in bo_fluids_mod.f90:
real(8) :: st_glr = runset ! gas-liquid ratio, volume/volume
real(8) :: st_gor = runset ! .
real(8) :: st_ogr = runset ! .
real(8) :: st_lgr = runset ! .
real(8) :: st_wgr = runset ! .
real(8) :: st_gwr = runset ! .
real(8) :: st_vfwl = runset ! volume fraction of water in liquid, fraction 0 to 1
real(8) :: st_ovis = runset ! oil viscosity
real(8) :: st_wvis = runset ! water viscosity
! Derivatives of phase volume fractions wrt flowrate ... Adrian's crackuot idea, but worth a few beers if he gets it to work
real(8) :: dmgdr = 0. ! derivative of mass fraction stgas vs rate
real(8) :: dmwdr = 0. ! derivative of mass fraction stwater vs rate
type(t_measurement), allocatable :: measurement ! measured values of P, T, VFG/O/W, plus some more things not directly applicable to fluids
type(t_multipoint_calib_results), allocatable :: mcalib_res ! results of multipoint calibration
integer(8) :: handle = 0 ! checksum/handle
end type t_bo_fluid
type, public :: t_calib_results
sequence
real(8) :: pRsO = runset ! "potential" Rs: gas that would disolve in the oil phase std.vol/std.vol
real(8) :: upRsO = runset ! Unlimited "potential" Rs, can go negative, used for tuning calcs vol/vol
real(8) :: p_sat_oil_dens = runset ! saturated oil density assuming Rs == pRsO
real(8) :: Bob = runset ! Oil Bo (FVF) at bubble point pressure
real(8) :: dov = runset ! dead Oil viscosity at atmosp and flash temperature
real(8) :: sov_at_pRs = runset ! Saturated Oil viscosity assuming Rs == pRso
real(8) :: sov_at_gor = runset ! Saturated Oil viscosity assuming Rs == GOR
end type
end module
program ivf_test
use bo_fl_types
implicit none
type t_fluid
real(8) :: bb(1000)
type(t_bo_fluid) :: bo
real(8) :: aa(2000)
end type
type(t_fluid) :: fl
type(t_fluid) afl ! , allocatable :: afl
fl%bo%rs_calib%apres = [1d0,2d0,3d0,4d0,5d0] ! without this, it runs without error
!! allocate(afl) ! fails with or without this
afl = fl ! fails here. forrtl: severe (157): Program Exception - access violation
print *, afl%bo%rs_calib%apres
end program