subroutine ROP_MainCalculation
    use SimulationVariables
    use sROP_Other_Variables
    use sROP_Variables
    use CStringConfigurationVariables
    use CformationVariables
    ! use CSimulationVariables
    use CDataDisplayConsole
    use SimulationVariables
    use CDrillingConsoleVariables
    use SimulationVariables
    use SimulationVariables
    use CmudPropertiesVariables
    use CHoistingVariables
    use SimulationVariables
    ! use CDrillingConsole
    use SimulationVariables !@
    use SimulationVariables !@, only: RTable
    use TD_DrillStemComponents
    use SimulationVariables !@
    use PressureDisplayVARIABLESModule
    USE MudSystemVARIABLES
use SimulationVariables !@@@
    USE FricPressDropVarsModule
    use CReservoirVariables
    use CWarnings
    ! use ConfigurationVariables, only: TDS
    use SimulationVariables !@
    
    implicit none
    
    Integer :: i , zero_ROPcount
    !Real(8) :: data%State%ROP_Bit%SetROPGauge
    
    zero_ROPcount = 0
    data%State%ROP_Bit%NoOfFormations = data%Configuration%Formation%Count
    data%State%ROP_Bit%DrillingVerticalDepth = data%State%TD_WellGeneral%WellTotalVerticalLength
    
    
    
   !===> MaximumWellDepthExceeded Warning
    if ( data%State%ROP_Bit%DrillingVerticalDepth>=(data%Configuration%Formation%Formations(data%Configuration%Formation%Count)%Top+data%Configuration%Formation%Formations(data%Configuration%Formation%Count)%Thickness) ) then
        data%State%ROP_Bit%RateOfPenetration = 0.0d0
        Call Set_ROP(data%State%ROP_Bit%RateOfPenetration)
        Call Activate_MaximumWellDepthExceeded()
        return
    end if
   !=====================================
    
    
    
    if ( data%State%ROP_Spec%FormationNumber/=0 .and. data%EquipmentControl%DrillingConsole%HideDrillingBrake==1 ) then      ! Hide Drilling Brake Mode
        data%State%ROP_Spec%FormationNumber = data%State%ROP_Spec%FormationNumber
    else
        do i= 1,data%State%ROP_Bit%NoOfFormations   
            data%State%ROP_Spec%FormationTopDepth = data%Configuration%Formation%Formations(i)%Top
            if (data%State%ROP_Bit%DrillingVerticalDepth>=data%State%ROP_Spec%FormationTopDepth) then    
                data%State%ROP_Spec%FormationNumber = i   
            end if
        end do
    end if
    
    
    
    
    !!===> Hide Drilling Brake Mode
    !if ( data%State%ROP_Spec%FormationNumber==FormationNo .and. HideDrillingBrake==1 ) then  !????????????
    !    data%State%ROP_Spec%FormationNumber = FormationNo-1
    !end if
    !!=============================
    
    
    
    
    !data%State%ROP_Spec%BitClass = BitDefinition%BitCode     !????????????
    call Bit_Specification
    
    
    
    
    ! $$$$$**$$$$$**$$$$$**$$$$$**$$$$$**     Variables Initialization:    *$$$$$**$$$$$**$$$$$**$$$$$**$$$$$  
    data%State%ROP_Spec%DiameterOfBit        =  data%Configuration%StringConfiguration%BitDefinition%BitSize          ! unit : [in.] (Typical Range: 3.0 to 30.0)
    data%State%ROP_Spec%NumberOfBitNozzles   =  data%Configuration%StringConfiguration%BitDefinition%BitNozzleNo      ! (Typical Values: 1 to 10)
    data%State%ROP_Spec%DiameterOfBitNozzle  =  data%Configuration%StringConfiguration%BitDefinition%BitNozzleSize    ! unit : [inch] *** basic input: [1/32 in.] (Typical Range: 8.0 to 32.0)
    data%State%ROP_Spec%CriticalMudDensity   =  data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%PorePressureGradient/.465d0*9.d0      ! ????????? delete ,unit : [ppg] or [lb/gal] (Typical Range: 0 to 10.0)
    data%State%ROP_Bit%FormationMudDensity   =  data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%PorePressureGradient/0.052d0
    data%State%ROP_Bit%BottomHolePressure    =  data%State%PressureDisplay%PressureGauges(3)              !5200 [psi]
    data%State%ROP_Bit%ECD                   =  data%State%ROP_Bit%BottomHolePressure/(0.052*data%State%ROP_Bit%DrillingVerticalDepth)
    data%State%ROP_Spec%CriticalWeightOnBit  =  (data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%ThresholdWeight/5.d0)-(.06d0*(data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%ThresholdWeight-10.d0))      ! unit : [klb/in] (Typical Range: 0 to 10 ----> 0.6 to 2)
    !IF (ALLOCATED(FlowEl)) THEN
    !    data%State%ROP_Bit%MudViscosity     =  FlowEl(NoHorizontalEl + NoStringEl)%mueff     !13.5  [cP]
        data%State%ROP_Bit%MudDensity        = data%State%MudSystem%BitMudDensity ! [ppg]
    !ELSE
        data%State%ROP_Bit%MudViscosity      =  13.5         ! [cP]
        !data%State%ROP_Bit%MudDensity       =  9.2          ! [ppg]
    !END IF
    data%State%ROP_Bit%MudFlowrate           =  data%State%MudSystem%StringFlowRateFinal    ! [gpm]
    data%State%ROP_Spec%ReynoldsNumber        =  data%State%ROP_Bit%MudFlowrate*data%State%ROP_Bit%MudDensity/(data%State%ROP_Bit%MudViscosity*data%State%ROP_Spec%NumberOfBitNozzles*data%State%ROP_Spec%DiameterOfBitNozzle)           ! unit : [dimensionless] (Typical Range: 0.1 to 1000.0)    
    ! $$$$$**$$$$$**$$$$$**$$$$$**$$$$    End of Variable Initialization    $$$$$**$$$$$**$$$$$**$$$$$**$$$$$
    
    
    
    
    
    ! -----**-----**-----**-----**-----*      data%State%ROP_Bit%RateofPenetration Model Coefficients:     *-----**-----**-----**-----**-----
    data%State%ROP_Spec%a1 = log(data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%Drillablity) 
    data%State%ROP_Spec%a2 = 1.2799d-04
    data%State%ROP_Spec%a3 = 1.7952d-04
    data%State%ROP_Spec%a4 = 4.0656d-05
    data%State%ROP_Spec%a5 = 2.9021d-01
    data%State%ROP_Spec%a6 = 9.4882d-02
    data%State%ROP_Spec%a7 = 2.1837d-01
    data%State%ROP_Spec%a8 = 4.4915d-01
    data%State%ROP_Spec%dt = 0.1d0   ![s]
    data%State%ROP_Spec%TouH = data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%Abrasiveness*3600.d0    ! [hr]--->[s]   ( Typical Range: 1<Abrasiveness<100 )
    ! -----**-----**-----**-----**---     End of data%State%ROP_Bit%RateofPenetration Model Coefficients      ---**-----**-----**-----**-----
    
    
    
    
    
    
    ! $$$$$**$$$$$**$$$$$**$$$$$**$$$$$**        Main Calculations:        *$$$$$**$$$$$**$$$$$**$$$$$**$$$$$
    data%State%ROP_Spec%f1 = data%Configuration%Formation%Formations(data%State%ROP_Spec%FormationNumber)%Drillablity                        ! 1<=Drillability<=100  [ft/h]
    data%State%ROP_Spec%f2 = exp(2.303d0*data%State%ROP_Spec%a2*(10000.d0 - data%State%ROP_Bit%DrillingVerticalDepth))            ! First Compaction Vairable
    data%State%ROP_Spec%f3 = exp(2.303d0*data%State%ROP_Spec%a3*(data%State%ROP_Bit%DrillingVerticalDepth**0.69d0)*(data%State%ROP_Bit%FormationMudDensity-9.d0))    ! Second Compaction Vairable
    
    
    if ( (2.303d0*data%State%ROP_Spec%a4*data%State%ROP_Bit%DrillingVerticalDepth*(data%State%ROP_Bit%FormationMudDensity-data%State%ROP_Bit%ECD))>=0.d0 ) then
        data%State%ROP_Spec%f4 = exp(2.303d0*data%State%ROP_Spec%a4*data%State%ROP_Bit%DrillingVerticalDepth*(data%State%ROP_Bit%FormationMudDensity-data%State%ROP_Bit%ECD))           ! Underbalance Drilling Variable
    else
        data%State%ROP_Spec%f4 = 1.0d0
    end if
    
    
    if (data%State%TD_String%WeightOnBit>0.d0) then
        data%State%ROP_Bit%WeightOnBit = data%State%TD_String%WeightOnBit/1000.d0    ![klb]
    else
        data%State%ROP_Bit%WeightOnBit = 0.d0
    end if
    
    if ( (data%State%ROP_Bit%WeightOnBit/data%State%ROP_Spec%DiameterOfBit)<data%State%ROP_Spec%CriticalWeightOnBit ) then
        data%State%ROP_Spec%f5 = 0.0d0
    else
        data%State%ROP_Spec%f5 = ( ((data%State%ROP_Bit%WeightOnBit/data%State%ROP_Spec%DiameterOfBit)-data%State%ROP_Spec%CriticalWeightOnBit)/(4.d0-data%State%ROP_Spec%CriticalWeightOnBit) )**data%State%ROP_Spec%a5 
    end if
   
    
    if (data%Configuration%Hoisting%DriveType==1 .and. data%State%RTable%Speed>0.d0) then
        data%State%ROP_Bit%RotarySpeed = data%State%RTable%Speed               ![rpm]
    else if (data%Configuration%Hoisting%DriveType==0 .and. (data%State%TDS%Speed>0. .or. data%State%RTable%Speed>0.)) then
        data%State%ROP_Bit%RotarySpeed = data%State%TDS%Speed+data%State%RTable%Speed     ![rpm]
    else
        data%State%ROP_Bit%RotarySpeed = 0.0d0
    end if
    data%State%ROP_Spec%f6 = (data%State%ROP_Bit%RotarySpeed/100.d0)**data%State%ROP_Spec%a6
    
    
    data%State%ROP_Spec%f7 = exp(-data%State%ROP_Spec%a7*data%State%ROP_Bit%BitWearing)
    
    
    Call JetImpactForce
    data%State%ROP_Spec%f8 = data%State%ROP_Bit%JetImpactForce/1000.d0
    
    
    
    
    data%State%ROP_Bit%RateOfPenetration = (data%State%ROP_Spec%f1*data%State%ROP_Spec%f2*data%State%ROP_Spec%f3*data%State%ROP_Spec%f4*data%State%ROP_Spec%f5*data%State%ROP_Spec%f6*data%State%ROP_Spec%f7*data%State%ROP_Spec%f8)    ![ft/h]
    data%State%ROP_Bit%RateOfPenetration = (DINT(data%State%ROP_Bit%RateOfPenetration*10.d0))/10.d0
    
    if ( (data%State%TD_WellGeneral%WellTotalLength==data%Configuration%Path%Items(data%Configuration%Path%ItemCount)%MeasuredDepth) ) then
        data%State%ROP_Bit%SetROPGauge = data%State%ROP_Bit%RateOfPenetration
        Call Set_ROP(data%State%ROP_Bit%SetROPGauge)                     ![ft/h]
        data%State%ROP_Bit%OldROPValue(4) = data%State%ROP_Bit%RateOfPenetration
        !print* , 'first rop=' , data%State%ROP_Bit%OldROPValue , data%State%ROP_Bit%RateOfPenetration ,&
        !    zero_ROPcount , data%State%ROP_Bit%SetROPGauge , data%State%ROP_Bit%OldROPDepth , data%State%TD_WellGeneral%WellTotalLength , PathGenerations(PathGenerationCount)%MeasuredDepth
    else if ( ((data%State%TD_WellGeneral%WellTotalLength+(data%State%ROP_Bit%RateOfPenetration*data%State%TD_General%TimeStep/3600.d0))-data%State%ROP_Bit%OldROPDepth)>=0.1 ) then
        do i= 1,4
            if ( data%State%ROP_Bit%OldROPValue(i)==0. ) then
                zero_ROPcount = zero_ROPcount+1
            end if
        end do
        data%State%ROP_Bit%SetROPGauge = (data%State%ROP_Bit%RateOfPenetration+data%State%ROP_Bit%OldROPValue(1)+data%State%ROP_Bit%OldROPValue(2)+data%State%ROP_Bit%OldROPValue(3)+data%State%ROP_Bit%OldROPValue(4))/sngl(5-zero_ROPcount)
        Call Set_ROP(data%State%ROP_Bit%SetROPGauge)                     ![ft/h]
        do i= 2,4
            data%State%ROP_Bit%OldROPValue(i-1) = data%State%ROP_Bit%OldROPValue(i)
        end do
        data%State%ROP_Bit%OldROPValue(4) = data%State%ROP_Bit%RateOfPenetration
        data%State%ROP_Bit%OldROPDepth    = data%State%TD_WellGeneral%WellTotalLength+(data%State%ROP_Bit%RateOfPenetration*data%State%TD_General%TimeStep/3600.d0)
        !print* , 'new rop=' , data%State%ROP_Bit%OldROPValue , data%State%ROP_Bit%RateOfPenetration ,&
        !    zero_ROPcount , data%State%ROP_Bit%SetROPGauge , data%State%ROP_Bit%OldROPDepth , data%State%TD_WellGeneral%WellTotalLength , PathGenerations(PathGenerationCount)%MeasuredDepth
    else
        Call Set_ROP(data%State%ROP_Bit%SetROPGauge)                     ![ft/h]
        !print* , 'old rop=' , data%State%ROP_Bit%OldROPValue , data%State%ROP_Bit%RateOfPenetration ,&
        !    zero_ROPcount , data%State%ROP_Bit%SetROPGauge , data%State%ROP_Bit%OldROPDepth , data%State%TD_WellGeneral%WellTotalLength , PathGenerations(PathGenerationCount)%MeasuredDepth
    end if    
    
    
    
    
    
    
    if (data%State%ROP_Bit%RotarySpeed > 0.d0) THEN 
        data%State%ROP_Bit%BitTorque = ( 3.79d0 + 19.17d0*sqrt( data%State%ROP_Bit%RateOfPenetration / (data%State%ROP_Bit%RotarySpeed*data%State%ROP_Spec%DiameterOfBit)) ) * data%State%ROP_Spec%DiameterOfBit * data%State%ROP_Bit%WeightOnBit * ( 1.d0 / ( 1.d0 + 0.00021d0*data%State%ROP_Bit%DrillingVerticalDepth) )
        !data%State%ROP_Bit%BitTorque = data%State%ROP_Bit%BitTorque/3.   !bi dalil taghsim bar 3 shode(chon adad bozorg bude), baadan az rabete check shavad (seyyed gofte)
    else
        data%State%ROP_Bit%BitTorque = 0.d0
    end if
   
    
    
    if ( (data%State%ROP_Bit%WeightOnBit/data%State%ROP_Spec%DiameterOfBit)<(data%State%ROP_Spec%wdmax) ) then
        data%State%ROP_Bit%BitWearing = data%State%ROP_Bit%BitWearing +( (data%State%ROP_Spec%dt*data%State%ROP_Spec%H3/data%State%ROP_Spec%TouH)*((data%State%ROP_Bit%RotarySpeed/100.d0)**data%State%ROP_Spec%H1)*((data%State%ROP_Spec%wdmax-4.d0)/(data%State%ROP_Spec%wdmax-(data%State%ROP_Bit%WeightOnBit/data%State%ROP_Spec%DiameterOfBit)))*((1.d0+(data%State%ROP_Spec%H2/2.d0))/(1.d0+(data%State%ROP_Spec%H2*data%State%ROP_Bit%BitWearing))) )
    else
        data%State%ROP_Bit%BitWearing = 1.0d0          !( Typical Range: 0<=data%State%ROP_Bit%BitWearing<=1 )
    end if
    
    
    
    data%State%ROP_Bit%BearingWear = data%State%ROP_Bit%BearingWear+(data%State%ROP_Spec%dt/3600.d0)*(data%State%ROP_Bit%RotarySpeed/100.d0/data%State%ROP_Spec%BrCoef)*((data%State%ROP_Bit%WeightOnBit/4.d0/data%State%ROP_Spec%DiameterOfBit)**1.5d0)
    
    
    !print*, 'data%State%ROP_Bit%RateOfPenetration=', data%State%ROP_Bit%RateOfPenetration
    !!print*, 'data%State%ROP_Bit%FormationMudDensity=', data%State%ROP_Bit%FormationMudDensity
    !!print*, 'data%State%ROP_Bit%ECD=', data%State%ROP_Bit%ECD
    !!print*, 'data%State%ROP_Bit%DrillingVerticalDepth=', data%State%ROP_Bit%DrillingVerticalDepth
    !!print*, 'power=', (2.303*data%State%ROP_Spec%a4*data%State%ROP_Bit%DrillingVerticalDepth*(data%State%ROP_Bit%FormationMudDensity-data%State%ROP_Bit%ECD))
    !print*, 'data%State%ROP_Bit%RotarySpeed=', data%State%ROP_Bit%RotarySpeed
    !!
    !print*, 'data%State%ROP_Spec%f1=', data%State%ROP_Spec%f1
    !print*, 'data%State%ROP_Spec%f2=', data%State%ROP_Spec%f2
    !print*, 'data%State%ROP_Spec%f3=', data%State%ROP_Spec%f3
    !print*, 'data%State%ROP_Spec%f4=', data%State%ROP_Spec%f4
    !print*, 'data%State%ROP_Spec%f5=', data%State%ROP_Spec%f5
    !print*, 'data%State%ROP_Spec%f6=', data%State%ROP_Spec%f6
    !print*, 'data%State%ROP_Spec%f7=', data%State%ROP_Spec%f7
    !print*, 'data%State%ROP_Spec%f8=', data%State%ROP_Spec%f8
    !print*, '***********************'

    
    
    
    
end subroutine