# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     name: python3
# ---

# + [markdown] id="view-in-github" colab_type="text"
# <a href="https://colab.research.google.com/github/EvenSol/NeqSim-Colab/blob/master/notebooks/reservoir/simplereservoir.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>

# + cellView="form" id="EbEbhy9hvF7i" outputId="19143128-fb9b-4aff-c365-5fb38b1d7382" colab={"base_uri": "https://localhost:8080/"}
#@title A simplified reservoir simulation model
#@markdown In this section we will use a simplified reservoir simulation model based in constant volume - temperature flashes. This will be used for developing fluid input to further gas processing calculations.
#@markdown <br><br>This document is part of the module ["Introduction to Gas Processing using NeqSim in Colab"](https://colab.research.google.com/github/EvenSol/NeqSim-Colab/blob/master/notebooks/examples_of_NeqSim_in_Colab.ipynb#scrollTo=_eRtkQnHpL70).
# #%%capture
# !pip install neqsim
import neqsim
from neqsim.thermo.thermoTools import *
from neqsim.process.processTools import simplereservoir
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import math
plt.style.use('classic')
# %matplotlib inline


# + [markdown] id="sVE0XWti5qav"
# # Reservoir simulation - the tank model
# One of the representations of reservoir models is called the Tank Model, is also called "the building block of reservoir simulators", it is a zero dimensional model, because just like in the example of the oil MBE equation, the difference between the initial oil and the final oil entering the reservoir is the Cumulative net withdrawal. The tank model takes the average values for the whole properties of the reservoir by assuming that there is no oil entering the reservoir. However, the tank model cannot represent sandbars and average them out as a whole due to variation of lithology, but instead it can average out the components within. In this case, because of the expansion of fluids complications, the MBE equation together with Darcy's Law are used to describe the behavior of each component. This new model is a one- dimensional simulator because it has more than one component in one direction and one component in the other two directions. 
#
# Ref.: https://wiki.seg.org/wiki/Reservoir_simulation

# + id="HqFMKNfG5qaw" outputId="b2824c9b-a13e-4a17-c4c0-08a57c469786" colab={"base_uri": "https://localhost:8080/", "height": 684}
fluid1 = fluid('srk')
fluid1.addComponent("nitrogen", 0.100)
fluid1.addComponent("CO2", 0.100)
fluid1.addComponent("methane", 30.00)
fluid1.addComponent("ethane", 1.0)
fluid1.addComponent("propane", 1.0)
fluid1.addComponent("i-butane", 1.0)
fluid1.addComponent("n-butane", 1.0)
fluid1.addComponent("n-hexane", 0.1)
fluid1.addComponent("n-heptane", 0.1)
fluid1.addComponent("n-nonane", 1.0)
fluid1.addComponent("nC10", 1.0)
fluid1.addComponent("nC12", 3.0)
fluid1.addComponent("nC15", 3.0)
fluid1.addComponent("nC20", 3.0)
fluid1.addComponent("water", 11.0)
fluid1.setMixingRule(2)
fluid1.setMultiPhaseCheck(True)

fluid1.setPressure(100.0, 'bara')
fluid1.setTemperature(100.0, 'C')

TPflash(fluid1)

reservoirOps = simplereservoir(fluid1, "Well 1 reservoir", gasvolume=5.0 * 1e7, oilvolume=552.0 * 1e6, watervolume=10.0e6)

producedGasStream = reservoirOps.addGasProducer("SLP_A32562G")
producedGasStream.setFlowRate(0.01, "MSm3/day")

injectionGasStream = reservoirOps.addGasInjector("SLP_A32562GI")
fluidComposition(injectionGasStream.getFluid(), [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,0.0])
injectionGasStream.setFlowRate(1.1, "MSm3/day")

injectionWaterStream = reservoirOps.addWaterInjector("SLP_A32562W")
injectionWaterStream.setFlowRate(10000000.1, "kg/day")

producedOilStream = reservoirOps.addOilProducer("SLP_A32562O")
producedOilStream.setFlowRate(50000000.0, "kg/day")


deltat = 24*60*60.0*365
time = []
pressure = []
gasvolume = []
watervolume = []
oilvolume = []
wateringas = []
totalproducedoe = []
co2reservoirgas = []

for t in range(10):
    reservoirOps.runTransient(deltat)
    time.append(t*deltat/(24*60*60.0*365))
    pressure.append(reservoirOps.getReservoirFluid().getPressure('bara'))
    gasvolume.append(reservoirOps.getReservoirFluid().getPhase("gas").getVolume("m3"))
    oilvolume.append(reservoirOps.getReservoirFluid().getPhase("oil").getVolume("m3"))
    watervolume.append(reservoirOps.getReservoirFluid().getPhase("aqueous").getVolume("m3"))
    wateringas.append(reservoirOps.getReservoirFluid().getPhase("gas").getComponent('water').getx())
    totalproducedoe.append(reservoirOps.getProductionTotal('MSm3 oe'))
    co2reservoirgas.append(reservoirOps.getReservoirFluid().getComponent('CO2').getz())


plt.rcParams['figure.figsize'] = [10, 20]
fig, ax = plt.subplots()
plt.subplot(7, 1, 1)
plt.plot(time, pressure)
plt.xlabel('Year [-]')
plt.ylabel('Pressure [bara]')
plt.subplot(7, 1, 2)
plt.plot(time, gasvolume)
plt.xlabel('Year [-]')
plt.ylabel('gasVol [m3]')
plt.subplot(7, 1, 3)
plt.plot(time, oilvolume)
plt.xlabel('Year [-]')
plt.ylabel('oilVol [m3]')
plt.subplot(7, 1, 4)
plt.plot(time, watervolume)
plt.xlabel('Year [-]')
plt.ylabel('waterVol [m3]')
plt.subplot(7, 1, 5)
plt.plot(time, wateringas)
plt.xlabel('Year [-]')
plt.ylabel('water in gas [-]')
plt.subplot(7, 1, 6)
plt.plot(time, totalproducedoe)
plt.xlabel('Year [-]')
plt.ylabel('Total production [MSm3 oe]')
plt.subplot(7, 1, 7)
plt.plot(time, co2reservoirgas)
plt.xlabel('Year [-]')
plt.ylabel('CO2 in reservoir gas [mole frac]')





# + id="r4wsTuOD5qaw"


StarcoderdataJupyterScriptsDedupFiltered