Simulation Core
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

489 lines
27 KiB

  1. SUBROUTINE GasKickCalculator
  2. use SimulationVariables
  3. use KickVARIABLESModule
  4. use SimulationVariables !@
  5. Use CReservoirVariables
  6. Use CFormationVariables
  7. USE Fluid_Flow_Startup_Vars
  8. use PressureDisplayVARIABLESModule
  9. USE FricPressDropVarsModule
  10. USE MudSystemVARIABLES
  11. use SimulationVariables !@@@
  12. USE CMudPropertiesVariables
  13. USE CError
  14. USE , INTRINSIC :: IEEE_ARITHMETIC
  15. !! Note: a subject that may be confusing is that when we use gauge pressure and when're using absolute pressure?!
  16. !! all stated pressure are gauge pressure, so I do like this.
  17. !! only when we want to use a state equation (like ideal gas equation), we should use absolute equation and so I do this.
  18. !! Thus gas pocket pressure are all absolute pressure.
  19. IMPLICIT NONE
  20. INTEGER :: i , j , k , l
  21. SolvingEquationError = .FALSE.
  22. KickVandPFunction(:) = 0.d0
  23. KickJacobian(: , :) = 0.d0
  24. !====================================================
  25. ! Gas Properties (Methane Gas)
  26. !====================================================
  27. !GasPocketNewTemp%Array(1) = 600
  28. BottomHoleTemperature = 600
  29. KickFluxAvgPressure = (BottomHolePress + FormPressure) / 2 + StandardPress
  30. KickFluxAvgTemperature = (FormTemperature + BottomHoleTemperature) / 2
  31. KickFluxAvgCompressibility = 0.98d0
  32. K_Aa = (5.8742362 * 10.**(-3) * KickFluxAvgTemperature**1.2288) / (511.1728532 + KickFluxAvgTemperature)
  33. K_Bb = 5.5565586 + (1000.01 / KickFluxAvgTemperature)
  34. K_Cc = 2.47862 - 0.12294 * K_Bb
  35. GasKickSIDensity = KickFluxAvgPressure / (KickFluxAvgCompressibility * &
  36. KickFluxAvgTemperature * data%State%GasType(KickGasType)%GasConstant) * Convpcftogpcm3
  37. GasKickViscosity = K_Aa * EXP(K_Bb * GasKickSIDensity**K_Cc)
  38. !!!!!!!!!!!!!!!!!!!!!!!!!
  39. !!!!!!!!!!!!!! Calculating compressibility for bottom hole condition
  40. BottomHoleCompressibility = 0.98d0
  41. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  42. GasKickBg = 0.00504 * KickFluxAvgCompressibility * KickFluxAvgTemperature / KickFluxAvgPressure ![bbl/SCF]
  43. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  44. !WRITE (*,*) 'Gas Kick Top'
  45. !===> Kick Flow Rate Calculation
  46. IF (FormPressure > BottomHolePress) THEN
  47. KickmdotACoef = 10.0**(-8) * 1.15741d0 * 7.080 * FormPermeability * REAL(KickFormLength) * data%State%GasType(KickGasType)%StDensity / &
  48. (GasKickViscosity * GasKickBg * LOG(10000.0))
  49. !IF (WellHeadOpen .AND. NoGasPocket == 1) KickmdotACoef = (1.d0 + 2.d0) * KickmdotACoef
  50. ELSE
  51. KickmdotACoef = 0.0
  52. END IF
  53. i = data%State%FricPressDrop%StringLastEl
  54. j = data%State%FricPressDrop%OpenholeFirstEl - 1
  55. k = GasPocketFlowEl(1 , 1)
  56. KickmdotBCoef = FormPressure + StandardPress !! - Sum(static and friction pressure loss) of flow elements below gas pocket, see below
  57. IF (FormPressure > BottomHolePress) THEN
  58. !WRITE (*,*) 'k , i, j' , k , i, j
  59. IF (k >= data%State%FricPressDrop%OpenholeFirstEl) THEN ! Bottom of active kick is in openhole
  60. KickmdotBCoef = KickmdotBCoef - (SUM(FlowEl(data%State%FricPressDrop%OpenholeFirstEl : k)%StaticPressDiff)) !+ SUM(FlowEl(j + 1 : GasPocketFlowEl(1 , 1) - 1)%FricPressLoss
  61. !WRITE (*,*) '1 SUM(FlowEl(j + 1 : k)%FricPressLoss', k, SUM(FlowEl(j + 1 : k)%FricPressLoss)
  62. ELSE IF (k < data%State%FricPressDrop%OpenholeFirstEl) THEN ! bottom of 1st gas pocket (active kick) is in annulus ond/or choke line only
  63. KickmdotBCoef = KickmdotBCoef - SUM(FlowEl(data%State%FricPressDrop%OpenholeFirstEl : data%State%FricPressDrop%NumbEl)%StaticPressDiff) &
  64. - (SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : k)%StaticPressDiff) + SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : k)%FricPressLoss))
  65. END IF
  66. END IF
  67. DO l = 1 , NoGasPocket
  68. KickUnknownVector(2 * l - 1) = GasPocketNewVol%Array(l)
  69. KickUnknownVector(2 * l) = GasPocketNewPress%Array(l)
  70. END DO
  71. IF (WellHeadOpen) THEN
  72. !!!!!!!!!! Calculation of functions of pocket Pressure and gas Volumes
  73. !IF (GasPocketElementNo(1) > 0) WRITE (*,*) ' GasPocketElementNo(1) ' , GasPocketElementNo(1)
  74. !WRITE (*,*) ' Kick Unknown Vector' , KickUnknownVector!(1) , KickUnknownVector(2)
  75. IF (KickIteration == 1) THEN ! updating initial guess based on previous time step data
  76. DO l = 1 , NoGasPocket
  77. KickUnknownVector(2 * l - 1) = KickUnknownVector(2 * l - 1) + GasPocketDeltaVol%Array(l)
  78. END DO
  79. END IF
  80. KickVandPFunction(1) = KickUnknownVector(1) - GasPocketCompressibility%Array(1) * data%State%GasType(KickGasType)%GasConstant * & ! VandP(1) = V(1)
  81. GasPocketNewTemp%Array(1) * (GasPocketWeight%Array(1) + KickmdotACoef * MAX(((KickmdotBCoef - KickUnknownVector(2)) * dt) , 0.0)) / KickUnknownVector(2)
  82. !WRITE (*,*) 'KickVandPFunction(1)',KickVandPFunction(1)
  83. l = 2 * NoGasPocket
  84. CALL KickFunctionsCalculator(KickVandPFunction(l) , NoGasPocket , 2) ! VandP(last) = P(last)
  85. !WRITE (*,*) 'KickVandPFunction(l)', l, KickVandPFunction(l)
  86. DO l = 2 , NoGasPocket ! VandP(Odd) = V(l, l > 1)
  87. KickVandPFunction(2 * l - 1) = KickUnknownVector(2 * l - 1) - GasPocketCompressibility%Array(l) * data%State%GasType(KickGasType)%GasConstant * &
  88. GasPocketNewTemp%Array(l) * GasPocketWeight%Array(l) / KickUnknownVector(2 * l)
  89. !WRITE(*,*) 'KickVandPFunction(V)', l, KickVandPFunction(2 * l - 1)
  90. END DO
  91. DO l = NoGasPocket - 1 , 1 , -1
  92. CALL KickFunctionsCalculator(KickVandPFunction(2 * l) , l , 1) ! VandP(Even) = P(l, l < NoGasPocket)
  93. !WRITE(*,*) 'KickVandPFunction(P)', l , KickVandPFunction(2 * l)
  94. END DO
  95. !!!!!!!!!! END - Calculation of functions of pocket Pressure and gas Volumes
  96. !!!!!!!!!! Calculation of Jacobian
  97. DO k = 1 , 2 * NoGasPocket ! Main Diagonal
  98. KickJacobian(k , k) = 1.d0
  99. END DO
  100. KickJacobian(1,2) = (GasPocketCompressibility%Array(1) * data%State%GasType(KickGasType)%GasConstant * GasPocketNewTemp%Array(1) &
  101. * (GasPocketWeight%Array(1) + KickmdotACoef * KickmdotBCoef * dt) / KickUnknownVector(2)**2) ! Row 1 Finished
  102. IF (KickJacobian(1,2) == 0.d0) THEN
  103. CALL Error('KickJacobian(1,2) = 0.0')
  104. KickJacobian(1,2) = OldKickJacobian(1,2)
  105. END IF
  106. !WRITE(*,*) 'KickJacobian(1,2)', KickJacobian(1,2)
  107. l = NoGasPocket
  108. CALL KickFunctionsCalculator(KickJacobian(2 * l , 2 * l - 1) , NoGasPocket , 4) ! for last Row
  109. IF (KickJacobian(2 * l , 2 * l - 1) == 0.d0) THEN
  110. CALL Error ('KickJacobian(Last,Odd) = 0.0')
  111. KickJacobian(2 * l , 2 * l - 1) = OldKickJacobian(2 * l , 2 * l - 1)
  112. END IF
  113. DO k = NoGasPocket - 1 , 1 , -1
  114. KickJacobian(2 * l , 2 * k - 1) = KickJacobian(2 * l , 2 * l - 1)
  115. END DO ! Last Row Finished
  116. !WRITE(*,*) 'KickJacobian(2,1)', KickJacobian(2,1)
  117. DO k = 2 , NoGasPocket
  118. KickJacobian(2 * k - 1 , 2 * k) = GasPocketCompressibility%Array(k) * data%State%GasType(KickGasType)%GasConstant * GasPocketNewTemp%Array(k) &
  119. * GasPocketWeight%Array(k) / KickUnknownVector(2 * k)**2
  120. END DO ! Odd Rows (V equations) Finished
  121. DO k = 1 , NoGasPocket - 1
  122. KickJacobian(2 * k , 2 * k + 2) = -1.d0
  123. END DO ! Even Rows (P equations) effect of upper pocket
  124. DO k = 2 , 2 * (NoGasPocket - 1) , 2
  125. DO l = 1 , k - 1 , 2
  126. CALL KickFunctionsCalculator(KickJacobian(k , l) , k / 2 , 3)
  127. IF (KickJacobian(k , l) == 0.d0) THEN
  128. WRITE (*,*) 'Jacobian Array = 0.0', k , l
  129. CALL Error ('KickJacobian(k , l) = 0.0')
  130. KickJacobian(k , l) = OldKickJacobian(k , l)
  131. END IF
  132. END DO
  133. END DO
  134. IF (ANY(IEEE_IS_NaN(KickJacobian))) CALL ErrorStop ('NaN in calculating Kick Jacobian, Call your Service Provider')
  135. !!!!!!!!!! Solving linear equation in order to finding correction vector for correcting pocket pressure and gas induced flowrates
  136. KickVandPFunction = -1.d0 * KickVandPFunction
  137. CALL SOLVE_LINEAR_EQUATIONS(KickJacobian , KickCorrectionVector , KickVandPFunction , SolvingEquationError, SIZE(KickCorrectionVector))
  138. IF (SolvingEquationError) CALL ErrorStop( ' Error in solving kick equation ' )
  139. KickUnknownVector = KickUnknownVector + KickCorrectionUnderRelaxation * KickCorrectionVector
  140. DO l = 1 , NoGasPocket
  141. GasPocketNewVol%Array(l) = KickUnknownVector(2 * l - 1)
  142. IF (IEEE_IS_NaN(GasPocketNewVol%Array(l))) CALL ErrorStop('Volume of this pocket is Not a Number:', l)
  143. IF (GasPocketNewVol%Array(l) <= 0.d0) CALL Error('Volume of this pocket is Negative or Zero:', l)
  144. GasPocketNewPress%Array(l) = KickUnknownVector(2 * l)
  145. IF (IEEE_IS_NaN(GasPocketNewPress%Array(l))) CALL ErrorStop('Pressure of this Pocket is Not a Number:', l)
  146. IF (GasPocketNewPress%Array(l) <= 0.d0) CALL ErrorStop('Pressure of this Pocket is Negative or Zero:', l)
  147. END DO
  148. ELSE ! well haed is closed, so build up process or migration occurs
  149. !WRITE (*,*) 'GasPocketOldPress (before)' , GasPocketOldPress(1)
  150. GasPocketNewPress%Array(1) = GasPocketOldPress%Array(1) * &
  151. (REAL((GasPocketWeight%Array(1) + KickmdotACoef * KickmdotBCoef * dt) / (GasPocketWeight%Array(1) + KickmdotACoef * GasPocketOldPress%Array(1) * dt)))
  152. END IF
  153. !DO l = 1 , NoGasPocket
  154. GasPocketDeltaVol%Array(:) = GasPocketNewVol%Array(:) - GasPocketOldVol%Array(:)
  155. GasPocketFlowInduced%Array(:) = (GasPocketDeltaVol%Array(:)) / dt * 448.8 ! gpm
  156. !END DO
  157. GasKickPumpFlowRate = 0.0
  158. IF (NOT(KickOffBottom) .AND. WellHeadOpen) GasKickPumpFlowRate = GasPocketFlowInduced%Array(1)
  159. END SUBROUTINE
  160. SUBROUTINE KickFunctionsCalculator(ExitValue , GasPocketNo , CalcMode)
  161. use SimulationVariables
  162. use KickVARIABLESModule
  163. USE FricPressDropVarsModule
  164. USE Fluid_Flow_Startup_Vars
  165. USE CError
  166. USE , INTRINSIC :: IEEE_Arithmetic
  167. IMPLICIT NONE
  168. REAL(8) :: ExitValue
  169. INTEGER :: GasPocketNo , CalcMode
  170. INTEGER :: x
  171. INTEGER :: y
  172. INTEGER :: z , i , j
  173. x = GasPocketFlowEl(GasPocketNo , 1)
  174. IF (GasPocketNo < NoGasPocket) y = GasPocketFlowEl(GasPocketNo + 1 , 1)
  175. i = data%State%FricPressDrop%StringLastEl
  176. j = data%State%FricPressDrop%OpenholeFirstEl - 1
  177. ! Case 1: gas pocket is completely in OP and STARTX of upper gas pocket is also
  178. ! Case 2: gas pocket is completely in OP and STARTX of upper gas pocket is above Bit
  179. ! Case 3: gas pocket is AROUNDBIT and so upper gas pocket is in ANN (or Choke line)
  180. ! Case 4: gas pocket is completely in ANN and upper gas pocket is also
  181. ! CalcMode 1: KickVandPFunction between 2 pocket
  182. ! CalcMode 2: KickVandPFunction for top gas pocket
  183. ! CalcMode 3: KickJacobian between 2 Pocket
  184. ! CalcMode 4: KickJacobian for top (last) gas pocket
  185. ! CalcMode 5: Calculating pressure of bottom pocket based on upper pocket
  186. IF (CalcMode == 1) THEN ! calculating pressure difference between two pocket, include static pressure difference and frictional
  187. ! pressure difference, use in calculating 'KickVandPFunction'
  188. ExitValue = KickUnknownVector(2 * GasPocketNo) - KickUnknownVector(2 * GasPocketNo + 2)
  189. IF (x >= data%State%FricPressDrop%OpenholeFirstEl .AND. y < data%State%FricPressDrop%OpenholeFirstEl) THEN ! Case 2 , Case 3
  190. ExitValue = ExitValue - SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%StaticPressDiff) - SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%FricPressLoss) &
  191. - SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : y)%StaticPressDiff) - SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : y)%FricPressLoss)
  192. ELSE ! Case 1 , Case 4
  193. ExitValue = ExitValue - SUM(FlowEl(x : y)%StaticPressDiff) - SUM(FlowEl(x : y)%FricPressLoss)
  194. END IF
  195. ELSE IF (CalcMode == 2) THEN
  196. ExitValue = KickUnknownVector(2 * GasPocketNo) - StandardPress - data%State%FricPressDrop%Kchoke * FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Flowrate**2
  197. IF (x >= data%State%FricPressDrop%OpenholeFirstEl) THEN ! Gas Pocket is in Openhole
  198. ExitValue = ExitValue - SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%StaticPressDiff) - SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%FricPressLoss) &
  199. - SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%OpenholeFirstEl - 1)%StaticPressDiff) - SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%OpenholeFirstEl - 1)%FricPressLoss)
  200. ELSE ! Gas Pocket is in Annulus
  201. ExitValue = ExitValue - SUM(FlowEl(x : data%State%FricPressDrop%OpenholeFirstEl - 1)%StaticPressDiff) - SUM(FlowEl(x : data%State%FricPressDrop%OpenholeFirstEl - 1)%FricPressLoss)
  202. END IF
  203. ELSE IF (CalcMode == 3) THEN ! calculating derivative of pressure difference between two pocket, relative to change in flowrate
  204. ! use in calculating 'KickJacobian'
  205. IF (x >= data%State%FricPressDrop%OpenholeFirstEl .AND. y < data%State%FricPressDrop%OpenholeFirstEl) THEN ! Top kick STARTX is in Annulus
  206. DO z = x , data%State%FricPressDrop%NumbEl ! open hole elements
  207. CALL PartialDerivativeFricToFlowRate(z)
  208. IF (IEEE_IS_NaN(FlowEl(z)%FricToQPartialDiff)) THEN
  209. WRITE (*,*) ' FricToQPartialDiff , GenRe ' , x , FlowEl(z)%FricToQPartialDiff , FlowEl(z)%GenRe
  210. WRITE (*,*) ' Op start, end, density, Q, mu' , FlowEl(z)%StartX, FlowEl(z)%EndX, FlowEl(z)%Density, FlowEl(z)%FlowRate, FlowEl(z)%mueff
  211. CALL ErrorStop('NaN in calculating partial derivative')
  212. END IF
  213. END DO
  214. DO z = data%State%FricPressDrop%AnnulusFirstEl , y ! Annulus elements
  215. CALL PartialDerivativeFricToFlowRate(z)
  216. IF (IEEE_IS_NaN(FlowEl(z)%FricToQPartialDiff)) THEN
  217. WRITE (*,*) ' FricToQPartialDiff , GenRe ' , x , FlowEl(z)%FricToQPartialDiff , FlowEl(z)%GenRe
  218. WRITE (*,*) ' Op start, end, density, Q, mu' , FlowEl(z)%StartX, FlowEl(z)%EndX, FlowEl(z)%Density, FlowEl(z)%FlowRate, FlowEl(z)%mueff
  219. CALL ErrorStop('NaN in calculating partial derivative')
  220. END IF
  221. END DO
  222. ExitValue = ExitValue - (SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%FricToQPartialDiff) + SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : y)%FricToQPartialDiff)) * 448.8 / dt
  223. ELSE ! both pockets are one side of bit
  224. DO z = x , y
  225. CALL PartialDerivativeFricToFlowRate(z)
  226. IF (IEEE_IS_NaN(FlowEl(z)%FricToQPartialDiff)) THEN
  227. WRITE (*,*) ' FricToQPartialDiff , GenRe ' , x , FlowEl(z)%FricToQPartialDiff , FlowEl(z)%GenRe
  228. WRITE (*,*) ' Op start, end, density, Q, mu' , FlowEl(z)%StartX, FlowEl(z)%EndX, FlowEl(z)%Density, FlowEl(z)%FlowRate, FlowEl(z)%mueff
  229. CALL ErrorStop('NaN in calculating partial derivative')
  230. END IF
  231. END DO
  232. ExitValue = ExitValue - SUM(FlowEl(x : y)%FricToQPartialDiff) * 448.8 / dt
  233. END IF
  234. ELSE IF (CalcMode == 4) THEN ! partial derivative of frictional pressure drop relative to flowrate for top gas pocket
  235. ExitValue = - 2.d0 * data%State%FricPressDrop%Kchoke * FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Flowrate * 448.8 / dt
  236. IF (x >= data%State%FricPressDrop%OpenholeFirstEl) THEN ! kick STARTX is in openhole
  237. DO z = x , data%State%FricPressDrop%NumbEl ! open hole elements
  238. CALL PartialDerivativeFricToFlowRate(z)
  239. IF (IEEE_IS_NaN(FlowEl(z)%FricToQPartialDiff)) THEN
  240. WRITE (*,*) ' FricToQPartialDiff , GenRe ' , x , FlowEl(z)%FricToQPartialDiff , FlowEl(z)%GenRe
  241. WRITE (*,*) ' Op start, end, density, Q, mu' , FlowEl(z)%StartX, FlowEl(z)%EndX, FlowEl(z)%Density, FlowEl(z)%FlowRate, FlowEl(z)%mueff
  242. CALL ErrorStop('NaN in calculating partial derivative')
  243. END IF
  244. END DO
  245. DO z = data%State%FricPressDrop%AnnulusFirstEl , data%State%FricPressDrop%OpenholeFirstEl - 1 ! Annulus elements
  246. CALL PartialDerivativeFricToFlowRate(z)
  247. IF (IEEE_IS_NaN(FlowEl(z)%FricToQPartialDiff)) THEN
  248. WRITE (*,*) ' FricToQPartialDiff , GenRe ' , x , FlowEl(z)%FricToQPartialDiff , FlowEl(z)%GenRe
  249. WRITE (*,*) ' Op start, end, density, Q, mu' , FlowEl(z)%StartX, FlowEl(z)%EndX, FlowEl(z)%Density, FlowEl(z)%FlowRate, FlowEl(z)%mueff
  250. CALL ErrorStop('NaN in calculating partial derivative')
  251. END IF
  252. END DO
  253. ExitValue = ExitValue - (SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%FricToQPartialDiff) + SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%OpenholeFirstEl - 1)%FricToQPartialDiff)) * 448.8 / dt
  254. ELSE
  255. DO z = x , data%State%FricPressDrop%OpenholeFirstEl - 1 ! Annulus elements
  256. CALL PartialDerivativeFricToFlowRate(z)
  257. IF (IEEE_IS_NaN(FlowEl(z)%FricToQPartialDiff)) THEN
  258. WRITE (*,*) ' FricToQPartialDiff , GenRe ' , x , FlowEl(z)%FricToQPartialDiff , FlowEl(z)%GenRe
  259. WRITE (*,*) ' Op start, end, density, Q, mu' , FlowEl(z)%StartX, FlowEl(z)%EndX, FlowEl(z)%Density, FlowEl(z)%FlowRate, FlowEl(z)%mueff
  260. CALL ErrorStop('NaN in calculating partial derivative')
  261. END IF
  262. END DO
  263. ExitValue = ExitValue - SUM(FlowEl(x : data%State%FricPressDrop%OpenholeFirstEl - 1)%FricToQPartialDiff) * 448.8 / dt
  264. END IF
  265. ELSE IF (CalcMode == 5) THEN
  266. IF (x >= data%State%FricPressDrop%OpenholeFirstEl .AND. y < data%State%FricPressDrop%OpenholeFirstEl) THEN ! Gas Pocket is in Openhole and upper pocket is in annulus
  267. !WRITE (*,*) 'x , y 1' , x, y
  268. ExitValue = GasPocketNewPress%Array(GasPocketNo + 1) + SUM(FlowEl(x : data%State%FricPressDrop%NumbEl)%StaticPressDiff) + SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : y)%StaticPressDiff)
  269. ELSE ! Both gas pockets are in Annulus or openhole
  270. !WRITE (*,*) 'x , y 2' , x, y
  271. ExitValue = GasPocketNewPress%Array(GasPocketNo + 1) + SUM(FlowEl(x : y)%StaticPressDiff)
  272. END IF
  273. END IF
  274. END SUBROUTINE
  275. SUBROUTINE NewGasKick
  276. use SimulationVariables
  277. use KickVARIABLESModule
  278. Use CReservoirVariables
  279. Use CFormationVariables
  280. USE Fluid_Flow_Startup_Vars
  281. use PressureDisplayVARIABLESModule
  282. USE FricPressDropVarsModule
  283. USE MudSystemVARIABLES
  284. USE CMudPropertiesVariables
  285. USE CError
  286. USE , INTRINSIC :: IEEE_ARITHMETIC
  287. !! Note: a subject that may be confusing is that when we use gauge pressure and when using absolute pressure?!
  288. !! all stated pressure are gauge pressure, so I do like this.
  289. !! only when we want to use a state equation (like ideal gas equation), we should use absolute equation and so I do this.
  290. !! Thus gas pocket pressure are all absolute pressure.
  291. IMPLICIT NONE
  292. INTEGER :: i , j , k , l
  293. IF (NOT(ALLOCATED(GasPocketWeight%Array))) THEN ! 1st kick
  294. WRITE (*,*) ' New Influx 1'
  295. NoGasPocket = 1
  296. data%State%MudSystem%NewInfluxNumber = data%State%MudSystem%NewInfluxNumber + 1
  297. data%State%MudSystem%NewInfluxElementCreated = 0
  298. KickOffBottom = .FALSE.
  299. CALL GasPocketOldPress%AddToFirst((BottomHolePress + StandardPress) * 1.d0)
  300. CALL GasPocketNewPress%AddToFirst((BottomHolePress + StandardPress) * 1.d0)
  301. CALL GasPocketOldTemp%AddToFirst(600.0)
  302. CALL GasPocketNewTemp%AddToFirst(600.0)
  303. CALL GasPocketOldVol%AddToFirst(0.d0)
  304. CALL GasPocketNewVol%AddToFirst(0.d0)
  305. CALL GasPocketdeltaVol%AddToFirst(0.0)
  306. CALL GasPocketFlowInduced%AddToFirst(0.0)
  307. CALL GasPocketModifiedVol%AddToFirst(0.0)
  308. CALL GasPocketWeight%AddToFirst(0.0)
  309. CALL GasPocketDensity%AddToFirst(2.0)
  310. CALL GasPocketCompressibility%AddToFirst(0.98)
  311. ALLOCATE(KickJacobian(2 , 2) , OldKickJacobian(2 , 2) , KickVandPFunction(2) , KickUnknownVector(2) , KickCorrectionVector(2))
  312. BottomHoleTemperature = 600
  313. KickFluxAvgPressure = (BottomHolePress + FormPressure) / 2 + StandardPress
  314. KickFluxAvgTemperature = (FormTemperature + BottomHoleTemperature) / 2
  315. KickFluxAvgCompressibility = 0.98
  316. GasKickSIDensity = KickFluxAvgPressure / (KickFluxAvgCompressibility * &
  317. KickFluxAvgTemperature * data%State%GasType(KickGasType)%GasConstant) * Convpcftogpcm3
  318. GasKickDensity = GasKickSIDensity * 8.3523
  319. GasPocketWeight%Array(1) = GasKickDensity * MinKickVol !1.0:seyyed gofte !KickmdotACoef * (KickmdotBCoef - GasPocketNewPress%Array(1)) * dt
  320. GasPocketNewVol%Array(1) = GasPocketCompressibility%Array(1) * data%State%GasType(KickGasType)%GasConstant * &
  321. GasPocketNewTemp%Array(1) * GasPocketWeight%Array(1) / GasPocketNewPress%Array(1)
  322. GasPocketDeltaVol%Array(1) = 0.05 !GasPocketNewVol%Array(1)
  323. GasPocketFlowInduced%Array(1) = (GasPocketDeltaVol%Array(1)) / dt * 448.8 ! gpm
  324. GasKickPumpFlowRate = GasPocketFlowInduced%Array(1)
  325. WRITE (*,*) ' FormPressure , BottomHolePress' , FormPressure , BottomHolePress, GasKickDensity
  326. WRITE (*,*) ' No Press(psia) Vol(gal) Weight(lbm) Flow Induced(gpm)'
  327. DO i = 1 , NoGasPocket
  328. WRITE (*,102) i , GasPocketNewPress%Array(i), GasPocketNewVol%Array(i) * Convft3toUSgal, GasPocketWeight%Array(i), GasPocketFlowInduced%Array(i)
  329. END DO
  330. !ELSE IF (NoGasPocket < MaxGasPocket .AND. KickOffBottom .AND. (GasPocketNewVol%Array(1) > MinAllowableKickVol .OR. KickWasExitingThroughChoke)) THEN
  331. ELSE IF (NoGasPocket < MaxGasPocket .AND. KickOffBottom .AND. (GasPocketNewVol%Array(1) > MinAllowableKickVol .OR. ANY(GasPocketFlowEl(1 , :) == data%State%FricPressDrop%OpenholeFirstEl - 1))) THEN
  332. WRITE (*,*) ' New Influx', NoGasPocket + 1
  333. 102 FORMAT (I2, 4X, (F8.1), 3X, (F8.3), 2X, (F8.3), 8X, (F8.3))
  334. NoGasPocket = NoGasPocket + 1
  335. data%State%MudSystem%NewInfluxNumber = data%State%MudSystem%NewInfluxNumber + 1
  336. data%State%MudSystem%NewInfluxElementCreated = 0
  337. KickOffBottom = .FALSE.
  338. CALL GasPocketOldPress%AddToFirst((BottomHolePress + StandardPress) * 1.d0)
  339. CALL GasPocketNewPress%AddToFirst((BottomHolePress + StandardPress) * 1.d0)
  340. CALL GasPocketOldTemp%AddToFirst(600.0)
  341. CALL GasPocketNewTemp%AddToFirst(600.0)
  342. CALL GasPocketOldVol%AddToFirst(0.d0)
  343. CALL GasPocketNewVol%AddToFirst(0.d0)
  344. CALL GasPocketdeltaVol%AddToFirst(0.0)
  345. CALL GasPocketFlowInduced%AddToFirst(0.0)
  346. CALL GasPocketModifiedVol%AddToFirst(0.0)
  347. CALL GasPocketWeight%AddToFirst(0.0)
  348. CALL GasPocketDensity%AddToFirst(2.0)
  349. CALL GasPocketCompressibility%AddToFirst(0.98)
  350. DEALLOCATE(KickJacobian , OldKickJacobian , KickVandPFunction , KickUnknownVector , KickCorrectionVector)
  351. ALLOCATE(KickJacobian(2 * NoGasPocket , 2 * NoGasPocket) , OldKickJacobian(2 * NoGasPocket , 2 * NoGasPocket))
  352. ALLOCATE(KickUnknownVector(2 * NoGasPocket) , KickCorrectionVector(2 * NoGasPocket) , KickVandPFunction(2 * NoGasPocket))
  353. BottomHoleTemperature = 600
  354. KickFluxAvgPressure = (BottomHolePress + FormPressure) / 2 + StandardPress
  355. KickFluxAvgTemperature = (FormTemperature + BottomHoleTemperature) / 2
  356. KickFluxAvgCompressibility = 0.98
  357. GasKickSIDensity = KickFluxAvgPressure / (KickFluxAvgCompressibility * &
  358. KickFluxAvgTemperature * data%State%GasType(KickGasType)%GasConstant) * Convpcftogpcm3
  359. GasKickDensity = GasKickSIDensity * 8.3523
  360. !GasPocketWeight%Array(1) = GasKickDensity * 0.05 !KickmdotACoef * (KickmdotBCoef - GasPocketNewPress%Array(1)) * dt
  361. GasPocketWeight%Array(1) = GasKickDensity * MinKickVol !1.0:seyyed gofte !KickmdotACoef * (KickmdotBCoef - GasPocketNewPress%Array(1)) * dt
  362. GasPocketNewVol%Array(1) = GasPocketCompressibility%Array(1) * data%State%GasType(KickGasType)%GasConstant * &
  363. GasPocketNewTemp%Array(1) * GasPocketWeight%Array(1) / GasPocketNewPress%Array(1)
  364. GasPocketDeltaVol%Array(1) = 0.05 !GasPocketNewVol%Array(1)
  365. GasPocketFlowInduced%Array(1) = (GasPocketDeltaVol%Array(1)) / dt * 448.8 ! gpm
  366. GasKickPumpFlowRate = GasPocketFlowInduced%Array(1)
  367. WRITE (*,*) ' FormPressure , BottomHolePress' , FormPressure , BottomHolePress, GasKickDensity
  368. WRITE (*,*) ' No Press(psia) Vol(gal) Weight(lbm) Flow Induced(gpm)'
  369. DO i = 1 , NoGasPocket
  370. WRITE (*,102) i , GasPocketNewPress%Array(i), GasPocketNewVol%Array(i) * Convft3toUSgal, GasPocketWeight%Array(i), GasPocketFlowInduced%Array(i)
  371. END DO
  372. ELSE ! no new kick, so mass of 1st kick should increase
  373. GasPocketWeight%Array(1) = GasPocketweight%Array(1) + KickmdotACoef * (KickmdotBCoef - GasPocketNewPress%Array(1)) * dt
  374. GasKickPumpFlowRate = GasPocketFlowInduced%Array(1)
  375. IF (NoGasPocket > 1 .OR. SecondaryKickWeight > 0.0) THEN
  376. SecondaryKickWeight = SecondaryKickWeight + KickmdotACoef * (KickmdotBCoef - GasPocketNewPress%Array(1)) * dt
  377. SecondaryKickVol = SecondaryKickWeight / GasReservoirDensity / 42.0 ! 42 USGal = 1bbl
  378. END IF
  379. END IF
  380. END SUBROUTINE