Gethermal energy paper

In this notebook, I'll read all the sheets in the excel files provide by Hamid, and save them in csv files. Then I'll load and analyze them. For a weird reason, all the units in this notebook are SI, except for energy and exergy that are reported in kJ instead of J. Sometimes, I forget to say that the units are kJ/s and not kJ. I try to fix, otherwise figure it out for yourselves.
BE CAREFUL: always run this notebook by choosing run all from the cell menu.

power plant efficiency and emission factors

I have calculated the efficiency factors of the fossil fuel power plants. Here, I need to use the chemical exergy and CO2 emission of coal and natural gas to estimate the CO2 emission of the power plants. Let's go to work:


In [16]:
using JLD
# efficiency factors
η_pc   = 0.34 # pulverized coal power plant efficiency
η_igcc = 0.40 # integrated gasification combined cycle
η_ngcc = 0.45 # natural gas combined cycle

# fossil fuels chemical exergy
MW_CO2  = 0.044 # kg/mol
# 1- coal; formula: CH
ex_coal = 400 + 100      # kJ/mol
MW_coal = 12 + 1         # g/mol
em_coal = MW_CO2/ex_coal # kg CO2/kJ chemical exergy
# 2- natural gas; formula: CH4
ex_gas  = 400 + 4*100   # kJ/mol
MW_gas  = 12 + 4        # g/mol
em_gas  = MW_CO2/ex_gas # kg CO2/kJ chemical exergy

e_pc    = em_coal/η_pc   # kg CO2/kJ electricity
e_igcc  = em_coal/η_igcc # kg CO2/kJ electricity
e_ngcc  = em_gas/η_ngcc  # kg CO2/kJ electricity

eta_pump = 0.8; # pump mechanical efficiency
eta_driver = 0.8 # electrical driver efficiency
ex_ccs = 5000 # [kJ/kg CO2]


Out[16]:
5000

In [17]:
# @save "input_param.jld"

The above numbers will be used later in the exergy analysis below.


In [18]:
using DataFrames, PyPlot, CoolProp, Dierckx, CSV
include("SetPyPlot.jl")
SetPyPlot.setrcparam()
PyPlot.svg(false)
p0 = 101325 # [Pa]
T0 = 20+273.15 # [K]


WARNING: replacing module SetPyPlot.
Out[18]:
293.15

In [19]:
# some functions
function fric_factor(Re)
    if Re<4000
        f = 64/Re
    else
        f = 0.25/(log10(5.74/Re^0.9))^2
    end
    return f
end

function trapz(t, h)
    return 0.5*sum((h[2:end]+h[1:end-1]).*(t[2:end]-t[1:end-1]))
end

function cum_trapz(t, h)
    return 0.5*cumsum([0.0; (h[2:end]+h[1:end-1]).*(t[2:end]-t[1:end-1])])
end

function water_exergy(T, p, T0, p0)
    if length(T)>1
        dh = zeros(length(T))
        ds = zeros(length(T))
        for i in eachindex(T)
            dh[i] = PropsSI("HMASS", "T", T[i], "P", p, "H2O")-
                PropsSI("HMASS", "T", T0, "P", p0, "H2O")
            ds[i] = PropsSI("SMASS", "T", T[i], "P", p, "H2O")-
                PropsSI("SMASS", "T", T0, "P", p0, "H2O")
        end
    else
        dh = PropsSI("HMASS", "T", T, "P", p, "H2O")-
                PropsSI("HMASS", "T", T0, "P", p0, "H2O")
        ds = PropsSI("SMASS", "T", T, "P", p, "H2O")-
            PropsSI("SMASS", "T", T0, "P", p0, "H2O")
    end
    return dh-T0*ds
end

function water_heat(T, p, T0, p0)
    if length(T)>1
        dh = zeros(length(T))
        ds = zeros(length(T))
        for i in eachindex(T)
            dh[i] = PropsSI("HMASS", "T", T[i], "P", p, "H2O")-
                PropsSI("HMASS", "T", T0, "P", p0, "H2O")
        end
    else
        dh = PropsSI("HMASS", "T", T, "P", p, "H2O")-
                PropsSI("HMASS", "T", T0, "P", p0, "H2O")
    end
    return dh
end

function water_density(T, p)
    if length(T)>1
        rho = zeros(length(T))
        for i in eachindex(T)
            rho[i] = PropsSI("D", "T", T[i], "P", p, "H2O")
        end
    else
        rho = PropsSI("D", "T", T, "P", p, "H2O")
    end
    return rho
end


Out[19]:
water_density (generic function with 1 method)

In [20]:
PropsSI("D", "T", 300, "P", 1e5, "H2O")


Out[20]:
996.5563403888981

Load the saved simulation files


In [21]:
df_res = CSV.read("results/res_guide.csv")


Out[21]:

150 rows × 4 columns

q_m3_hk_DL_mcsv_name
Float64Float64Float64String
150.00.02500.0results/Q-50.0-L-500.0-k0.02.csv
250.00.02650.0results/Q-50.0-L-650.0-k0.02.csv
350.00.02800.0results/Q-50.0-L-800.0-k0.02.csv
450.00.02900.0results/Q-50.0-L-900.0-k0.02.csv
550.00.021000.0results/Q-50.0-L-1000.0-k0.02.csv
650.00.05500.0results/Q-50.0-L-500.0-k0.05.csv
750.00.05650.0results/Q-50.0-L-650.0-k0.05.csv
850.00.05800.0results/Q-50.0-L-800.0-k0.05.csv
950.00.05900.0results/Q-50.0-L-900.0-k0.05.csv
1050.00.051000.0results/Q-50.0-L-1000.0-k0.05.csv
1150.00.1500.0results/Q-50.0-L-500.0-k0.1.csv
1250.00.1650.0results/Q-50.0-L-650.0-k0.1.csv
1350.00.1800.0results/Q-50.0-L-800.0-k0.1.csv
1450.00.1900.0results/Q-50.0-L-900.0-k0.1.csv
1550.00.11000.0results/Q-50.0-L-1000.0-k0.1.csv
1650.00.2500.0results/Q-50.0-L-500.0-k0.2.csv
1750.00.2650.0results/Q-50.0-L-650.0-k0.2.csv
1850.00.2800.0results/Q-50.0-L-800.0-k0.2.csv
1950.00.2900.0results/Q-50.0-L-900.0-k0.2.csv
2050.00.21000.0results/Q-50.0-L-1000.0-k0.2.csv
2150.00.5500.0results/Q-50.0-L-500.0-k0.5.csv
2250.00.5650.0results/Q-50.0-L-650.0-k0.5.csv
2350.00.5800.0results/Q-50.0-L-800.0-k0.5.csv
2450.00.5900.0results/Q-50.0-L-900.0-k0.5.csv
2550.00.51000.0results/Q-50.0-L-1000.0-k0.5.csv
2650.01.0500.0results/Q-50.0-L-500.0-k1.0.csv
2750.01.0650.0results/Q-50.0-L-650.0-k1.0.csv
2850.01.0800.0results/Q-50.0-L-800.0-k1.0.csv
2950.01.0900.0results/Q-50.0-L-900.0-k1.0.csv
3050.01.01000.0results/Q-50.0-L-1000.0-k1.0.csv
&vellip&vellip&vellip&vellip&vellip

In [22]:
CSV.read(df_res[:csv_name][26])


┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[22]:1
└ @ Core In[22]:1
Out[22]:

100 rows × 5 columns

T_sdp_PaT_Kp_inj_Pap_out_Pa
Float64Float64Float64Float64Float64
10.0246218.0353.152.39507e72.37045e7
23.80242e6246218.0353.152.39507e72.37045e7
37.60483e6253240.0353.152.39577e72.37044e7
41.14072e7256048.0353.152.39604e72.37044e7
51.52097e7257550.0353.152.39619e72.37043e7
61.90121e7258571.0353.152.39628e72.37043e7
72.28145e7259365.0353.152.39636e72.37042e7
82.66169e7260025.0353.152.39642e72.37042e7
93.04193e7260594.0353.152.39647e72.37041e7
103.42217e7261095.0353.152.39651e72.3704e7
113.80242e7261543.0353.152.39655e72.3704e7
124.18266e7261949.0353.152.39659e72.37039e7
134.5629e7262320.0353.152.39662e72.37039e7
144.94314e7262662.0353.152.39665e72.37038e7
155.32338e7262979.0353.152.39667e72.37038e7
165.70362e7263275.0353.152.3967e72.37037e7
176.08386e7263553.0353.152.39672e72.37036e7
186.46411e7263815.0353.152.39674e72.37036e7
196.84435e7264063.0353.152.39676e72.37035e7
207.22459e7264299.0353.152.39678e72.37035e7
217.60483e7264524.0353.152.39679e72.37034e7
227.98507e7264738.0353.152.39681e72.37033e7
238.36531e7264944.0353.152.39682e72.37033e7
248.74555e7265142.0353.152.39684e72.37032e7
259.1258e7265333.0353.152.39685e72.37032e7
269.50604e7265517.0353.152.39686e72.37031e7
279.88628e7265695.0353.152.39687e72.3703e7
281.02665e8265868.0353.152.39688e72.3703e7
291.06468e8266035.0353.152.3969e72.37029e7
301.1027e8266198.0353.152.39691e72.37029e7
&vellip&vellip&vellip&vellip&vellip&vellip

In [23]:
df_res[:csv_name][17]


┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[23]:1
└ @ Core In[23]:1
Out[23]:
"results/Q-50.0-L-650.0-k0.2.csv"

The recovery factors and CO2 emission of a geothermal power plant

In this notebook, I first describe the process and present the details of the exergy analysis formulations. First, I write all the pparameters that are required for doing the calculations, here in Julia:


In [24]:
heat_loss = 0.1 # 10% exergy loss
poros = 0.2
# T0 = 20.0+273.15 # [K] reference temperature; defined above
T_in=40.0+273.15 # [K] injection temperature
# p0 = 1.014e5 # [Pa] reference pressure
eta_pump = 0.8; # pump mechanical efficiency
eta_driver = 0.8 # electrical driver efficiency
eta_pp = η_igcc # power plant efficiency
W = 500.0 # [m] width of the reservoir
H = 100.0 # [m] thickness of the reservoir
t_life = 30*365*24*3600.0 # [s] project life time (must be dynamic)
D_well = 0.17 # [m] well diameter
nwells = 2
t_tube = 0.015 # [m] tube thickness
t_cement = 0.050 # [m] cement thickness
ex_dril = 70000.0 # [kJ/m] drilling exergy; practical
depth = 2500.0 # [m]
rho_steel = 7850 # [kg/m^3]
rho_cement = 3150 # [kg/m^3]
ex_steel_th = 6738.0 # 376/0.0558 # [kJ/kg] exergy of Fe
ex_steel = 60000 #  [kJ/kg]
ex_cement = 12000 # 3000 #  [kJ/kg]
ex_cement_th = 2400 #135/0.056 # [kJ/kg] 
ex_methane = ex_gas # 800.0 # [kJ/mol]
cp_water = 4.1855 # [kJ/kg/K]
rho_water = 1000 # [kg/m^3]
mu_water = 1e-3 # [Pa.s]
ex_ccs = 5000 # [kJ/kg CO2]
A_pipe = pi/4*D_well^2 # m^2
c_methane = em_gas # 0.044/ex_methane # [kg CO2/kJ]


Out[24]:
5.4999999999999995e-5

Well energy

This section deals with the energy requirement for drilling and tubing the injection and production wells.


In [25]:
m_steel = nwells*pi/4*((D_well+2*t_tube)^2-D_well^2)*depth*rho_steel # [kg]
m_cement = nwells*pi/4*((D_well+2*t_tube+2*t_cement)^2-(D_well+2*t_tube)^2)*depth*rho_cement # [kg]
Ex_pipe_th=(m_steel*ex_steel_th+m_cement*ex_cement+nwells*depth*ex_dril) # [kJ] theoretical pipe exergy
Ex_pipe_pr=(m_steel*ex_steel+m_cement*ex_cement+nwells*depth*ex_dril) # [kJ] practical pipe exergy


Out[25]:
2.8302713334396893e10

Exergy-economical calculation

At which point in time the project starts giving back? Plot the net exergy return vs time, it also shows at which point the project become nonviable. Note: the project life time is the time at which the temperature of the produced water goes below 70 degC. Other criteria can be used for the project life time.

Approach 1: average exergy flow (the main approach)

This approach gives a single value of recovery factor for the project life time:


In [26]:
# Just look into one of the simulations
# T_s	dp_Pa	T_K	
fn = "results/Q-50.0-L-650.0-k0.2.csv" # a good one, high perm, low flow
Q        = 100/3600 # m^3/s
t1       = CSV.read(fn)
t        = float(t1[:T_s]) # [s] simulation time
Th       = float(t1[:T_K]) # [K] hot water temperature

# find the project life time
ind_life = findfirst(t1[:T_K].<=(70+273.15))[1]
t_life   = t[ind_life]
u_pipe   = Q/A_pipe; # [m/s] velocity of water in wells
Re       = rho_water*u_pipe*D_well/mu_water # Reynolds number
f        = fric_factor(Re)
dp_pipe  = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
dp_res   = float(t1[:dp_Pa][1:ind_life]) # [Pa] pressure drop in the reservoir
Ex_pump  = trapz(t[1:ind_life],Q*(dp_pipe.+dp_res)/1000)
Ex_th    = Ex_pump+Ex_pipe_th
Ex_prac  = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
heat_prod = Q*rho_water*cp_water*(Th[1:ind_life].-T_in) # [kJ] extracted heat
# Ex_prod = trapz(t,heat_prod.*(1.-T0./Th)) # [kJ] extracted exergy
Ex_prod   = Q*trapz(t[1:ind_life], water_density(Th[1:ind_life], p0).*(water_exergy(Th[1:ind_life], p0, T0, p0).-
      water_exergy(T_in, p0, T0, p0)))
Ex_prod   = Ex_prod/1000 # J to kJ
R_th      = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
R_pr      = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
carbon_em = Ex_prac*c_methane # [kg CO2]
Ex_ccs    = carbon_em*ex_ccs # [kJ] CCS exergy
R_ze      = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
c         = carbon_em/Ex_prod*1000 # [kg CO2/MJ]


┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[26]:6
└ @ Core In[26]:6
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[26]:7
└ @ Core In[26]:7
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[26]:8
└ @ Core In[26]:8
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[26]:16
└ @ Core In[26]:16
Out[26]:
0.024148606654147864

In [27]:
R_th, R_pr, R_ze


Out[27]:
(0.8836583538772836, 0.5609344244700388, 0.44019139119929956)

Approach 2: time dependent recovery factor

This approach gives a recovery factor that is time dependent and shows at which point the project become profitable.


In [28]:
# Just look into one of the simulations
fn = "results/Q-50.0-L-650.0-k0.2.csv" # a good one, high perm, low flow
Q        = 100/3600 # m^3/s
t1       = CSV.read(fn)
t        = float(t1[:T_s]) # [s] simulation time
Th       = float(t1[:T_K]) # [K] hot water temperature
p_out    = float(t1[:p_out_Pa])

capital_exergy_th = Ex_pipe_th
capital_exergy_pr = Ex_pipe_pr

# find the project life time
ind_life = length(t) # find(t1[:T_out].<70)[1]
t_life   = t[ind_life]
u_pipe   = Q/A_pipe; # [m/s] velocity of water in wells
Re       = rho_water*u_pipe*D_well/mu_water # Reynolds number
f        = fric_factor(Re)
dp_pipe  = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
dp_res   = float(t1[:dp_Pa][1:ind_life]) # [Pa] pressure drop in the reservoir
dp_dh    = water_density(Th[1:ind_life], p0)*9.81*depth-p_out[1:ind_life]
Ex_pump  = cum_trapz(t[1:ind_life],Q*((dp_pipe.+dp_res)+dp_dh)/1000)
Ex_th    = Ex_pump.+Ex_pipe_th
Ex_prac  = Ex_pump/eta_driver/eta_pp/eta_pump.+Ex_pipe_pr # [kJ] practical pumping exergy
heat_prod = Q*rho_water*cp_water*(Th[1:ind_life].-T_in) # [kJ] extracted heat
# Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
Ex_prod   = Q*cum_trapz(t[1:ind_life], water_density(Th[1:ind_life], p0).*(water_exergy(Th[1:ind_life], p0, T0, p0).-
      water_exergy(T_in, p0, T0, p0)))
Ex_prod   = Ex_prod/1000 # J to kJ
R_th      = (Ex_prod-Ex_th)./Ex_prod # theoretical recovery factor
R_pr      = (Ex_prod-Ex_prac)./Ex_prod # theoretical recovery factor
carbon_em = Ex_prac*c_methane # [kg CO2]
Ex_ccs    = carbon_em*ex_ccs # [kJ] CCS exergy
R_ze      = (Ex_prod-Ex_prac-Ex_ccs)./Ex_prod # zero-emission recovery factor
c         = carbon_em/Ex_prod*1000 # [kg CO2/MJ]


┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[28]:5
└ @ Core In[28]:5
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[28]:6
└ @ Core In[28]:6
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[28]:7
└ @ Core In[28]:7
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at In[28]:19
└ @ Core In[28]:19
Out[28]:
100×100 Array{Float64,2}:
 0.0  1.17123e-7  2.34246e-7  …  4.77247e-5  4.79237e-5  4.81165e-5
 0.0  1.2162e-7   2.4324e-7      4.95571e-5  4.97637e-5  4.9964e-5
 0.0  1.26152e-7  2.52303e-7     5.14037e-5  5.1618e-5   5.18257e-5
 0.0  1.30732e-7  2.61463e-7     5.32699e-5  5.3492e-5   5.37072e-5
 0.0  1.35332e-7  2.70664e-7     5.51444e-5  5.53744e-5  5.55972e-5
 0.0  1.39944e-7  2.79889e-7  …  5.70239e-5  5.72617e-5  5.74921e-5
 0.0  1.44566e-7  2.89132e-7     5.8907e-5   5.91526e-5  5.93906e-5
 0.0  1.49195e-7  2.98389e-7     6.07931e-5  6.10466e-5  6.12922e-5
 0.0  1.5383e-7   3.07659e-7     6.26818e-5  6.29432e-5  6.31965e-5
 0.0  1.5847e-7   3.16941e-7     6.45728e-5  6.48421e-5  6.5103e-5
 0.0  1.63116e-7  3.26233e-7  …  6.64659e-5  6.67431e-5  6.70116e-5
 0.0  1.67767e-7  3.35534e-7     6.83609e-5  6.8646e-5   6.89222e-5
 0.0  1.72422e-7  3.44844e-7     7.02577e-5  7.05506e-5  7.08345e-5
 ⋮                            ⋱                          
 0.0  2.79253e-6  5.58506e-6     0.00113789  0.00114263  0.00114723
 0.0  2.84602e-6  5.69205e-6     0.00115968  0.00116452  0.00116921
 0.0  2.89978e-6  5.79955e-6  …  0.00118159  0.00118651  0.00119129
 0.0  2.95377e-6  5.90755e-6     0.00120359  0.00120861  0.00121347
 0.0  3.008e-6    6.01601e-6     0.00122569  0.0012308   0.00123575
 0.0  3.06245e-6  6.1249e-6      0.00124787  0.00125308  0.00125812
 0.0  3.11711e-6  6.23422e-6     0.00127015  0.00127544  0.00128057
 0.0  3.17197e-6  6.34393e-6  …  0.0012925   0.00129789  0.00130311
 0.0  3.22701e-6  6.45402e-6     0.00131493  0.00132041  0.00132572
 0.0  3.28224e-6  6.56447e-6     0.00133743  0.00134301  0.00134841
 0.0  3.33763e-6  6.67526e-6     0.00136     0.00136567  0.00137117
 0.0  3.39318e-6  6.78637e-6     0.00138264  0.0013884   0.00139399

In [30]:
figure(figsize=(4,3))
plot(float(t[1:ind_life])/(365*24*3600),R_th, "--", label="Theoretical")
plot(float(t[1:ind_life])/(365*24*3600),R_pr, label="Practical")
plot(float(t[1:ind_life])/(365*24*3600),R_ze, "-.", label="Zero-emission")
plot([0, 30], [0, 0], "k--")
legend()
# grid()
xlabel("Production time [year]")
ylabel("Recovery factor")
#yscale("log")
axis([0,30, -1,1])
tight_layout()
savefig("figs/rec_fac_time.png")
savefig("figs/rec_fac_time.svg")

# cumsum(rand(10))


The point at which the recovery factor is zero shows the time at which all the initial exergy consumption is returned (or paid back) by the geothermal reservoir.

Recovery factor for all cases

What was missing from my previous calculation is the down hole pump for the extraction of water (note that the bottomhole pressure is less than the hydrostatic pressure). The pump must overcome the difference between the hydrostatic pressure and the bottomhole pressure, i.e., $$ W_{pump,dh} = Q_{water}(\rho_{water}gh_{well}-p_{out})$$ where $p_{out}$ is the production well downhole pressure. This needs to be included in the analysis.


In [36]:
df_res[:csv_name]


Out[36]:
150-element Array{Union{Missing, String},1}:
 "results/Q-50.0-L-500.0-k0.02.csv" 
 "results/Q-50.0-L-650.0-k0.02.csv" 
 "results/Q-50.0-L-800.0-k0.02.csv" 
 "results/Q-50.0-L-900.0-k0.02.csv" 
 "results/Q-50.0-L-1000.0-k0.02.csv"
 "results/Q-50.0-L-500.0-k0.05.csv" 
 "results/Q-50.0-L-650.0-k0.05.csv" 
 "results/Q-50.0-L-800.0-k0.05.csv" 
 "results/Q-50.0-L-900.0-k0.05.csv" 
 "results/Q-50.0-L-1000.0-k0.05.csv"
 "results/Q-50.0-L-500.0-k0.1.csv"  
 "results/Q-50.0-L-650.0-k0.1.csv"  
 "results/Q-50.0-L-800.0-k0.1.csv"  
 ⋮                                  
 "results/Q-250.0-L-900.0-k0.2.csv" 
 "results/Q-250.0-L-1000.0-k0.2.csv"
 "results/Q-250.0-L-500.0-k0.5.csv" 
 "results/Q-250.0-L-650.0-k0.5.csv" 
 "results/Q-250.0-L-800.0-k0.5.csv" 
 "results/Q-250.0-L-900.0-k0.5.csv" 
 "results/Q-250.0-L-1000.0-k0.5.csv"
 "results/Q-250.0-L-500.0-k1.0.csv" 
 "results/Q-250.0-L-650.0-k1.0.csv" 
 "results/Q-250.0-L-800.0-k1.0.csv" 
 "results/Q-250.0-L-900.0-k1.0.csv" 
 "results/Q-250.0-L-1000.0-k1.0.csv"

In [41]:
# create empty data frames to save the analyzed files
df_geothermal = DataFrame(q_m3_s=[], k_m2=[], L_m=[], t_life_s=[], R_th=[], R_pr=[], 
    R_ze=[], c_CO2=[], COP=[], c_CO2_heat=[], heat_per_m3=[])

i = 0
for fn in df_res[:csv_name]
    i=i+1
    Q    = df_res[:q_m3_h][i]/3600  # m3/s
    perm = df_res[:k_D][i]*1e-12    # m2
    L    = df_res[:L_m][i]          # m
    println(fn)
    t1 = CSV.read(fn)
    # deleterows!(t1,find(isna(t1[:,:Time_s_])))
    ind_life = findfirst(t1[:T_K].<=(70+273.15))[1]
    t=float(t1[:T_s][1:ind_life])    # [s] simulation time
    t_life   = t[ind_life]
    Th = float(t1[:T_K][1:ind_life]) # [K] hot water temperature
    p_out    = float(t1[:p_out_Pa][1:ind_life])
    dp_res = float(t1[:dp_Pa][1:ind_life]) # [Pa] pressure drop in the reservoir
    u_pipe = Q/A_pipe                # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_dh    = water_density(Th[1:ind_life], p0)*9.81*depth-p_out # [Pa]
    Ex_pump = trapz(t,Q*(dp_pipe.+dp_res.+dp_dh)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    # heat_prod = Q*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    # Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    Ex_prod = Q*trapz(t, water_density(Th, p0).*(water_exergy(Th, p0, T0, p0).-
          water_exergy(T_in, p0, T0, p0)))
    heat_prod = Q*trapz(t, water_density(Th, p0).*(water_heat(Th, p0, T0, p0).-
          water_heat(T_in, p0, T0, p0)))
    heat_prod = heat_prod/1000 # J to kJ
    heat_waste = heat_prod*heat_loss
    Ex_prod = Ex_prod/1000 # J to kJ
    Ex_waste = Ex_prod*heat_loss
    R_th = (Ex_prod-Ex_waste-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr = (Ex_prod-Ex_waste-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze = (Ex_prod-Ex_waste-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c = carbon_em/(Ex_prod-Ex_waste)*1000 # [kg CO2/MJ]
    c_heat = carbon_em/(heat_prod-heat_waste)*1000 # [kg CO2/MJ]
    cop = (heat_prod-heat_waste)/Ex_prac # kJ/kJ
    push!(df_geothermal, [Q, perm, L, t_life, R_th, R_pr, R_ze, c, cop, c_heat, (heat_prod-heat_loss)/(Q*t_life)])
end


results/Q-50.0-L-500.0-k0.02.csv
results/Q-50.0-L-650.0-k0.02.csv
results/Q-50.0-L-800.0-k0.02.csv
results/Q-50.0-L-900.0-k0.02.csv
results/Q-50.0-L-1000.0-k0.02.csv
results/Q-50.0-L-500.0-k0.05.csv
results/Q-50.0-L-650.0-k0.05.csv
results/Q-50.0-L-800.0-k0.05.csv
results/Q-50.0-L-900.0-k0.05.csv
results/Q-50.0-L-1000.0-k0.05.csv
results/Q-50.0-L-500.0-k0.1.csv
results/Q-50.0-L-650.0-k0.1.csv
results/Q-50.0-L-800.0-k0.1.csv
results/Q-50.0-L-900.0-k0.1.csv
results/Q-50.0-L-1000.0-k0.1.csv
results/Q-50.0-L-500.0-k0.2.csv
results/Q-50.0-L-650.0-k0.2.csv
results/Q-50.0-L-800.0-k0.2.csv
results/Q-50.0-L-900.0-k0.2.csv
results/Q-50.0-L-1000.0-k0.2.csv
results/Q-50.0-L-500.0-k0.5.csv
results/Q-50.0-L-650.0-k0.5.csv
results/Q-50.0-L-800.0-k0.5.csv
results/Q-50.0-L-900.0-k0.5.csv
results/Q-50.0-L-1000.0-k0.5.csv
results/Q-50.0-L-500.0-k1.0.csv
results/Q-50.0-L-650.0-k1.0.csv
results/Q-50.0-L-800.0-k1.0.csv
results/Q-50.0-L-900.0-k1.0.csv
results/Q-50.0-L-1000.0-k1.0.csv
results/Q-100.0-L-500.0-k0.02.csv
results/Q-100.0-L-650.0-k0.02.csv
results/Q-100.0-L-800.0-k0.02.csv
results/Q-100.0-L-900.0-k0.02.csv
results/Q-100.0-L-1000.0-k0.02.csv
results/Q-100.0-L-500.0-k0.05.csv
results/Q-100.0-L-650.0-k0.05.csv
results/Q-100.0-L-800.0-k0.05.csv
results/Q-100.0-L-900.0-k0.05.csv
results/Q-100.0-L-1000.0-k0.05.csv
results/Q-100.0-L-500.0-k0.1.csv
results/Q-100.0-L-650.0-k0.1.csv
results/Q-100.0-L-800.0-k0.1.csv
results/Q-100.0-L-900.0-k0.1.csv
results/Q-100.0-L-1000.0-k0.1.csv
results/Q-100.0-L-500.0-k0.2.csv
results/Q-100.0-L-650.0-k0.2.csv
results/Q-100.0-L-800.0-k0.2.csv
results/Q-100.0-L-900.0-k0.2.csv
results/Q-100.0-L-1000.0-k0.2.csv
results/Q-100.0-L-500.0-k0.5.csv
results/Q-100.0-L-650.0-k0.5.csv
results/Q-100.0-L-800.0-k0.5.csv
results/Q-100.0-L-900.0-k0.5.csv
results/Q-100.0-L-1000.0-k0.5.csv
results/Q-100.0-L-500.0-k1.0.csv
results/Q-100.0-L-650.0-k1.0.csv
results/Q-100.0-L-800.0-k1.0.csv
results/Q-100.0-L-900.0-k1.0.csv
results/Q-100.0-L-1000.0-k1.0.csv
results/Q-150.0-L-500.0-k0.02.csv
results/Q-150.0-L-650.0-k0.02.csv
results/Q-150.0-L-800.0-k0.02.csv
results/Q-150.0-L-900.0-k0.02.csv
results/Q-150.0-L-1000.0-k0.02.csv
results/Q-150.0-L-500.0-k0.05.csv
results/Q-150.0-L-650.0-k0.05.csv
results/Q-150.0-L-800.0-k0.05.csv
results/Q-150.0-L-900.0-k0.05.csv
results/Q-150.0-L-1000.0-k0.05.csv
results/Q-150.0-L-500.0-k0.1.csv
results/Q-150.0-L-650.0-k0.1.csv
results/Q-150.0-L-800.0-k0.1.csv
results/Q-150.0-L-900.0-k0.1.csv
results/Q-150.0-L-1000.0-k0.1.csv
results/Q-150.0-L-500.0-k0.2.csv
results/Q-150.0-L-650.0-k0.2.csv
results/Q-150.0-L-800.0-k0.2.csv
results/Q-150.0-L-900.0-k0.2.csv
results/Q-150.0-L-1000.0-k0.2.csv
results/Q-150.0-L-500.0-k0.5.csv
results/Q-150.0-L-650.0-k0.5.csv
results/Q-150.0-L-800.0-k0.5.csv
results/Q-150.0-L-900.0-k0.5.csv
results/Q-150.0-L-1000.0-k0.5.csv
results/Q-150.0-L-500.0-k1.0.csv
results/Q-150.0-L-650.0-k1.0.csv
results/Q-150.0-L-800.0-k1.0.csv
results/Q-150.0-L-900.0-k1.0.csv
results/Q-150.0-L-1000.0-k1.0.csv
results/Q-200.0-L-500.0-k0.02.csv
results/Q-200.0-L-650.0-k0.02.csv
results/Q-200.0-L-800.0-k0.02.csv
results/Q-200.0-L-900.0-k0.02.csv
results/Q-200.0-L-1000.0-k0.02.csv
results/Q-200.0-L-500.0-k0.05.csv
results/Q-200.0-L-650.0-k0.05.csv
results/Q-200.0-L-800.0-k0.05.csv
results/Q-200.0-L-900.0-k0.05.csv
results/Q-200.0-L-1000.0-k0.05.csv
results/Q-200.0-L-500.0-k0.1.csv
results/Q-200.0-L-650.0-k0.1.csv
results/Q-200.0-L-800.0-k0.1.csv
results/Q-200.0-L-900.0-k0.1.csv
results/Q-200.0-L-1000.0-k0.1.csv
results/Q-200.0-L-500.0-k0.2.csv
results/Q-200.0-L-650.0-k0.2.csv
results/Q-200.0-L-800.0-k0.2.csv
results/Q-200.0-L-900.0-k0.2.csv
results/Q-200.0-L-1000.0-k0.2.csv
results/Q-200.0-L-500.0-k0.5.csv
results/Q-200.0-L-650.0-k0.5.csv
results/Q-200.0-L-800.0-k0.5.csv
results/Q-200.0-L-900.0-k0.5.csv
results/Q-200.0-L-1000.0-k0.5.csv
results/Q-200.0-L-500.0-k1.0.csv
results/Q-200.0-L-650.0-k1.0.csv
results/Q-200.0-L-800.0-k1.0.csv
results/Q-200.0-L-900.0-k1.0.csv
results/Q-200.0-L-1000.0-k1.0.csv
results/Q-250.0-L-500.0-k0.02.csv
results/Q-250.0-L-650.0-k0.02.csv
results/Q-250.0-L-800.0-k0.02.csv
results/Q-250.0-L-900.0-k0.02.csv
results/Q-250.0-L-1000.0-k0.02.csv
results/Q-250.0-L-500.0-k0.05.csv
results/Q-250.0-L-650.0-k0.05.csv
results/Q-250.0-L-800.0-k0.05.csv
results/Q-250.0-L-900.0-k0.05.csv
results/Q-250.0-L-1000.0-k0.05.csv
results/Q-250.0-L-500.0-k0.1.csv
results/Q-250.0-L-650.0-k0.1.csv
results/Q-250.0-L-800.0-k0.1.csv
results/Q-250.0-L-900.0-k0.1.csv
results/Q-250.0-L-1000.0-k0.1.csv
results/Q-250.0-L-500.0-k0.2.csv
results/Q-250.0-L-650.0-k0.2.csv
results/Q-250.0-L-800.0-k0.2.csv
results/Q-250.0-L-900.0-k0.2.csv
results/Q-250.0-L-1000.0-k0.2.csv
results/Q-250.0-L-500.0-k0.5.csv
results/Q-250.0-L-650.0-k0.5.csv
results/Q-250.0-L-800.0-k0.5.csv
results/Q-250.0-L-900.0-k0.5.csv
results/Q-250.0-L-1000.0-k0.5.csv
results/Q-250.0-L-500.0-k1.0.csv
results/Q-250.0-L-650.0-k1.0.csv
results/Q-250.0-L-800.0-k1.0.csv
results/Q-250.0-L-900.0-k1.0.csv
results/Q-250.0-L-1000.0-k1.0.csv

In [46]:
df_geothermal


Out[46]:

150 rows × 11 columns

q_m3_sk_m2L_mt_life_sR_thR_prR_zec_CO2COPc_CO2_heatheat_per_m3
AnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAny
10.01388892.0e-14500.01.05763e9-0.310919-3.78832-5.077610.2865081.645990.03341451.5436e5
20.01388892.0e-14650.01.4292e9-0.417142-4.2143-5.620730.312541.506480.03650891.54967e5
30.01388892.0e-14800.01.77659e9-0.523523-4.63601-6.158410.3383121.389510.03958241.55609e5
40.01388892.0e-14900.02.02833e9-0.60341-4.95111-6.560160.3575681.314880.0418291.55504e5
50.01388892.0e-141000.02.2559e9-0.676724-5.23971-6.928130.3752051.25230.04391911.55751e5
60.01388895.0e-14500.01.05763e90.388476-1.05631-1.594290.1195523.944650.01394291.5436e5
70.01388895.0e-14650.01.4292e90.352124-1.20935-1.789430.1289053.652590.01505781.54967e5
80.01388895.0e-14800.01.77659e90.313042-1.36818-1.991930.1386113.391410.01621751.55609e5
90.01388895.0e-14900.02.02833e90.282732-1.48961-2.146760.1460323.219550.01708311.55504e5
100.01388895.0e-141000.02.2559e90.254659-1.6015-2.289410.1528693.073670.01789391.55751e5
110.01388891.0e-13500.01.05763e90.621608-0.145634-0.4331840.06389997.380150.007452431.5436e5
120.01388891.0e-13650.01.4292e90.608546-0.207706-0.5123250.06769316.955450.007907461.54967e5
130.01388891.0e-13800.01.77659e90.591896-0.278904-0.6031020.07204416.524980.008429141.55609e5
140.01388891.0e-13900.02.02833e90.578113-0.335783-0.6756240.07552016.225590.00883451.55504e5
150.01388891.0e-131000.02.2559e90.56512-0.388756-0.7431640.07875735.966040.009218851.55751e5
160.01388892.0e-13500.01.05763e90.7381740.3097010.1473690.036073813.07290.004207171.5436e5
170.01388892.0e-13650.01.4292e90.7367560.2931180.1262250.037087212.69540.004332291.54967e5
180.01388892.0e-13800.01.77659e90.7313240.2657350.09131210.038760612.12790.004534981.55609e5
190.01388892.0e-13900.02.02833e90.7258030.2411320.05994340.040264111.67680.004710181.55504e5
200.01388892.0e-131000.02.2559e90.7203510.2176130.02995690.041701411.26750.004881311.55751e5
210.01388895.0e-13500.01.05763e90.8081130.5829020.4957010.019378224.33610.002260011.5436e5
220.01388895.0e-13650.01.4292e90.8136830.5936120.5093560.018723725.14660.002187181.54967e5
230.01388895.0e-13800.01.77659e90.814980.5925180.5079610.018790625.01720.002198491.55609e5
240.01388895.0e-13900.02.02833e90.8144180.5872810.5012840.019110624.60190.00223561.55504e5
250.01388895.0e-131000.02.2559e90.8134890.5814350.493830.019467924.13560.002278791.55751e5
260.01388891.0e-12500.01.05763e90.8314270.6739690.6118110.01381334.14110.001610961.5436e5
270.01388891.0e-12650.01.4292e90.8393250.6937770.6370660.012602537.36050.001472141.54967e5
280.01388891.0e-12800.01.77659e90.8428660.7014460.6468430.012133938.74170.001419661.55609e5
290.01388891.0e-12900.02.02833e90.8439560.7026650.6483970.012059438.98680.001410731.55504e5
300.01388891.0e-121000.02.2559e90.8445350.7027090.6484540.012056738.97170.001411281.55751e5
&vellip&vellip&vellip&vellip&vellip&vellip&vellip&vellip&vellip&vellip&vellip&vellip

In [47]:
CSV.write("geothermal_final_results.csv", df_geothermal)


Out[47]:
"geothermal_final_results.csv"

In [32]:
(df_geothermal)


Out[32]:

0 rows × 11 columns

q_m3_sk_m2L_mt_life_sR_thR_prR_zec_CO2COPc_CO2_heatheat_per_m3
AnyAnyAnyAnyAnyAnyAnyAnyAnyAnyAny

In [44]:
plot(df_geothermal[:L_m], df_geothermal[:t_life_s]/365/24/3600, "o")


Out[44]:
1-element Array{PyCall.PyObject,1}:
 PyObject <matplotlib.lines.Line2D object at 0x7f1c3ba69908>

Effect of permeability


In [42]:
f_name = ["Geothermal_Q150_2Q150-20mD-L800.csv" 
"Geothermal_Q150_2Q150-50mD-L800.csv"
"Geothermal_Q150_2Q150-100mD-L800.csv"
"Geothermal_Q150_2Q150-500mD-L800.csv"
"Geothermal_Q150_2Q150-1D-L800.csv"]
i=0
R_th=zeros(5)
R_pr=zeros(5)
R_ze=zeros(5)
c=zeros(5)
for fn in f_name
    i=i+1
    Q=100/3600 # m^3/s
    t1 = CSV.read(fn)
    t=float(t1[:Time_s_]) # [s] simulation time
    Th = float(t1[:T_out])+273.15 # [K] hot water temperature
    u_pipe = Q/A_pipe; # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_res = float(t1[:Dp_Mpa_])*1e6 # [Pa] pressure drop in the reservoir
    Ex_pump = trapz(t,Q*(dp_pipe+dp_res)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    heat_prod = Q*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    # Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    Ex_prod = Q*rho_water*trapz(t, water_exergy(Th, p0, T0, p0)-
          water_exergy(T_in, p0, T0, p0))
    Ex_prod = Ex_prod/1000 # J to kJ
    R_th[i] = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr[i] = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze[i] = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c[i] = carbon_em/Ex_prod*1000 # [kg CO2/MJ]
end


ArgumentError: "Geothermal_Q150_2Q150-20mD-L800.csv" is not a valid file

Stacktrace:
 [1] #File#1(::Int64, ::Bool, ::Int64, ::Nothing, ::Int64, ::Nothing, ::Bool, ::Nothing, ::Bool, ::Array{String,1}, ::String, ::String, ::Bool, ::Char, ::Nothing, ::Nothing, ::Char, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Nothing, ::Dict{Type,Type}, ::Symbol, ::Bool, ::Bool, ::Bool, ::Bool, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Type, ::String) at /home/ali/.julia/packages/CSV/eWuJV/src/CSV.jl:135
 [2] Type at /home/ali/.julia/packages/CSV/eWuJV/src/CSV.jl:135 [inlined]
 [3] #read#105(::Bool, ::Dict{Int64,Function}, ::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::Function, ::String, ::Type) at /home/ali/.julia/packages/CSV/eWuJV/src/CSV.jl:310
 [4] read at /home/ali/.julia/packages/CSV/eWuJV/src/CSV.jl:300 [inlined] (repeats 2 times)
 [5] top-level scope at ./In[42]:14

In [43]:
figure(figsize=(5,3))
perm
plot(perm_range, R_th, "-o", perm_range, R_pr, "--^k", perm_range, R_ze, "-vr")
xlabel("Permeability [mD]", fontsize=12)
ylabel("Recovery factor [-]", fontsize=12)
legend(["Theoretical", "Practical", "Zero-emission"], loc=4, fontsize=12)
plot([0, 1000], [0, 0], ":k")
# text(800, 0.25, "(a)", fontsize=14)
axis([0, 1000, -1.0, 1.0])
savefig("perm_effect.png")


UndefVarError: perm_range not defined

Stacktrace:
 [1] top-level scope at In[43]:2

In [49]:
figure(figsize=(5,3))
plot(perm_range, c, "-o")
xlabel("Permeability [mD]", fontsize=12)
ylabel("CO2 emission [kg CO2/MJ]", fontsize=12)
#legend(["Theoretical", "Practical", "Zero-emission"], loc=4, fontsize=12)
axis([0, 1000, 0.0, 0.3])
savefig("perm_effect_CO2_emission.svg")


Effect of permeability: higher flow rate


In [31]:
f_name = ["Geothermal_Q250_Q250-20mD-L800.csv"
    "Geothermal_Q250_Q250-50mD-L800.csv"
    "Geothermal_Q250_Q250-100mD-L800.csv"
    "Geothermal_Q250_Q250-500mD-L800.csv" 
    "Geothermal_Q250_Q250-1D-L800.csv"]
i=0
R_th=zeros(5)
R_pr=zeros(5)
R_ze=zeros(5)
c=zeros(5)
for fn in f_name
    i=i+1
    Q=250/3600 # m^3/s
    t1 = CSV.read(fn)
    t=float(t1[:Time_s_]) # [s] simulation time
    Th = float(t1[:T_out])+273.15 # [K] hot water temperature
    u_pipe = Q/A_pipe; # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_res = float(t1[:Dp_Mpa_])*1e6 # [Pa] pressure drop in the reservoir
    Ex_pump = trapz(t,Q*(dp_pipe+dp_res)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    heat_prod = Q*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    Ex_prod = Q*rho_water*trapz(t, water_exergy(Th, p0, T0, p0)-
          water_exergy(T_in, p0, T0, p0))
    Ex_prod = Ex_prod/1000 # J to kJ
    # Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    R_th[i] = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr[i] = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze[i] = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c[i] = carbon_em/Ex_prod*1000 # [kg CO2/MJ]
end

In [32]:
figure(figsize=(5,3))
plot(perm_range, R_th, "-o", perm_range, R_pr, "--^k", perm_range, R_ze, "-vr")
xlabel("Permeability [mD]", fontsize=12)
ylabel("Recovery factor [-]", fontsize=12)
legend(["Theoretical", "Practical", "Zero-emission"], loc=4, fontsize=12)
plot([0, 1000], [0, 0], ":k")
text(800, 0.25, "(b)", fontsize=14)
axis([0, 1000, -1.0, 1.0])
savefig("perm_effect_high_flow.svg")



In [33]:
figure(figsize=(5,3))
plot(perm_range, c, "-o")
xlabel("Permeability [mD]", fontsize=14)
ylabel("CO2 emission [kg CO2/MJ]", fontsize=14)
#legend(["Theoretical", "Practical", "Zero-emission"], loc=4, fontsize=12)
savefig("perm_effect_CO2_emission_high_flow.svg")


Effect of flow rate and well spacing


In [136]:
f_name = ["Geothermal_Q100_Q100-100mD-L470.csv", "Geothermal_Q150_Q150-100mD-L600.csv",
    "Geothermal_Q200_Q200-100mD-L700.csv", "Geothermal_Q250_Q250-100mD-L800.csv"]
i=0
R_th=zeros(4)
R_pr=zeros(4)
R_ze=zeros(4)
c=zeros(4)
for fn in f_name
    i=i+1
    Q=Q_range[i] # m^3/s
    t1 = CSV.read(fn)
    t=float(t1[:Time_s_]) # [s] simulation time
    Th = float(t1[:T_out])+273.15 # [K] hot water temperature
    u_pipe = Q/A_pipe; # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_res = float(t1[:Dp_Mpa_])*1e6 # [Pa] pressure drop in the reservoir
    Ex_pump = trapz(t,Q*(dp_pipe+dp_res)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    heat_prod = Q*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    Ex_prod = Q*rho_water*trapz(t, water_exergy(Th, p0, T0, p0)-
          water_exergy(T_in, p0, T0, p0))
    Ex_prod = Ex_prod/1000 # J to kJ
    #Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    R_th[i] = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr[i] = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze[i] = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c[i] = carbon_em/Ex_prod*1000 # [kg CO2/MJ]
end

In [137]:
figure(figsize=(5,3))
plot(L_range, Q_range*3600, "-o")
xlabel("Well spacing [m]", fontsize=12)
ylabel("Flow rate "*L"[m^3/h]", fontsize=12)
savefig("well_space_flow_rate.svg")



In [138]:
figure(figsize=(5,3))
plot(L_range, R_th, "-o", L_range, R_pr, "--^k", L_range, R_ze, "-vr")
xlabel("Well spacing [m]", fontsize=12)
ylabel("Recovery factor [-]", fontsize=12)
legend(["Theoretical", "Practical", "Zero-emission"], loc=3, fontsize=12)
savefig("well_space.svg")


flow rate: 500 mD


In [139]:
f_name = ["Geothermal_Q100_Q100-500mD-L470.csv", "Geothermal_Q150_Q150-500mD-L600.csv",
    "Geothermal_Q200_Q200-500mD-L700.csv", "Geothermal_Q250_Q250-500mD-L800.csv"]
i=0
R_th=zeros(4)
R_pr=zeros(4)
R_ze=zeros(4)
c=zeros(4)
for fn in f_name
    i=i+1
    Q=Q_range[i] # m^3/s
    t1 = CSV.read(fn)
    t=float(t1[:Time_s_]) # [s] simulation time
    Th = float(t1[:T_out])+273.15 # [K] hot water temperature
    u_pipe = Q/A_pipe; # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_res = float(t1[:Dp_Mpa_])*1e6 # [Pa] pressure drop in the reservoir
    Ex_pump = trapz(t,Q*(dp_pipe+dp_res)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    heat_prod = Q*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    # Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    Ex_prod = Q*rho_water*trapz(t, water_exergy(Th, p0, T0, p0)-
          water_exergy(T_in, p0, T0, p0))
    Ex_prod = Ex_prod/1000 # J to kJ
    R_th[i] = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr[i] = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze[i] = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c[i] = carbon_em/Ex_prod*1000 # [kg CO2/MJ]
end

In [140]:
figure(figsize=(5,3))
plot(L_range, R_th, "-o", L_range, R_pr, "--^k", L_range, R_ze, "-vr")
xlabel("Well spacing [m]", fontsize=14)
ylabel("Recovery factor [-]", fontsize=14)
legend(["Theoretical", "Practical", "Zero-emission"], loc=3, fontsize=12)
savefig("well_space_500.svg")


flow rate: 50 mD


In [141]:
f_name = ["Geothermal_Q100_Q100-50mD-L470.csv", "Geothermal_Q150_Q150-50mD-L600.csv",
    "Geothermal_Q200_Q200-50mD-L700.csv", "Geothermal_Q250_Q250-50mD-L800.csv"]
i=0
R_th=zeros(4)
R_pr=zeros(4)
R_ze=zeros(4)
c=zeros(4)
for fn in f_name
    i=i+1
    Q=Q_range[i] # m^3/s
    t1 = CSV.read(fn)
    t=float(t1[:Time_s_]) # [s] simulation time
    Th = float(t1[:T_out])+273.15 # [K] hot water temperature
    u_pipe = Q/A_pipe; # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_res = float(t1[:Dp_Mpa_])*1e6 # [Pa] pressure drop in the reservoir
    Ex_pump = trapz(t,Q*(dp_pipe+dp_res)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    heat_prod = Q*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    # Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    Ex_prod = Q*rho_water*trapz(t, water_exergy(Th, p0, T0, p0)-
          water_exergy(T_in, p0, T0, p0))
    Ex_prod = Ex_prod/1000 # J to kJ
    R_th[i] = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr[i] = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze[i] = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c[i] = carbon_em/Ex_prod*1000 # [kg CO2/MJ]
end

In [142]:
figure(figsize=(5,3))
plot(L_range, R_th, "-o", L_range, R_pr, "--^k", L_range, R_ze, "-vr")
xlabel("Well spacing [m]", fontsize=14)
ylabel("Recovery factor [-]", fontsize=14)
legend(["Theoretical", "Practical", "Zero-emission"], loc=3, fontsize=12)
savefig("well_space_50.svg")


NOT YET THROWN AWAY

m
i=0;
%for perm = 3e-14:0.1e-14:10e-14
for Q = 100/3600:100/3600:1000/3600
    i=i+1;
% calculation starts here ----------------------------------------------->
    m_steel = nwells*pi()/4*((D_well+2*t_tube)^2-D_well^2)*depth*rho_steel; % [kg]
    m_cement = nwells*pi()/4* ...
        ((D_well+2*t_tube+2*t_cement)^2-(D_well+2*t_tube)^2)*depth*rho_cement; % [kg]
    A_res = W*H; % [m^2] reservoir cross section
    A_pipe = pi()/4*D_well^2;
    u_res = Q/A_res; % [m/s] Darcy velocity
    u_pipe = Q/A_pipe; % [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water; % Reynolds number

    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2; % [Pa] pressure drop in pipes
    dp_res = mu_water/perm*u_res*L; % [Pa] pressure drop in the reservoir
    Ex_pump = Q*(dp_pipe+dp_res)/1000;
    Ex_pipe_th=(m_steel*ex_steel_th+m_cement*ex_cement+ ...
        nwells*depth*ex_dril)/t_life; % [kJ] theoretical pipe exergy
    Ex_th = Ex_pump+Ex_pipe_th;
    Ex_pipe_pr=(m_steel*ex_steel+m_cement*ex_cement+ ...
        nwells*depth*ex_dril)/t_life; % [kJ] practical pipe exergy
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr; % [kJ] practical pumping exergy
    heat_prod = Q*rho_water*cp_water*(Th-T0) # [kJ] extracted heat
    Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    R_th(i) = (Ex_prod-Ex_th)/Ex_prod; % theoretical recovery factor
    R_pr(i) = (Ex_prod-Ex_prac)/Ex_prod; % theoretical recovery factor
    carbon_em = Ex_prac*c_methane; % [kg CO2]
    Ex_ccs = carbon_em*ex_ccs; % [kJ] CCS exergy
    R_ze(i) = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod; % zero-emission recovery factor
    c(i) = carbon_em/Ex_prod*1000; % [kg CO2/MJ]
% end of calculation ----------------------------------------------->

end

 %plot(perm, R_th, 'o', perm, R_pr, '^');
 Q = 100/3600:100/3600:1000/3600;
 plot(Q, R_th, Q, R_th, 'o', ...
     Q, R_pr, Q, R_pr, '^', ...
     Q, R_ze, Q, R_ze, 's');
 xlabel('flow rate (m^3/s)');
perm = 3e-14:0.1e-14:10e-14;
%plot(perm, R_th, perm, R_th, 'o', ...
%    perm, R_pr, perm, R_pr, '^', ...
%    perm, R_ze, perm, R_ze, 's');
%xlabel('Permeability [m^2]');
ylabel('Recovery factors');
legend('Theoretical', '','Practical', '', 'Zero-emission','');

In [ ]:


In [87]:
# file_list = readdir()
# f_list = Array{Any}(20)
# j=0
# for i in eachindex(file_list)
#     if file_list[i][end-2:end]=="csv"
#         j+=1
#         f_list[j] = file_list[i]
#     end
# end
f_list = 
["Geothermal_Q100_Q100-100mD-L470.csv" 
 "Geothermal_Q100_Q100-1D-L470.csv"    
 "Geothermal_Q100_Q100-20mD-L470.csv"  
 "Geothermal_Q100_Q100-500mD-L470.csv" 
 "Geothermal_Q100_Q100-50mD-L470.csv"  
 "Geothermal_Q150_2Q150-100mD-L800.csv"
 "Geothermal_Q150_2Q150-1D-L800.csv"   
 "Geothermal_Q150_2Q150-20mD-L800.csv" 
 "Geothermal_Q150_2Q150-500mD-L800.csv"
 "Geothermal_Q150_2Q150-50mD-L800.csv" 
 "Geothermal_Q150_Q150-100mD-L600.csv" 
 "Geothermal_Q150_Q150-1D-L600.csv"    
 "Geothermal_Q150_Q150-20mD-L600.csv"  
 "Geothermal_Q150_Q150-500mD-L600.csv" 
 "Geothermal_Q150_Q150-50mD-L600.csv"  
 "Geothermal_Q200_Q200-100mD-L700.csv" 
 "Geothermal_Q200_Q200-1D-L700.csv"    
 "Geothermal_Q200_Q200-20mD-L700.csv"  
 "Geothermal_Q200_Q200-500mD-L700.csv" 
 "Geothermal_Q200_Q200-50mD-L700.csv"  
 "Geothermal_Q250_Q250-100mD-L800.csv" 
 "Geothermal_Q250_Q250-1D-L800.csv"    
 "Geothermal_Q250_Q250-20mD-L800.csv"  
 "Geothermal_Q250_Q250-500mD-L800.csv" 
 "Geothermal_Q250_Q250-50mD-L800.csv"]
# flow[m3/h] perm[mD] L[m]
sim_params = 
[100 100 470
100 1000 470
100 20   470
100 500  470
100 50   470
150 100  600
150 1000 600
150 20   600
150 500  600
150 50   600
150 100  800
150 1000 800
150 20   800
150 500  800
150 50   800
200 100  700
200 1000 700
200 20   700
200 500  700
200 50   700
250 100  800
250 1000 800
250 20   800
250 500  800
250 50   800]


Out[87]:
25×3 Array{Int64,2}:
 100   100  470
 100  1000  470
 100    20  470
 100   500  470
 100    50  470
 150   100  600
 150  1000  600
 150    20  600
 150   500  600
 150    50  600
 150   100  800
 150  1000  800
 150    20  800
 150   500  800
 150    50  800
 200   100  700
 200  1000  700
 200    20  700
 200   500  700
 200    50  700
 250   100  800
 250  1000  800
 250    20  800
 250   500  800
 250    50  800

In [26]:
find(sim_params[:,2].==100)
length(f_list)


Out[26]:
25

In [92]:
i    = 0
n_data = length(f_list)
R_th = zeros(n_data)
R_pr = zeros(n_data)
R_ze = zeros(n_data)
Q    = sim_params[:, 1]/3600       # m3/s
perm = sim_params[:, 2]/1000*1e-12 # m2
L    = sim_params[:, 3]            # m
c    = zeros(n_data)
for fn in f_list
    i=i+1
    println(fn)
    t1 = CSV.read(fn)
    deleterows!(t1,find(isna(t1[:,:Time_s_])))
    t=float(t1[:Time_s_]) # [s] simulation time
    Th = float(t1[:T_out])+273.15 # [K] hot water temperature
    u_pipe = Q[i]/A_pipe; # [m/s] velocity of water in wells
    Re = rho_water*u_pipe*D_well/mu_water # Reynolds number
    f=fric_factor(Re)
    dp_pipe = nwells*rho_water*f*depth/D_well*u_pipe^2/2 # [Pa] pressure drop in pipes
    dp_res = float(t1[:Dp_Mpa_])*1e6 # [Pa] pressure drop in the reservoir
    Ex_pump = trapz(t,Q[i]*(dp_pipe+dp_res)/1000)
    Ex_th = Ex_pump+Ex_pipe_th
    Ex_prac = Ex_pump/eta_driver/eta_pp/eta_pump+Ex_pipe_pr # [kJ] practical pumping exergy
    heat_prod = Q[i]*rho_water*cp_water*(Th-T_in) # [kJ] extracted heat
    # Ex_prod = trapz(t,heat_prod.*(1-T0./Th)) # [kJ] extracted exergy
    Ex_prod = Q[i]*rho_water*trapz(t, water_exergy(Th, p0, T0, p0)-
          water_exergy(T_in, p0, T0, p0))
    Ex_prod = Ex_prod/1000 # J to kJ
    R_th[i] = (Ex_prod-Ex_th)/Ex_prod # theoretical recovery factor
    R_pr[i] = (Ex_prod-Ex_prac)/Ex_prod # theoretical recovery factor
    carbon_em = Ex_prac*c_methane # [kg CO2]
    Ex_ccs = carbon_em*ex_ccs # [kJ] CCS exergy
    R_ze[i] = (Ex_prod-Ex_prac-Ex_ccs)/Ex_prod # zero-emission recovery factor
    c[i] = carbon_em/Ex_prod*1000 # [kg CO2/MJ]
end


Geothermal_Q100_Q100-100mD-L470.csv
Geothermal_Q100_Q100-1D-L470.csv
Geothermal_Q100_Q100-20mD-L470.csv
Geothermal_Q100_Q100-500mD-L470.csv
Geothermal_Q100_Q100-50mD-L470.csv
Geothermal_Q150_2Q150-100mD-L800.csv
Geothermal_Q150_2Q150-1D-L800.csv
Geothermal_Q150_2Q150-20mD-L800.csv
Geothermal_Q150_2Q150-500mD-L800.csv
Geothermal_Q150_2Q150-50mD-L800.csv
Geothermal_Q150_Q150-100mD-L600.csv
Geothermal_Q150_Q150-1D-L600.csv
Geothermal_Q150_Q150-20mD-L600.csv
Geothermal_Q150_Q150-500mD-L600.csv
Geothermal_Q150_Q150-50mD-L600.csv
Geothermal_Q200_Q200-100mD-L700.csv
Geothermal_Q200_Q200-1D-L700.csv
Geothermal_Q200_Q200-20mD-L700.csv
Geothermal_Q200_Q200-500mD-L700.csv
Geothermal_Q200_Q200-50mD-L700.csv
Geothermal_Q250_Q250-100mD-L800.csv
Geothermal_Q250_Q250-1D-L800.csv
Geothermal_Q250_Q250-20mD-L800.csv
Geothermal_Q250_Q250-500mD-L800.csv
Geothermal_Q250_Q250-50mD-L800.csv

In [93]:
# Q=250, L = 800
ind      = [11:15; 21:25]
spl_R_pr = Spline2D(perm[ind], Q[ind], R_pr[ind], kx=1, ky=1, s=16)
Qi       = collect(linspace(minimum(Q[ind]), maximum(Q[ind]), 20))
permi    = collect(linspace(minimum(perm[ind]), maximum(perm[ind]), 20))
R_pri    = evalgrid(spl_R_pr, permi, Qi)


Out[93]:
20×20 Array{Float64,2}:
 -2.20258      -2.25847    -2.31436    …  -3.90693    -4.25921    -4.61149  
 -1.25511      -1.35026    -1.4454        -2.81194    -2.88326    -2.95457  
 -0.344254     -0.476616   -0.608978      -1.75584    -1.55867    -1.36151  
 -0.258151     -0.381789   -0.505427      -1.57585    -1.39135    -1.20685  
 -0.172047     -0.286962   -0.401876      -1.39587    -1.22403    -1.05219  
 -0.0859442    -0.192135   -0.298325   …  -1.21588    -1.05671    -0.897532 
  0.000159038  -0.0973077  -0.194774      -1.0359     -0.889387   -0.742873 
  0.0862623    -0.0024806  -0.0912235     -0.855916   -0.722065   -0.588214 
  0.172366      0.0923465   0.0123274     -0.675932   -0.554743   -0.433555 
  0.258469      0.187174    0.115878      -0.495948   -0.387422   -0.278896 
  0.344572      0.282001    0.219429   …  -0.315963   -0.2201     -0.124237 
  0.430675      0.376828    0.32298       -0.135979   -0.0527784   0.0304221
  0.516779      0.471655    0.426531       0.0440054   0.114543    0.185081 
  0.602882      0.566482    0.530082       0.22399     0.281865    0.33974  
  0.688985      0.661309    0.633633       0.403974    0.449187    0.494399 
  0.775088      0.756136    0.737183   …   0.583958    0.616508    0.649058 
  0.861192      0.850963    0.840734       0.763943    0.78383     0.803717 
  0.947295      0.94579     0.944285       0.943927    0.951152    0.958376 
  1.0334        1.04062     1.04784        1.12391     1.11847     1.11304  
  1.1195        1.13544     1.15139        1.3039      1.28579     1.26769  

In [94]:
plot3D(perm[ind], Q[ind], R_pr[ind], "o")
surf(permi, Qi, R_pri)
xlabel("Permeability [m^2]")
ylabel("flow rate [m^3/s]")
zlabel("Recovery factor (pr)")


Out[94]:
PyObject <matplotlib.text.Text object at 0x7fc3565e60d0>