コード例 #1
0
ファイル: BaseWell.cs プロジェクト: vcer007/FIM
        /// <summary>
        /// Gets the well mobility of a certain phase at a specified time level.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="phase">The phase.</param>
        /// <param name="timeLevel">The time level.</param>
        /// <returns></returns>
        /// <seealso cref="Global.STEPS_MEMORY"/>
        public double GetWellMobility(SimulationData data, Global.Phase phase, int timeLevel)
        {
            BaseBlock block = data.grid[this.index];

            if (phase == Global.Phase.Oil)
            {
                return(block.Kro[timeLevel] / (block.viscosityOil[timeLevel] * block.Bo[timeLevel]));
            }
            else if (phase == Global.Phase.Gas)
            {
                return(block.Krg[timeLevel] / (block.viscosityGas[timeLevel] * block.Bg[timeLevel]));
            }
            else
            {
                return(block.Krw[timeLevel] / (block.viscosityWater[timeLevel] * block.Bw[timeLevel]));
            }
        }
コード例 #2
0
ファイル: SCAL.cs プロジェクト: vcer007/FIM
        /// <summary>
        /// Gets the relative permeability for a certain phase.
        /// </summary>
        /// <param name="phase">The phase.</param>
        /// <param name="saturation">The saturation.</param>
        /// <returns>The value of the relative permeability</returns>
        /// <seealso cref="Global.Phase"/>
        public double GetKr(Global.Phase phase, double saturation)
        {
            switch (phase)
            {
            case Global.Phase.Water:
                return(GetKrw(saturation));

            case Global.Phase.Oil:
                return(GetKro(saturation));

            case Global.Phase.Gas:
                return(GetKrg(saturation));

            default:
                return(1);
            }
        }
コード例 #3
0
        // The publicly accessible methods.

        /// <summary>
        /// Gets the FVF of a certain phase.
        /// </summary>
        /// <param name="phase">The phase.</param>
        /// <param name="pressure">The pressure.</param>
        /// <returns>The value of FVF</returns>
        /// <seealso cref="Global.Phase"/>
        public double GetFVF(Global.Phase phase, double pressure)
        {
            switch (phase)
            {
            case Global.Phase.Water:
                return(GetWaterFVF(pressure));

            case Global.Phase.Oil:
                return(GetOilFVF(pressure));

            case Global.Phase.Gas:
                return(GetGasFVF(pressure) * Global.a);

            default:
                return(1);
            }
        }
コード例 #4
0
        /// <summary>
        /// Gets the solution Gas/Oil ratio.
        /// </summary>
        /// <param name="phase">The phase.</param>
        /// <param name="pressure">The pressure.</param>
        /// <returns>The value of RsO.</returns>
        public double GetRs(Global.Phase phase, double pressure)
        {
            switch (phase)
            {
            case Global.Phase.Water:
                return(GetRsw(pressure));

            case Global.Phase.Oil:
                return(GetRso(pressure) / Global.a);

            case Global.Phase.Gas:
                return(1);

            default:
                return(1);
            }
        }
コード例 #5
0
        /// <summary>
        /// Gets the density of a certain phase.
        /// </summary>
        /// <param name="phase">The phase.</param>
        /// <param name="pressure">The pressure.</param>
        /// <returns>The value of density</returns>
        /// <seealso cref="Global.Phase"/>
        public double GetDensity(Global.Phase phase, double pressure)
        {
            switch (phase)
            {
            case Global.Phase.Water:
                return(GetWaterDensity(pressure));

            case Global.Phase.Oil:
                return(GetOilDensity(pressure));

            case Global.Phase.Gas:
                return(GetGasDensity(pressure));

            default:
                return(1);
            }
        }
コード例 #6
0
        //public static double getQ_P(this BaseBlock block, SimulationData data)
        //{

        //}

        /// <summary>
        /// Gets the residual equation result multiplied by -1.
        /// </summary>
        /// <param name="block">The block.</param>
        /// <param name="data">The <seealso cref="SimulationData"/> data.</param>
        /// <param name="phase">The phase.</param>
        /// <returns></returns>
        public static double getminus_R(this BaseBlock block, SimulationData data, Global.Phase phase)
        {
            double R = 0;

            if (phase == Global.Phase.Oil)
            {
                R = -1 / (Global.a * data.timeStep) * (block.Vp[1] * (1 - block.Sg[1]) / block.Bo[1] - block.Vp[0] * (1 - block.Sg[0]) / block.Bo[0]) /*- block.q_oil[1]*/;
            }
            else if (phase == Global.Phase.Gas)
            {
                R = -1 / (Global.a * data.timeStep) * (block.Vp[1] * block.Sg[1] / block.Bg[1] - block.Vp[0] * block.Sg[0] / block.Bg[0]) /*- block.q_gas[1]*/;

                if (data.solubleGasPresent)
                {
                    R += -1 / (Global.a * data.timeStep) * (block.Rso[1] * block.Vp[1] * (1 - block.Sg[1]) / block.Bo[1] - block.Rso[0] * block.Vp[0] * (1 - block.Sg[0]) / block.Bo[0]) /*- block.Rso[1] * block.q_oil[1]*/;
                }
            }

            return(-1 * R);
        }
コード例 #7
0
        // calculates d(1/B)/dP.
        private static double FVF_dash(this BaseBlock block, Global.Phase phase)
        {
            double P_difference = block.P[1] - block.P[0];

            double FVF_1 = 1, FVF_0 = 1;

            if (phase == Global.Phase.Oil)
            {
                FVF_1 = block.Bo[1];
                FVF_0 = block.Bo[0];
            }
            else if (phase == Global.Phase.Water)
            {
                FVF_1 = block.Bw[1];
                FVF_0 = block.Bw[0];
            }
            else
            {
                FVF_1 = block.Bg[1];
                FVF_0 = block.Bg[0];
            }
            return((1 / FVF_1 - 1 / FVF_0) / (P_difference));
        }
コード例 #8
0
ファイル: NumericalPerturbation.cs プロジェクト: vcer007/FIM
        // perturb the residual equation "calculate at independent variable + epsilon".
        // the perturbed value will then be subtracted from the original R value and divided by epsilon to get the derivative numerically.
        private static double Perturb(this BaseBlock block, SimulationData data, Global.Phase equation_phase, int neighbour_block_index, Global.Variable variable)
        {
            double R_plus = 0;

            double transmissibility_temp = 0;

            double transmissibility_term = 0;
            double accumulation_term     = 0;

            double    kr, viscosity, B, Rso;
            BaseBlock upstream_block, downstream_block, neighbor_block;

            double transmissiblity;

            #region Variable Dependencies
            int  pd = 1, npd = 1, swd = 1, nswd = 1, sgd = 1, nsgd = 1;
            bool this_block = true;

            if (neighbour_block_index == -1)
            {
                this_block = true;
            }
            else
            {
                this_block = false;
            }

            if (variable == Global.Variable.Pressure)
            {
                if (this_block)
                {
                    pd = 2;
                }
                else
                {
                    npd = 2;
                }
            }
            else if (variable == Global.Variable.SaturationGas)
            {
                if (this_block)
                {
                    sgd = 2;
                }
                else
                {
                    nsgd = 2;
                }
            }
            else if (variable == Global.Variable.SaturationWater)
            {
                if (this_block)
                {
                    swd = 2;
                }
                else
                {
                    nswd = 2;
                }
            }
            #endregion


            if (equation_phase == Global.Phase.Oil)
            {
                if (this_block)
                {
                    // transmissibility term
                    for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                    {
                        if (block.neighborBlocksIndices[i] == -1)
                        {
                            continue;
                        }

                        neighbor_block = data.grid[block.neighborBlocksIndices[i]];

                        if (block.P[1] >= neighbor_block.P[1])
                        {
                            upstream_block   = block;
                            downstream_block = neighbor_block;

                            kr = upstream_block.Kro[sgd];
                        }
                        else
                        {
                            upstream_block   = neighbor_block;
                            downstream_block = block;

                            kr = upstream_block.Kro[nsgd];
                        }

                        B               = 0.5 * (block.Bo[pd] + neighbor_block.Bo[npd]);
                        viscosity       = 0.5 * (block.viscosityOil[pd] + neighbor_block.viscosityOil[npd]);
                        transmissiblity = block.transmissibility_list[i];

                        transmissibility_temp = transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);

                        transmissibility_term += transmissibility_temp;
                    }
                    // accumulation term
                    accumulation_term = 1 / (data.timeStep * Global.a) * ((block.Vp[pd] * (1 - block.Sg[sgd] - block.Sw[swd]) / block.Bo[pd]) - (block.Vp[0] * block.So[0] / block.Bo[0]));
                }
                else
                {
                    // transmissibility term
                    neighbor_block = data.grid[block.neighborBlocksIndices[neighbour_block_index]];

                    if (block.P[1] >= neighbor_block.P[1])
                    {
                        upstream_block   = block;
                        downstream_block = neighbor_block;

                        kr = upstream_block.Kro[sgd];
                    }
                    else
                    {
                        upstream_block   = neighbor_block;
                        downstream_block = block;

                        kr = upstream_block.Kro[nsgd];
                    }

                    B               = 0.5 * (block.Bo[pd] + neighbor_block.Bo[npd]);
                    viscosity       = 0.5 * (block.viscosityOil[pd] + neighbor_block.viscosityOil[npd]);
                    transmissiblity = block.transmissibility_list[neighbour_block_index];

                    transmissibility_temp = transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);

                    transmissibility_term = transmissibility_temp;
                    for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                    {
                        if (i == neighbour_block_index)
                        {
                            continue;
                        }

                        transmissibility_term += block.transmissibility_terms_oil[i];
                    }
                    // accumulation term
                    accumulation_term = block.accumulation_term_oil;
                }
            }
            else if (equation_phase == Global.Phase.Gas)
            {
                if (this_block)
                {
                    // transmissibility term
                    for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                    {
                        if (block.neighborBlocksIndices[i] == -1)
                        {
                            continue;
                        }

                        neighbor_block = data.grid[block.neighborBlocksIndices[i]];

                        if (block.P[1] >= neighbor_block.P[1])
                        {
                            upstream_block   = block;
                            downstream_block = neighbor_block;

                            kr = upstream_block.Krg[sgd];
                        }
                        else
                        {
                            upstream_block   = neighbor_block;
                            downstream_block = block;

                            kr = upstream_block.Krg[nsgd];
                        }

                        B               = 0.5 * (block.Bg[pd] + neighbor_block.Bg[npd]);
                        viscosity       = 0.5 * (block.viscosityGas[pd] + neighbor_block.viscosityGas[npd]);
                        transmissiblity = block.transmissibility_list[i];

                        transmissibility_temp = transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);

                        if (data.solubleGasPresent)
                        {
                            if (upstream_block.index == block.index)
                            {
                                kr = upstream_block.Kro[sgd];
                            }
                            else
                            {
                                kr = upstream_block.Kro[nsgd];
                            }

                            Rso       = 0.5 * (block.Rso[pd] + neighbor_block.Rso[npd]);
                            B         = 0.5 * (block.Bo[pd] + neighbor_block.Bo[npd]);
                            viscosity = 0.5 * (block.viscosityOil[pd] + neighbor_block.viscosityOil[npd]);

                            transmissibility_temp += Rso * transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);
                        }


                        transmissibility_term += transmissibility_temp;
                    }
                    // accumulation term
                    accumulation_term = 1 / (data.timeStep * Global.a) * ((block.Vp[pd] * block.Sg[sgd] / block.Bg[pd]) - (block.Vp[0] * block.Sg[0] / block.Bg[0]));

                    if (data.solubleGasPresent)
                    {
                        accumulation_term += 1 / (data.timeStep * Global.a) * (block.Rso[pd] * (block.Vp[pd] * (1 - block.Sg[sgd] - block.Sw[swd]) / block.Bo[pd]) - block.Rso[0] * (block.Vp[0] * block.So[0] / block.Bo[0]));
                    }
                }
                else
                {
                    // transmissibility term
                    neighbor_block = data.grid[block.neighborBlocksIndices[neighbour_block_index]];

                    if (block.P[1] >= neighbor_block.P[1])
                    {
                        upstream_block   = block;
                        downstream_block = neighbor_block;

                        kr = upstream_block.Krg[sgd];
                    }
                    else
                    {
                        upstream_block   = neighbor_block;
                        downstream_block = block;

                        kr = upstream_block.Krg[nsgd];
                    }

                    B               = 0.5 * (block.Bg[pd] + neighbor_block.Bg[npd]);
                    viscosity       = 0.5 * (block.viscosityGas[pd] + neighbor_block.viscosityGas[npd]);
                    transmissiblity = block.transmissibility_list[neighbour_block_index];

                    transmissibility_temp = transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);

                    if (data.solubleGasPresent)
                    {
                        if (upstream_block.index == block.index)
                        {
                            kr = upstream_block.Kro[sgd];
                        }
                        else
                        {
                            kr = upstream_block.Kro[nsgd];
                        }

                        Rso       = 0.5 * (block.Rso[pd] + neighbor_block.Rso[npd]);
                        B         = 0.5 * (block.Bo[pd] + neighbor_block.Bo[npd]);
                        viscosity = 0.5 * (block.viscosityOil[pd] + neighbor_block.viscosityOil[npd]);

                        transmissibility_temp += Rso * transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);
                    }

                    transmissibility_term = transmissibility_temp;
                    for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                    {
                        if (i == neighbour_block_index)
                        {
                            continue;
                        }

                        transmissibility_term += block.transmissibility_terms_gas[i];
                    }
                    // accumulation term
                    accumulation_term = block.accumulation_term_gas;
                }
            }
            else if (equation_phase == Global.Phase.Water)
            {
                if (this_block)
                {
                    // transmissibility term
                    for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                    {
                        if (block.neighborBlocksIndices[i] == -1)
                        {
                            continue;
                        }

                        neighbor_block = data.grid[block.neighborBlocksIndices[i]];

                        if (block.P[1] >= neighbor_block.P[1])
                        {
                            upstream_block   = block;
                            downstream_block = neighbor_block;

                            kr = upstream_block.Krw[swd];
                        }
                        else
                        {
                            upstream_block   = neighbor_block;
                            downstream_block = block;

                            kr = upstream_block.Krw[nswd];
                        }

                        B               = 0.5 * (block.Bw[pd] + neighbor_block.Bw[npd]);
                        viscosity       = 0.5 * (block.viscosityWater[pd] + neighbor_block.viscosityWater[npd]);
                        transmissiblity = block.transmissibility_list[i];

                        transmissibility_temp = transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);

                        transmissibility_term += transmissibility_temp;
                    }
                    // accumulation term
                    accumulation_term = 1 / (data.timeStep * Global.a) * ((block.Vp[pd] * block.Sw[swd] / block.Bw[pd]) - (block.Vp[0] * block.Sw[0] / block.Bw[0]));
                }
                else
                {
                    // transmissibility term
                    neighbor_block = data.grid[block.neighborBlocksIndices[neighbour_block_index]];

                    if (block.P[1] >= neighbor_block.P[1])
                    {
                        upstream_block   = block;
                        downstream_block = neighbor_block;

                        kr = upstream_block.Krw[swd];
                    }
                    else
                    {
                        upstream_block   = neighbor_block;
                        downstream_block = block;

                        kr = upstream_block.Krw[nswd];
                    }

                    B               = 0.5 * (block.Bw[pd] + neighbor_block.Bw[npd]);
                    viscosity       = 0.5 * (block.viscosityWater[pd] + neighbor_block.viscosityWater[npd]);
                    transmissiblity = block.transmissibility_list[neighbour_block_index];

                    transmissibility_temp = transmissiblity * kr / (viscosity * B) * (neighbor_block.P[npd] - block.P[pd]);

                    transmissibility_term = transmissibility_temp;
                    for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                    {
                        if (i == neighbour_block_index)
                        {
                            continue;
                        }

                        transmissibility_term += block.transmissibility_terms_water[i];
                    }
                    // accumulation term
                    accumulation_term = block.accumulation_term_water;
                }
            }


            R_plus = transmissibility_term - accumulation_term;
            return(R_plus);
        }
コード例 #9
0
ファイル: NumericalPerturbation.cs プロジェクト: vcer007/FIM
        // calculate the value of the residual equation for any phase.
        private static double CalculateR(this BaseBlock block, SimulationData data, Global.Phase phase)
        {
            // Note : Kro, Krw, Krg are all calculated based on Sg.

            BaseBlock upstream_block, downstream_block, neighbor_block;
            double    transmissibility;

            double Kr, B, viscosity, Rso;
            double R = 0;

            double temp, accumulation_term;


            if (phase == Global.Phase.Oil)
            {
                for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                {
                    if (block.neighborBlocksIndices[i] < 0)
                    {
                        continue;
                    }
                    neighbor_block   = data.grid[block.neighborBlocksIndices[i]];
                    transmissibility = block.transmissibility_list[i];

                    if (block.P[1] >= neighbor_block.P[1])
                    {
                        upstream_block   = block;
                        downstream_block = neighbor_block;
                    }
                    else
                    {
                        upstream_block   = neighbor_block;
                        downstream_block = block;
                    }

                    Kr        = upstream_block.Kro[1];
                    B         = 0.5 * (block.Bo[1] + neighbor_block.Bo[1]);
                    viscosity = 0.5 * (block.viscosityOil[1] + neighbor_block.viscosityOil[1]);

                    temp = transmissibility * Kr / (viscosity * B) * (neighbor_block.P[1] - block.P[1]);
                    block.transmissibility_terms_oil[i] = temp;

                    R += temp;
                }

                accumulation_term           = 1 / (Global.a * data.timeStep) * ((block.Vp[1] * (1 - block.Sw[1] - block.Sg[1]) / block.Bo[1]) - (block.Vp[0] * block.So[0] / block.Bo[0]));
                block.accumulation_term_oil = accumulation_term;

                R -= accumulation_term;
            }
            else if (phase == Global.Phase.Water)
            {
                for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                {
                    if (block.neighborBlocksIndices[i] < 0)
                    {
                        continue;
                    }
                    neighbor_block   = data.grid[block.neighborBlocksIndices[i]];
                    transmissibility = block.transmissibility_list[i];

                    if (block.P[1] >= neighbor_block.P[1])
                    {
                        upstream_block   = block;
                        downstream_block = neighbor_block;
                    }
                    else
                    {
                        upstream_block   = neighbor_block;
                        downstream_block = block;
                    }

                    Kr        = upstream_block.Krw[1];
                    B         = 0.5 * (block.Bw[1] + neighbor_block.Bw[1]);
                    viscosity = 0.5 * (block.viscosityWater[1] + neighbor_block.viscosityWater[1]);

                    temp = transmissibility * Kr / (viscosity * B) * (neighbor_block.P[1] - block.P[1]);
                    block.transmissibility_terms_water[i] = temp;

                    R += temp;
                }

                accumulation_term             = 1 / (Global.a * data.timeStep) * ((block.Vp[1] * block.Sw[1] / block.Bw[1]) - (block.Vp[0] * block.Sw[0] / block.Bw[0]));
                block.accumulation_term_water = accumulation_term;

                R -= accumulation_term;
            }
            else
            {
                for (int i = 0; i < block.neighborBlocksIndices.Length; i++)
                {
                    if (block.neighborBlocksIndices[i] < 0)
                    {
                        continue;
                    }
                    neighbor_block   = data.grid[block.neighborBlocksIndices[i]];
                    transmissibility = block.transmissibility_list[i];

                    if (block.P[1] >= neighbor_block.P[1])
                    {
                        upstream_block   = block;
                        downstream_block = neighbor_block;
                    }
                    else
                    {
                        upstream_block   = neighbor_block;
                        downstream_block = block;
                    }

                    Kr        = upstream_block.Krg[1];
                    B         = 0.5 * (block.Bg[1] + neighbor_block.Bg[1]);
                    viscosity = 0.5 * (block.viscosityGas[1] + neighbor_block.viscosityGas[1]);

                    temp = transmissibility * Kr / (viscosity * B) * (neighbor_block.P[1] - block.P[1]);

                    if (data.solubleGasPresent)
                    {
                        Kr        = upstream_block.Kro[1];
                        B         = 0.5 * (block.Bo[1] + neighbor_block.Bo[1]);
                        viscosity = 0.5 * (block.viscosityOil[1] + neighbor_block.viscosityOil[1]);
                        Rso       = 0.5 * (block.Rso[1] + neighbor_block.Rso[1]);

                        temp += Rso * transmissibility * Kr / (viscosity * B) * (neighbor_block.P[1] - block.P[1]);
                        //temp += Rso * block.transmissibility_terms_oil[i];
                    }

                    block.transmissibility_terms_gas[i] = temp;

                    R += temp;
                }

                accumulation_term = 1 / (Global.a * data.timeStep) * ((block.Vp[1] * block.Sg[1] / block.Bg[1]) - (block.Vp[0] * block.Sg[0] / block.Bg[0]));
                // check for presence of soluble_gas in simulation_data
                if (data.solubleGasPresent)
                {
                    accumulation_term += 1 / (Global.a * data.timeStep) * ((block.Rso[1] * block.Vp[1] * (1 - block.Sw[1] - block.Sg[1]) / block.Bo[1]) - (block.Rso[0] * block.Vp[0] * block.So[0] / block.Bo[0]));
                }
                block.accumulation_term_gas = accumulation_term;

                R -= accumulation_term;
            }

            return(R);
        }