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
30 KiB

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