SUBROUTINE PressureHorizAndStringDistribution
    
  
    !!      Record of revisions
    !!          Date            Programmer          Discription of change
    !!         ------          ------------        -----------------------
    !!        1396/07/30        Sheikh              Original code
    !! 
    
    USE FricPressDropVarsModule
    use PressureDisplayVARIABLESModule
    USE MudSystemVARIABLES
use SimulationVariables !@@@
    USE GeoElements_FluidModule
    USE Fluid_Flow_Startup_Vars
    use KickVARIABLESModule
    USE CMudPropertiesVariables
    use CDataDisplayConsole
    use SimulationVariables !, StandPipePressureDataDisplay=> data%EquipmentControl%ChokeControlPanel%StandPipePressure
    use CDataDisplayConsole
    use SimulationVariables !, CasingPressureDataDisplay=> CasingPressure
    use SimulationVariables !@
    USE CShoeVariables
    USE CDownHoleVariables! , OperationScenarioCommon%ElevatorConnection => DownHole%CasingPressure
    use SimulationVariables !@
    USE CManifolds
    use SimulationVariables
    USE CError
    use UTUBEVARSModule
    use OperationScenariosModule
    use SimulationVariables
    USE , INTRINSIC :: IEEE_ARITHMETIC
    Use TD_DrillStemComponents
    Use sROP_Variables
    

    
    IMPLICIT NONE
    
    INTEGER :: i , j , l
    INTEGER :: ifric
    INTEGER :: OldCasingPressure
    REAL :: PressBelowFloatValve , PressAboveFloatValve         ![psi]
    REAL :: PumpMinDischargedVol = 0.0050     ! [gal]
    REAL :: FloatValveBottomToUpAreaRatio = 1.1     ![-]
    REAL :: ZeroHeight , StaticHeadOnBit
    REAL(8) :: ShoeTVD
    !REAL(8) , DIMENSION(5) :: MDObserve , TVDObserve , StPressObserve , AnnPressObserve , NomMD
    
    KickVARIABLES%ExitMass = 0.0
    BitPressLoss = 0.0
    
    KickVARIABLES%WellHeadWasOpen = KickVARIABLES%WellHeadOpen
    KickVARIABLES%WellToChokeManifoldWasOpen = data%State%MudSystem%WellToChokeManifoldOpen
    KickVARIABLES%KickWasExitingThroughChoke = .FALSE.
    
    
    IF (data%State%MudSystem%UtubeMode1Activated .OR. data%State%FricPressDrop%FloatValveWasOpen == .FALSE.) THEN       ! Horizontal line flow rate
        FlowEl(1 : data%State%FricPressDrop%NoHorizontalEl)%FlowRate = 0.0
    ELSE        ! connection and line is open
        FlowEl(1 : data%State%FricPressDrop%NoHorizontalEl)%FlowRate = data%State%MudSystem%StringFlowRate   ! pump flow rate [gpm]
    END IF
    
    !WRITE (*,*) 'a)A/B P Bit', StaticHeadOnBit , FlowEl(AnnulusFirstEl)%StartPress , SUM(FlowEl(StringFirstEl : StringLastEl)%StaticPressDiff)
    !IF (FloatValveIn == .FALSE.)        FloatValveOpen = .TRUE.
    data%State%FricPressDrop%FloatValveWasOpen = data%State%FricPressDrop%FloatValveOpen
    
    PressBelowFloatValve = FlowEl(data%State%FricPressDrop%AnnulusFirstEl)%StartPress
    
    data%State%FricPressDrop%StMudVol = SUM(FlowEl(1 : data%State%FricPressDrop%StringLastEl)%Volume) * Convft3toUSGal
    data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility = 1.0 / (MudCompressibility * data%State%FricPressDrop%StMudVol)
    
    data%State%FricPressDrop%AnnMudVol = SUM(FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%Volume) * Convft3toUSGal
    
    IF ( (DownHole%KickVolume > 2.0) .or. (KickVARIABLES%NoGasPocket>1) .or. (any(FlowEl(data%State%FricPressDrop%OpenholeFirstEl:data%State%FricPressDrop%NumbEl)%Materialtype==1)) .or. (data%State%ROP_Bit%RateofPenetration > 0.0) ) THEN
        data%State%FricPressDrop%AnnCompressedMudVol = 0.0
        data%State%FricPressDrop%AnnDeltaPDueToCompressibility = 0.0
        
    ELSE IF (KickVARIABLES%WellHeadOpen) THEN
        data%State%FricPressDrop%AnnDeltaPtoDeltaVCompressibility = 1.0 / (MudCompressibility * data%State%FricPressDrop%AnnMudVol)
        
        data%State%FricPressDrop%AnnCompressedMudVol = data%State%FricPressDrop%BackPressure / data%State%FricPressDrop%AnnDeltaPtoDeltaVCompressibility
        data%State%FricPressDrop%AnnDeltaPDueToCompressibility = data%State%FricPressDrop%AnnCompressedMudVol / (MudCompressibility * data%State%FricPressDrop%AnnMudVol)
        
    ELSE        ! No gas pocket, wellhead is closed and mud is compressed based on volume pumped into annulus
        data%State%FricPressDrop%AnnDeltaPtoDeltaVCompressibility = 1.0 / (MudCompressibility * data%State%FricPressDrop%AnnMudVol)
        data%State%FricPressDrop%AnnCompressedMudVol = data%State%FricPressDrop%AnnCompressedMudVol + REAL(data%State%MudSystem%Ann_Saved_MudDischarged_Volume_Final)  !!!!!!!!!
        data%State%FricPressDrop%AnnCompressedMudVol = MAX((data%State%FricPressDrop%AnnCompressedMudVol - REAL(data%State%MudSystem%Qlost / ConvMinToSec / dt)) , 0.0)
        data%State%FricPressDrop%AnnDeltaPDueToCompressibility = data%State%FricPressDrop%AnnCompressedMudVol / (MudCompressibility * data%State%FricPressDrop%AnnMudVol)
    END IF    
    
    IF (data%State%FricPressDrop%FloatValveIn == .FALSE. .OR. KickVARIABLES%NoGasPocket == 0 .OR. (data%State%FricPressDrop%FloatValveWasOpen .AND. REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final) >= PumpMinDischargedVol)) THEN     ! float valve remains open
        data%State%FricPressDrop%FloatValveOpen = .TRUE.
        
        FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%FlowRate = REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final) / dt * ConvMinToSec       !data%State%MudSystem%StringFlowRate   ! String flow rate pump flow rate [gpm]
        
        !!!!!!!!!!!!!!! Calculating frictional pressure loss
        IF (KickVARIABLES%WellHeadOpen) THEN
            DO ifric = 1 , data%State%FricPressDrop%StringLastEl
                CALL FricPressDrop(ifric)
                !WRITE (*,*) ' element No, FlowRate , Density, FricPressLoss', ifric, FlowEl(ifric)%FlowRate, FlowEl(ifric)%Density, FlowEl(ifric)%FricPressLoss    
                IF (IEEE_IS_NaN(FlowEl(ifric)%FricPressLoss)) THEN
                    WRITE (*,*) 'Hz/St start, end, density, Q, mu, Type' , FlowEl(ifric)%StartX, FlowEl(ifric)%EndX, FlowEl(ifric)%Density, FlowEl(ifric)%FlowRate, FlowEl(ifric)%mueff, FlowEl(ifric)%MaterialType
                    CALL ErrorStop('NaN in calculating pressure drop' , ifric)
                END IF
            END DO
        END IF
        
        !!!!!!!!!!!!!!!        
   
        
        !IF (ABS(MudVolume_InjectedToBH - St_Saved_MudDischarged_Volume_Final)> PumpMinDischargedVol)   WRITE (*,*) 'Injected to BH & St Saved Mud', MudVolume_InjectedToBH , St_Saved_MudDischarged_Volume_Final
        IF (data%State%FricPressDrop%BitTotallyPluged) THEN
            data%State%MudSystem%MudVolume_InjectedToBH = 0.d0
            data%State%FricPressDrop%StCompressedMudVol = data%State%FricPressDrop%StCompressedMudVol + REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final)
            data%State%FricPressDrop%StDeltaPDueToCompressibility = data%State%FricPressDrop%StCompressedMudVol * data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility
            
        ELSE IF (KickVARIABLES%WellHeadOpen .OR. KickVARIABLES%NoGasPocket > 0) THEN
            IF (REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final) >= PumpMinDischargedVol) THEN
                
                data%State%MudSystem%MudVolume_InjectedToBH = data%State%MudSystem%St_Saved_MudDischarged_Volume_Final
                !WRITE (*,*) 'MudVolume_InjectedToBH,BitTrue', MudVolume_InjectedToBH
            
                !IF (BitTrue .AND. UtubeMode1Activated == .FALSE.) THEN
                IF (BitTrue) THEN
                    BitPressLoss = data%State%FricPressDrop%KBit * (data%State%MudSystem%MudVolume_InjectedToBH * ConvMinToSec / dt)**2
                    !WRITE (*,*) 'BitPressLoss', BitPressLoss
                END IF
            
                data%State%FricPressDrop%StCompressedMudVol = BitPressLoss / data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility
                
            ELSE
                data%State%MudSystem%MudVolume_InjectedToBH = MAX( 0.d0 , REAL((data%State%FricPressDrop%StDeltaPDueToCompressibility + SUM(FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%StaticPressDiff - PressBelowFloatValve - data%State%FricPressDrop%AnnDeltaPDueToCompressibility - FloatValveMinOpenPressure) &
                                                        / data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility ) * 1.d0))
                data%State%MudSystem%MudVolume_InjectedToBH = MIN(data%State%MudSystem%MudVolume_InjectedToBH , data%State%FricPressDrop%StCompressedMudVol)
                data%State%FricPressDrop%StCompressedMudVol = data%State%FricPressDrop%StCompressedMudVol - data%State%MudSystem%MudVolume_InjectedToBH
                
            END IF
            
            data%State%FricPressDrop%StDeltaPDueToCompressibility = data%State%FricPressDrop%StCompressedMudVol / (MudCompressibility * data%State%FricPressDrop%StMudVol)
        
        ELSE    ! IF (NoGasPocket == 0 .AND. WellHeadOpen == .FALSE.) THEN
            data%State%FricPressDrop%StCompressedMudVol = data%State%FricPressDrop%StCompressedMudVol + REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final)
            data%State%FricPressDrop%StDeltaPDueToCompressibility = data%State%FricPressDrop%StCompressedMudVol * data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility
            data%State%MudSystem%MudVolume_InjectedToBH = MAX( 0.d0 , REAL((data%State%FricPressDrop%StDeltaPDueToCompressibility - data%State%FricPressDrop%AnnDeltaPDueToCompressibility - FloatValveMinOpenPressure) &
                                                        / (data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility + data%State%FricPressDrop%AnnDeltaPtoDeltaVCompressibility)) * 1.d0)
            data%State%MudSystem%MudVolume_InjectedToBH = MIN(data%State%MudSystem%MudVolume_InjectedToBH , data%State%FricPressDrop%StCompressedMudVol)
            data%State%FricPressDrop%StCompressedMudVol = data%State%FricPressDrop%StCompressedMudVol - REAL(data%State%MudSystem%MudVolume_InjectedToBH)
            data%State%FricPressDrop%StDeltaPDueToCompressibility = data%State%FricPressDrop%StCompressedMudVol / (MudCompressibility * data%State%FricPressDrop%StMudVol)
            FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%StartPress = FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%StartPress + data%State%FricPressDrop%StDeltaPDueToCompressibility
            FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%EndPress = FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%EndPress + data%State%FricPressDrop%StDeltaPDueToCompressibility
            
        END IF
         
        FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress = FlowEl(data%State%FricPressDrop%AnnulusFirstEl)%StartPress + BitPressLoss + FloatValveMinOpenPressure
        !WRITE (*,*) 'BitPressLoss=', BitPressLoss
        FlowEl(data%State%FricPressDrop%StringLastEl)%StartPress = FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress + FlowEl(data%State%FricPressDrop%StringLastEl)%FricPressLoss - FlowEl(data%State%FricPressDrop%StringLastEl)%StaticPressDiff
        DO i = data%State%FricPressDrop%StringLastEl - 1 , data%State%FricPressDrop%StringFirstEl , -1
            FlowEl(i)%EndPress = FlowEl(i + 1)%StartPress
            FlowEl(i)%StartPress = FlowEl(i)%EndPress + FlowEl(i)%FricPressLoss - FlowEl(i)%StaticPressDiff
        END DO
        
        !!!!!!!!!!!!!!!!!!!!!!!!!!!! Float valve was open and remains open
        
    ELSE IF (REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final) < PumpMinDischargedVol) THEN     ! NoGasPocket > 0
        data%State%FricPressDrop%FloatValveOpen = data%State%FricPressDrop%FloatValveWasOpen      ! remains in its former status
        
        IF (data%State%FricPressDrop%FloatValveOpen) THEN
            PressAboveFloatValve = MAX(FlowEl(data%State%FricPressDrop%AnnulusFirstEl)%StartPress , SUM(FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%StaticPressDiff) + 0.052 * FlowEl(data%State%FricPressDrop%StringFirstEl)%Density * FlowEl(data%State%FricPressDrop%StringFirstEl)%StartTVD)
        ELSE
            PressAboveFloatValve = SUM(FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%StaticPressDiff) + data%State%FricPressDrop%StDeltaPDueToCompressibility
            data%State%MudSystem%MudVolume_InjectedToBH = 0.d0
        END IF
        
        
        IF (PressBelowFloatValve >= PressAboveFloatValve .AND. KickVARIABLES%KickFlux) THEN       
            data%State%FricPressDrop%FloatValveOpen = .FALSE.
            IF (data%State%FricPressDrop%FloatValveOpen /= data%State%FricPressDrop%FloatValveWasOpen) THEN           ! float valve was open and now closed
                WRITE (*,*) 'Float valve was open and now closed'
                WRITE (*,*) 'PressAboveFloatValve=', PressAboveFloatValve
                WRITE (*,*) 'PressBelowFloatValve=', PressBelowFloatValve
            END IF
            
        END IF
        
        IF (data%State%FricPressDrop%FloatValveOpen) THEN
            data%State%MudSystem%MudVolume_InjectedToBH = MAX( 0.d0 , 0.1 * REAL((PressAboveFloatValve - PressBelowFloatValve - data%State%FricPressDrop%AnnDeltaPDueToCompressibility - FloatValveMinOpenPressure) &
                                                        / data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility ) * 1.d0)
            data%State%MudSystem%MudVolume_InjectedToBH = MIN(data%State%MudSystem%MudVolume_InjectedToBH , data%State%FricPressDrop%StCompressedMudVol)
            !WRITE (*,*) 'MudVolume_InjectedToBH (No Pump)', MudVolume_InjectedToBH
            
            data%State%FricPressDrop%StCompressedMudVol = data%State%FricPressDrop%StCompressedMudVol - data%State%MudSystem%MudVolume_InjectedToBH
            data%State%FricPressDrop%StDeltaPDueToCompressibility = data%State%FricPressDrop%StCompressedMudVol / (MudCompressibility * data%State%FricPressDrop%StMudVol)
            !WRITE (*,*) 'StDeltaPDueToCompressibility(No Pump)', StDeltaPDueToCompressibility
            
        END IF
        
        IF (KickVARIABLES%NoGasPocket == 0 .AND. KickVARIABLES%WellHeadOpen == .FALSE.) THEN  !***********
            FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%StartPress = FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%StartPress + data%State%FricPressDrop%AnnDeltaPDueToCompressibility
            FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%EndPress = FlowEl(data%State%FricPressDrop%AnnulusFirstEl : data%State%FricPressDrop%NumbEl)%EndPress + data%State%FricPressDrop%AnnDeltaPDueToCompressibility
        END IF
        
        
        
        IF (data%State%FricPressDrop%FloatValveOpen) THEN
            FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress = MAX(FlowEl(data%State%FricPressDrop%AnnulusFirstEl)%StartPress , SUM(FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%StaticPressDiff) + 0.052 * FlowEl(data%State%FricPressDrop%StringFirstEl)%Density * FlowEl(data%State%FricPressDrop%StringFirstEl)%StartTVD)
        ELSE
            FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress = data%State%FricPressDrop%StDeltaPDueToCompressibility + SUM(FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%StaticPressDiff)
        END IF
            
        FlowEl(data%State%FricPressDrop%StringLastEl)%StartPress = FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress - FlowEl(data%State%FricPressDrop%StringLastEl)%StaticPressDiff
        DO i = data%State%FricPressDrop%StringLastEl - 1 , data%State%FricPressDrop%StringFirstEl , -1
            FlowEl(i)%EndPress = FlowEl(i + 1)%StartPress
            FlowEl(i)%StartPress = FlowEl(i)%EndPress + FlowEl(i)%FricPressLoss - FlowEl(i)%StaticPressDiff
        END DO
        
        
        
        !!!!!!!!!!!!!!!!!!!!!!!!!!!! Float valve was open (close) and maybe remains open (close) or maybe closed
        
    ELSE IF(data%State%FricPressDrop%FloatValveWasOpen == .FALSE. .AND. REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final) >= PumpMinDischargedVol) THEN
        data%State%FricPressDrop%FloatValveOpen = .FALSE.
        data%State%MudSystem%MudVolume_InjectedToBH = 0.d0
        
        data%State%FricPressDrop%StCompressedMudVol = data%State%FricPressDrop%StCompressedMudVol + REAL(data%State%MudSystem%St_Saved_MudDischarged_Volume_Final)
        data%State%FricPressDrop%StDeltaPDueToCompressibility = data%State%FricPressDrop%StCompressedMudVol * data%State%FricPressDrop%StDeltaPtoDeltaVCompressibility
        PressAboveFloatValve = SUM(FlowEl(data%State%FricPressDrop%StringFirstEl : data%State%FricPressDrop%StringLastEl)%StaticPressDiff) + data%State%FricPressDrop%StDeltaPDueToCompressibility

        
        IF (PressAboveFloatValve > FloatValveBottomToUpAreaRatio * PressBelowFloatValve) THEN       ! float valve was open and now closed
            data%State%FricPressDrop%FloatValveOpen = .TRUE.
            WRITE (*,*) 'Float valve was closed and now opened'
            WRITE (*,*) 'PressAboveFloatValve=', PressAboveFloatValve
            WRITE (*,*) 'PressBelowFloatValve=', PressBelowFloatValve
        END IF
        
            
        FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress = PressAboveFloatValve
        FlowEl(data%State%FricPressDrop%StringLastEl)%StartPress = FlowEl(data%State%FricPressDrop%StringLastEl)%EndPress - FlowEl(data%State%FricPressDrop%StringLastEl)%StaticPressDiff
        DO i = data%State%FricPressDrop%StringLastEl - 1 , data%State%FricPressDrop%StringFirstEl , -1
            FlowEl(i)%EndPress = FlowEl(i + 1)%StartPress
            FlowEl(i)%StartPress = FlowEl(i)%EndPress - FlowEl(i)%StaticPressDiff
            !WRITE(*,*) "STRING: Start , End Pressure", FlowEl(i)%StartPress , FlowEl(i)%EndPress
            !WRITE(*,*) "STRING: Start , End X", FlowEl(i)%StartX , FlowEl(i)%EndX
        END DO
        
        
        
  
    END IF
    
    IF ((data%State%MudSystem%UtubePossibility == .TRUE. .AND. Get_KellyConnection() /= KELLY_CONNECTION_STRING) .OR. data%State%MudSystem%NewPipeFilling == 0) THEN
        FlowEl(data%State%FricPressDrop%NoHorizontalEl)%EndPress = 0.0
    ELSE IF (KickVARIABLES%WellHeadOpen == .FALSE.) THEN
        FlowEl(data%State%FricPressDrop%NoHorizontalEl)%EndPress = FlowEl(data%State%FricPressDrop%StringFirstEl)%StartPress - 0.052 * FlowEl(data%State%FricPressDrop%NoHorizontalEl)%Density * FlowEl(data%State%FricPressDrop%StringFirstEl)%StartTVD
    ELSE IF (KickVARIABLES%WellHeadOpen) THEN
        FlowEl(data%State%FricPressDrop%NoHorizontalEl)%EndPress = FlowEl(data%State%FricPressDrop%StringFirstEl)%StartPress - 2.0 * 0.052 * FlowEl(data%State%FricPressDrop%NoHorizontalEl)%Density * FlowEl(data%State%FricPressDrop%StringFirstEl)%StartTVD
    END IF
    
    FlowEl(data%State%FricPressDrop%NoHorizontalEl)%StartPress = FlowEl(data%State%FricPressDrop%NoHorizontalEl)%EndPress + FlowEl(data%State%FricPressDrop%NoHorizontalEl)%FricPressLoss
    DO i = data%State%FricPressDrop%NoHorizontalEl - 1 , 1 , -1
        FlowEl(i)%EndPress = FlowEl(i + 1)%StartPress
        FlowEl(i)%StartPress = FlowEl(i)%EndPress + FlowEl(i)%FricPressLoss
    END DO
        
    
    
!!!!!!!!!!!!!!!!!!!!! Pressure distribution in string and horizontal pump to string line
    
        
    IF (data%State%RamLine%ShearBop_Situation_forTD == 1) THEN
        FlowEl(1 : data%State%FricPressDrop%NoHorizontalEl)%EndPress = 0.0
        FlowEl(1 : data%State%FricPressDrop%NoHorizontalEl)%StartPress = 0.0
        FlowEl(1 : data%State%FricPressDrop%NoHorizontalEl)%FricPressLoss = 0.0
    END IF
        
!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    
    
    
    

    IF (data%State%MudSystem%UtubePossibility== .true. .and. Get_KellyConnection() /= KELLY_CONNECTION_STRING .and. KickVARIABLES%WellHeadOpen) THEN
        data%State%MudSystem%MudVolume_InjectedToBH = 0.d0
        data%State%MudSystem%MudVolume_InjectedFromAnn = 0.d0
        
    END IF
    
  
                                                               
110     FORMAT (I6 , 4X , F6.2 , 7X , F4.2 , 3X , F4.1 , 2X , F4.2)
            
                
            
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            !!!!    Kick Information Reports
    
 
!!!!!!!!!!!!!!!!! 1- Stand pipe pressure gauge      PressureGauges(1)
    
    !ElementTrueDepth = STpipeGauge_Height/Convfttom
    !DistancetoRefrence = -170.7       ! 165 ft after pump and 100 ft before string
    i = 1
    DO WHILE (NOT(FlowEl(i)%EndX >= -170 .AND. FlowEl(i)%StartX <= -170))
        i = i + 1
        IF (i > data%State%FricPressDrop%NoHorizontalEl) EXIT
    END DO
    CALL PumpPressureDelay%AddToFirst(REAL(FlowEl(i)%StartPress - 0.052 * (data%State%MudSystem%STpipeGauge_Height / Convfttom) * FlowEl(i)%Density + (FlowEl(i)%StartX + 170) * FlowEl(i)%dPdLFric))
    CALL PumpPressureDelay%Remove(data%State%PressureDisplay%PressureTimeStepDelay(1) + 1)
    !IF (ANY(data%State%Pump(:)%PowerFailMalf == 1))    PumpPressureDelay%Array(1 : PressureTimeStepDelay(1) / 2) = 0.0   !seyyed goft vaghti pumpfailure mishavad feshar dasti 0 nashavad, be in dalil in khat comment shod.
     
    DO j = data%State%PressureDisplay%PressureTimeStepDelay(1) , 1 , -1
        IF (NOT(IEEE_IS_NaN(PumpPressureDelay%Array(j)))) THEN
            data%State%PressureDisplay%PressureGauges(1) = INT(PumpPressureDelay%Array(j))
            EXIT
        END IF
    END DO
    
    !PressureGauges(1) = INT(PumpPressureDelay%Array(PressureTimeStepDelay(1)))
    
    IF (i > data%State%FricPressDrop%NoHorizontalEl) THEN
        WRITE (*,*) ' Error in calculating standpipe pressure '
    END IF
    
    IF (data%State%PressureDisplay%PressureGauges(1) < 0) THEN
        !CALL Set_StandPipePressure(real(PressureGauges(1) , 8))    ! for display console
        data%State%PressureDisplay%PressureGauges(1) = 0.0
        !CALL Set_StandPipePressure(0.0d0)   !StandPipePressureGauge = 0
    END IF
    DownHole%DrillPipePressure = real(data%State%PressureDisplay%PressureGauges(1), 8)
    !WRITE (*,*) 'Drillpipe Pressure', PressureGauges(1)
    
!!!!!!!!!!!!!!!!! 2- Casing pressure gauge      PressureGauge(2)
    !WRITE (*,*) 'here 1', (WelltoPitsOpen == .FALSE. .AND. WellToChokeManifoldOpen) , (Valve(26)%Status == .TRUE. .AND. Valve(47)%Status == .TRUE. .AND. Valve(49)%Status == .TRUE.), BackPressure
    !WRITE (*,*) Valve(26)%Status , Valve(47)%Status , Valve(49)%Status
    !WRITE (*,*) (Valve(26)%Status == .TRUE.) , (Valve(47)%Status == .TRUE.) , (Valve(49)%Status == .TRUE.)
    
    !!! in normal mode changes in choke position immidiately observes in casing pressure
    !!      but when pumps off due to failure, casing pressure will drop after a delay time
    IF (data%State%MudSystem%WellToChokeManifoldOpen .OR. data%State%MudSystem%WellToChokeLineGauge) THEN
        !WRITE (*,*) 'Here 1'
        CALL CasingPressureDelay%AddToFirst(FlowEl(data%State%FricPressDrop%NoHorizontalEl + data%State%FricPressDrop%NoStringEl + data%State%FricPressDrop%NoAnnulusEl + data%State%FricPressDrop%NoWellToChokeEl)%EndPress)
        CALL CasingPressureDelay%Remove(data%State%PressureDisplay%PressureTimeStepDelay(1) + 1)
        
        DO j = 1 , data%State%PressureDisplay%PressureTimeStepDelay(1)
            IF (NOT(IEEE_IS_NaN(CasingPressureDelay%Array(j)))) THEN
                data%State%PressureDisplay%PressureGauges(2) = INT(CasingPressureDelay%Array(j))
                EXIT
            END IF
        END DO
        
        !PressureGauges(2) = INT(CasingPressureDelay%Array(1))
        IF (ANY(data%State%Pump(:)%PowerFailMalf == 1)) THEN
            DO j = data%State%PressureDisplay%PressureTimeStepDelay(1) , 1 , -1
                IF (NOT(IEEE_IS_NaN(CasingPressureDelay%Array(j)))) THEN
                    data%State%PressureDisplay%PressureGauges(2) = INT(CasingPressureDelay%Array(j))
                    EXIT
                END IF
            END DO
        END IF
        
        
        
        
        !IF (ANY(data%State%Pump(:)%PowerFailMalf == 1))    PressureGauges(2) = INT(CasingPressureDelay%Array(PressureTimeStepDelay(1)))
   
    ELSE !IF (ChokeLineGaugeToTanks) THEN
        data%State%PressureDisplay%PressureGauges(2) = 0
        !WRITE (*,*) 'Here 2'
    END IF

    
    !WRITE (*,*) 'GaugePoint(2)%Pressure =' , GaugePoint(2)%Pressure
    !IF (PressureGauges(2) < 0) THEN
    !    PressureGauges(2) = 0.0
    !END IF
    CALL Set_CasingPressure(real(data%State%PressureDisplay%PressureGauges(2) , 8))    ! for display console
    Downhole%CasingPressure = real(data%State%PressureDisplay%PressureGauges(2) , 8)

!!!!!!!!!!!!!!!!! 3- Bottom Hole Pressure       PressureGauge(3)
    
    CALL BottomHolePressureDelay%AddToFirst(FlowEl(data%State%FricPressDrop%OpenholeFirstEl)%StartPress)
    CALL BottomHolePressureDelay%Remove(data%State%PressureDisplay%PressureTimeStepDelay(2) + 1)
    !PressureGauges(3) = INT(BottomHolePressureDelay%Array(PressureTimeStepDelay(2)))

    DO j = data%State%PressureDisplay%PressureTimeStepDelay(2) , 1 , -1
        IF (NOT(IEEE_IS_NaN(BottomHolePressureDelay%Array(j)))) THEN
            data%State%PressureDisplay%PressureGauges(3) = INT(BottomHolePressureDelay%Array(j))
            EXIT
        END IF
    END DO
    
    
    KickVARIABLES%BottomHolePress = BottomHolePressureDelay%Array(data%State%PressureDisplay%PressureTimeStepDelay(2))
    
    DownHole%BottomHolePressure = REAL(data%State%PressureDisplay%PressureGauges(3) , 8)
!!!!!!!!!!!!!!!!! 4- Under Bit Pressure     PressureGauges(4)
        
    data%State%PressureDisplay%PressureGauges(4) = FlowEl(data%State%FricPressDrop%AnnulusFirstEl)%StartPress
    
!!!!!!!!!!!!!!!!!
    
    
!!!!!!!!!!!!!!!!! 5- Casing Shoe Pressure       PressureGauges(5)

        DO ShoeFlowElNo = data%State%FricPressDrop%AnnulusFirstEl , data%State%FricPressDrop%NumbEl
            IF (FlowEl(ShoeFlowElNo)%StartX >= Shoe%ShoeDepth .AND. FlowEl(ShoeFlowElNo)%EndX < Shoe%ShoeDepth) EXIT
        END DO
        CALL TVD_Calculator(Shoe%ShoeDepth , ShoeTVD)
        
        IF (ShoeFlowElNo > data%State%FricPressDrop%NumbEl) THEN
            WRITE (*,*) 'ShoeDepth =', Shoe%ShoeDepth
            DO i = data%State%FricPressDrop%AnnulusFirstEl , data%State%FricPressDrop%NumbEl
                WRITE (*,*) 'i, StartX, EndX', i, FlowEl(i)%StartX, FlowEl(i)%EndX
            END DO
            
            CALL ErrorSTOP ('Error in finding location of shoe')
        END IF
        
    !ELSE
       ! WRITE (*,*) ' Error in calculating shoe pressure '
    !END IF
    
    CALL ShoePressureDelay%AddToFirst(REAL(FlowEl(ShoeFlowElNo)%StartPress &
                                        - (FlowEl(ShoeFlowElNo)%StartX - Shoe%ShoeDepth) * FlowEl(ShoeFlowElNo)%dPdLfric &
                                        - (FlowEl(ShoeFlowElNo)%StartTVD - ShoeTVD) * FlowEl(ShoeFlowElNo)%dPdLGrav))
    CALL ShoePressureDelay%Remove(data%State%PressureDisplay%PressureTimeStepDelay(3) + 1)
    
    !data%State%FricPressDrop%FlowrateNearShoe = FlowEl(ShoeFlowElNo)%FlowRate
    DO j = data%State%PressureDisplay%PressureTimeStepDelay(3) , 1 , -1
        IF (NOT(IEEE_IS_NaN(ShoePressureDelay%Array(j)))) THEN
            data%State%PressureDisplay%PressureGauges(5) = INT(ShoePressureDelay%Array(j))
            EXIT
        END IF
    END DO
    
    
    !PressureGauges(5) = INT(ShoePressureDelay%Array(PressureTimeStepDelay(3)))
    DownHole%ShoePressure = real(data%State%PressureDisplay%PressureGauges(5), 8)
        
    
    
    
    data%State%MudSystem%ShoeMudViscosity = FlowEl(ShoeFlowElNo)%MuEff
    data%State%MudSystem%ShoeMudDensity = FlowEl(ShoeFlowElNo)%Density
    
    
    
    
    
!!!!!!!!!!!!!!!!!
    
!!!!!!!!! 6- Pressure Before Bop 
    
    data%State%PressureDisplay%PressureGauges(6) = FlowEl(data%State%FricPressDrop%NoHorizontalEl + data%State%FricPressDrop%NoStringEl + data%State%FricPressDrop%NoAnnulusEl)%EndPress
    
!!!!!!!!!!!!!!!!!
101 FORMAT(4X, I2, 8X, (F8.1), 12X, (F8.3), 7X, (F8.2))
    
    
    IF (KickVARIABLES%ChokeKroneckerDelta == 1) THEN
    END IF
    

    
    !WRITE (*,*) 'Horiz 1'
    
    KickVARIABLES%KickInFluxConditions = (Reservoir%FormationTop < data%State%TD_WellGeneral%WellTotalVerticalLength) .AND. (NOT(Reservoir%InactiveInflux)) .AND. (KickVARIABLES%FormPressure > KickVARIABLES%BottomHolePress + 5.0)
    IF (KickVARIABLES%KickInFluxConditions) THEN
        KickVARIABLES%KickFlux = .TRUE.

        CALL NewGasKick
        
        !WRITE (*,*) 'Kick Flux top' , KickFlux
        !WRITE (*,*) 'KickVARIABLES%FormPressure, BottomHolePress, FormationTop, data%State%TD_WellGeneral%WellTotalVerticalLength' , FormPressure, BottomHolePress, FormationTop, data%State%TD_WellGeneral%WellTotalVerticalLength
        
    ELSE
        IF (ALLOCATED(GasPocketWeight%Array) .AND. KickVARIABLES%KickFlux) THEN
            KickVARIABLES%KickOffBottom = .TRUE.
            WRITE (*,*) 'Kick Off Bottom'
            WRITE (*,*) 'FormPressure , BottomHolePress' , KickVARIABLES%FormPressure , KickVARIABLES%BottomHolePress
            !WRITE (*,*) 'No  Press(psia)  Vol(gal)  Weight(lbm)  Flow Induced(gpm)  Flow El Press(psia)'                                                                                                
            DO i = 1 , KickVARIABLES%NoGasPocket
                WRITE (*,102) i , GasPocketNewPress%Array(i), GasPocketNewVol%Array(i) * Convft3toUSgal, GasPocketWeight%Array(i), GasPocketFlowInduced%Array(i), FlowEl(KickVARIABLES%GasPocketFlowEl(i , 1))%StartPress + StandardPress
            END DO
        END IF
        KickVARIABLES%KickFlux = .FALSE.
    END IF
    
    IF (ALLOCATED(KickVARIABLES%KickJacobian))        KickVARIABLES%OldKickJacobian = KickVARIABLES%KickJacobian
    
102 FORMAT (I2, 3X, (F8.1), 2X, (F8.2), 2X, (F8.3), 8X, (F8.2), 10X, (F8.1))
    
    !!!!!!!!  Auto Choke Procedure
    ! DO i = 1 , 5
    !   AreaChange = -1.0 * (BottomHolePressure - (KickVARIABLES%FormPressure + BHPSafetyMargin)) / FlowEl(OpenholeFirstEl - 1)%Flowrare**2 * 89158.0 &
    !                       * (0.26 * 0.61)**2 * TotalOpenChokeArea**3 / (4.0 * KickVARIABLES%ChokeDensity)
    !   data%State%CHOOKE(1)%AreaChokeFinal = data%State%CHOOKE(1)%AreaChokeFinal + AreaChange / * Convfttoinch**2
    !
    !
    !
    ! END DO
    !
    !
    !
    !
    !
    
    
    !WRITE (*,*) ' SecondaryKickWeight', KickVARIABLES%SecondaryKickWeight
    !WRITE (*,*) ' SecondaryKickVol', KickVARIABLES%SecondaryKickVol
    DownHole%SecondKickVolume = KickVARIABLES%SecondaryKickVol
    
    
    
    IF (KickVARIABLES%WellHeadOpen == .FALSE. .OR. (FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Flowrate < PressFlowrateTolerance .AND. FlowEl(data%State%FricPressDrop%AnnulusLastEl)%Flowrate < PressFlowrateTolerance)) THEN
        data%State%FricPressDrop%OnShakerDensity = 0.0
    ELSE IF (FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%MaterialType == 1 .AND. KickVARIABLES%ChokeKroneckerDelta == 1) THEN
        data%State%FricPressDrop%OnShakerDensity = 2.0
    ELSE IF (KickVARIABLES%ChokeKroneckerDelta == 0) THEN
        data%State%FricPressDrop%OnShakerDensity = FlowEl(data%State%FricPressDrop%AnnulusLastEl)%Density
    ELSE IF (KickVARIABLES%ChokeKroneckerDelta == 1) THEN  !!!(FlowEl(OpenholeFirstEl - 1)%Flowrate > PressFlowrateTolerance .AND. FlowEl(AnnulusLastEl)%Flowrate < PressFlowrateTolerance) THEN
        data%State%FricPressDrop%OnShakerDensity = FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Density
    ELSE
        data%State%FricPressDrop%OnShakerDensity = (FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Density * FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Flowrate &
                        + FlowEl(data%State%FricPressDrop%AnnulusLastEl)%Density * FlowEl(data%State%FricPressDrop%AnnulusLastEl)%Flowrate) / (FlowEl(data%State%FricPressDrop%OpenholeFirstEl - 1)%Flowrate + FlowEl(data%State%FricPressDrop%AnnulusLastEl)%Flowrate)
    END IF
    !WRITE (*,*) 'ANINT(OnShakerDensity * 100) / 100', ANINT(OnShakerDensity * 100) / 100 , OnShakerDensity
    CALL Set_MudWeightOut(ANINT(data%State%FricPressDrop%OnShakerDensity * 100) / 100)

    
    IF (ALLOCATED(FinalFlowEl))     DEALLOCATE(FinalFlowEl)
    ALLOCATE(FinalFlowEl(data%State%FricPressDrop%NumbEl))
    
    FinalFlowEl(:)%StartX = FlowEl(:)%StartX
    FinalFlowEl(:)%EndX = FlowEl(:)%EndX
    FinalFlowEl(:)%StartTVD = FlowEl(:)%StartTVD
    FinalFlowEl(:)%EndTVD = FlowEl(:)%EndTVD
    FinalFlowEl(:)%Length = FlowEl(:)%Length
    FinalFlowEl(:)%DepthDiff = FlowEl(:)%DepthDiff
    FinalFlowEl(:)%density = FlowEl(:)%density
    FinalFlowEl(:)%StartPress = FlowEl(:)%StartPress
    FinalFlowEl(:)%EndPress = FlowEl(:)%EndPress
    FinalFlowEl(:)%dPdLFric = FlowEl(:)%dPdLFric
    FinalFlowEl(:)%dPdLGrav = FlowEl(:)%dPdLGrav


    
    
    END SUBROUTINE
        
    
    
SUBROUTINE SOLVE_LINEAR_EQUATIONS(A , x , b , error, dim)
    
    !!! This subroutine solves a linear systems of equations Ax=b
    !! if vaiable erorr changed its value to .FALSE. means that the system of equations cab not be solved
    !! I use this subroutine to solve the linearized equations which uprising in calculation of volume and pressure of gas kick pockets
    
    use KickVARIABLESModule

    IMPLICIT NONE
    INTEGER , INTENT(IN) :: dim
    REAL(8) , DIMENSION(dim,dim) , INTENT(in) :: A
    REAL , DIMENSION(dim) , INTENT(OUT) :: x
    REAL(8) , DIMENSION(dim) , INTENT(in) :: b
    LOGICAL , INTENT(OUT) :: error
    REAL(8) , DIMENSION(:,:) , ALLOCATABLE :: m
    INTEGER , DIMENSION(1) :: max_loc
    REAL(8) , DIMENSION(:) , ALLOCATABLE :: temp_row
    INTEGER :: n , k
    
    !WRITE (*,*) 'SIZE(A , dim = 1), SIZE(A , dim = 2), SIZE(b)', SIZE(A , dim = 1), SIZE(A , dim = 2), SIZE(b)
    error = (SIZE(A , dim = 1) /= SIZE(b)) .OR. (SIZE(A , dim = 2) /= SIZE(b))
    !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 1' , error
    
    IF (error) THEN
        x = 0.0d0
        RETURN
    END IF
    n = SIZE(b)
    
    ALLOCATE (m(n , n + 1) , temp_row(n + 1))
    m(1:n , 1:n) = A
    m(1:n , n + 1) = b
    !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 2' , m
    ! Triangularization phase
    TRIANG_LOOP: DO k = 1 , n
        max_loc = MAXLOC(ABS(m(k:n , k)))
        temp_row(k:n + 1) = m(k , k:n + 1)
        m(k , k:n+1) = m(k-1+max_loc(1) , k:n+1)
        m(k - 1 + max_loc(1) , k:n + 1) = temp_row(k:n + 1)
        !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 3' , max_loc
        
        IF (m(k , k) == 0) THEN
            error = .TRUE.
            !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 4'
            EXIT TRIANG_LOOP
        ELSE
            !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 5'
            m(k , k : n + 1) = m(k , k : n + 1) / m(k , k)
            m(k + 1 : n , k + 1 : n + 1) = m(k + 1 : n , k + 1 : n + 1) - SPREAD(m(k , k + 1:n + 1) , 1, n - k) * SPREAD(m(k + 1:n , k) , 2 , n - k + 1)
        END IF
    END DO TRIANG_LOOP
    !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 6'
    
    ! Back substitution phase
    IF (error) THEN
        x = 0.0
    ELSE
        DO k = n , 1 , -1
            x(k) = REAL(m(k , n + 1) - SUM(m(k , k + 1 : n) * x(k + 1 : n)))
            !WRITE (*,*) 'SOLVE_LINEAR_EQUATIONS 7'
        END DO
    END IF
    
    DEALLOCATE(m , temp_row)
    
END SUBROUTINE solve_linear_equations
    