Пример #1
0
        //Method Name: getTransmissibility
        //Objectives: calculating the transmissibility between two blocks
        //Inputs: two variables of type "GridBlock", the value of the geometric factor and a variable of type "Phase"
        public static double getTransmissibility(GridBlock block_1, GridBlock block_2, double geometric_factor, Phase phase)
        {
            GridBlock upstream_block;
            double    viscosity, FVF, Kr;

            //Check for Inactive blocks
            if (block_1.type == GridBlock.Type.Inactive || block_2.type == GridBlock.Type.Inactive)
            {
                return(0);
            }

            //Determine the upstream block
            if (block_1.pressure >= block_2.pressure)
            {
                upstream_block = block_1;
            }
            else
            {
                upstream_block = block_2;
            }

            //Assign the values of viscosity, FVF and Kr according to the appropriate phase
            if (phase == Phase.Oil)
            {
                viscosity = 2 / (1 / block_1.oil_viscosity + 1 / block_2.oil_viscosity);
                FVF       = 2 / (1 / block_1.Bo + 1 / block_2.Bo);
                Kr        = upstream_block.Kro;
            }
            else if (phase == Phase.Gas)
            {
                viscosity = 2 / (1 / block_1.gas_viscosity + 1 / block_2.gas_viscosity);
                FVF       = 2 / (1 / block_1.Bg + 1 / block_2.Bg);
                Kr        = upstream_block.Krg;
            }
            else
            {
                viscosity = 2 / (1 / block_1.water_viscosity + 1 / block_2.water_viscosity);
                FVF       = 2 / (1 / block_1.Bw + 1 / block_2.Bw);
                //viscosity = upstream_block.water_viscosity;
                //FVF = upstream_block.Bw;
                Kr = upstream_block.Krw;
            }

            double T = geometric_factor * Kr / (viscosity * FVF);

            return(T);
        }
Пример #2
0
        //Method Name: assignBlockOrdering_ActiveOnly
        //Objectives: this method is used for each "active block only" in the grid to assign its numbering and the numbering of neighbouring blocks
        //Inputs: a variable of type "GridBlock" that contains all the data of the block, a general counter of the loop, block counter, array of block coordinates, array of grid dimensions and an array of the natural ordering of the in-active blocks
        //Ouputs: N/A. This is an internal method that calculates the numbering and assign it to the variable "block" that is passed to this method
        private static void assignBlockOrdering_ActiveOnly(GridBlock block, int counter, int block_counter, int[] block_coordinates, int[] grid_diemnsions, int[] inactive_blocks)
        {
            int i, j, k;

            i = block_coordinates[0]; j = block_coordinates[1]; k = block_coordinates[2];

            int x, y, z;

            x = grid_diemnsions[0]; y = grid_diemnsions[1]; z = grid_diemnsions[2];

            block.counter        = block_counter;
            block.east_counter   = getNextBlockCounter(Direction.East, block_counter, counter, inactive_blocks, grid_diemnsions, block_coordinates);
            block.west_counter   = getNextBlockCounter(Direction.West, block_counter, counter, inactive_blocks, grid_diemnsions, block_coordinates);
            block.north_counter  = getNextBlockCounter(Direction.North, block_counter, counter, inactive_blocks, grid_diemnsions, block_coordinates);
            block.south_counter  = getNextBlockCounter(Direction.South, block_counter, counter, inactive_blocks, grid_diemnsions, block_coordinates);
            block.top_counter    = getNextBlockCounter(Direction.Top, block_counter, counter, inactive_blocks, grid_diemnsions, block_coordinates);
            block.bottom_counter = getNextBlockCounter(Direction.Bottom, block_counter, counter, inactive_blocks, grid_diemnsions, block_coordinates);
        }
Пример #3
0
        //Method Name: assignBlockOrdering_Natural
        //Objectives: this method is used for each block "both active and in-active" in the grid to assign its numbering and the numbering of neighbouring blocks
        //Inputs: a variable of type "GridBlock" that contains all the data of the block, a general counter of the loop, array of block coordinates, array of grid dimensions and an array of the natural ordering of the in-active blocks
        //Ouputs: N/A. This is an internal method that calculates the numbering and assign it to the variable "block" that is passed to this method
        private static void assignBlockOrdering_Natural(GridBlock block, int counter, int[] block_dimensions, int[] grid_diemnsions, int[] inactive_blocks)
        {
            int i, j, k;

            i = block_dimensions[0]; j = block_dimensions[1]; k = block_dimensions[2];

            int x, y, z;

            x = grid_diemnsions[0]; y = grid_diemnsions[1]; z = grid_diemnsions[2];

            block.counter        = counter;
            block.east_counter   = i < (x - 1) ? counter + 1 : -1;
            block.west_counter   = i > 0 ? counter - 1 : -1;
            block.north_counter  = j < (y - 1) ? counter + x : -1;
            block.south_counter  = j > 0 ? counter - x : -1;
            block.top_counter    = k > 0 ? (k - 1) : -1;
            block.bottom_counter = k < (z - 1) ? (k + 1) : -1;
        }
Пример #4
0
        //Homogeneous grid
        public static double getGeometricFactor(GridBlock block, GridType type, Direction direction)
        {
            double area, length, permeability, G;

            //Rectangular grid
            if (type == GridType.Rectangular)
            {
                if (direction == Direction.x)
                {
                    area         = block.delta_y * block.h;
                    length       = block.delta_x;
                    permeability = block.Kx;
                }
                else if (direction == Direction.y)
                {
                    area         = block.delta_x * block.h;
                    length       = block.delta_y;
                    permeability = block.Ky;
                }
                else
                {
                    area         = block.delta_x * block.delta_y;
                    length       = block.h;
                    permeability = block.Kz;
                }

                G = Bc * permeability * area / length;
                return(G);
            }
            //Cylindrical grid
            else
            {
                //To-Do: implement this method
                return(0);
            }
        }
Пример #5
0
        //Method Name: getGeometricFactor
        //Objectives: calculate the geometric factor of the well if it is perfectly centred within a grid block
        //Inputs: a variable of type "GridBlock"
        //Outputs: the value of the geometric factor of the well
        public static double getGeometricFactor(GridBlock block)
        {
            double r_equivalent;
            double Kh;

            if (block.delta_x == block.delta_y && block.Kx == block.Ky)
            {
                r_equivalent = 0.198 * block.delta_x;
            }
            else if (block.delta_x == block.delta_y)
            {
                r_equivalent = 0.14 * Math.Sqrt(Math.Pow(block.delta_x, 2) + Math.Pow(block.delta_y, 2));
            }
            else
            {
                r_equivalent = 0.28 * Math.Sqrt(Math.Sqrt(block.Ky / block.Kx) * Math.Pow(block.delta_x, 2) + Math.Sqrt(block.Kx / block.Ky) * Math.Pow(block.delta_y, 2)) / (Math.Pow((block.Ky / block.Kx), 0.25) + Math.Pow((block.Kx / block.Ky), 0.25));
            }

            Kh = Math.Sqrt(block.Kx * block.Ky);

            double G = 2 * Math.PI * Bc * Kh * block.h / (Math.Log(r_equivalent / (block.rw / 12)) + block.skin);

            return(G);
        }
Пример #6
0
        //Method Name: assignGridOrdering
        //Objectives: gives each block in the grid a number according to the numbering scheme used
        //Inputs: an array of the (x, y, z) grid dimensions and an array of the Inactive blocks numberings
        //Ouputs: an array of GridBlocks that are given numbers according to the numbering scheme used
        public static GridBlock[] assignGridOrdering(int[] grid_dimensions, int[] inactive_blocks, NumberingScheme scheme)
        {
            //variables to store the grid dimensions
            int x, y, z;

            //store the grid dimensions
            x = grid_dimensions[0]; y = grid_dimensions[1]; z = grid_dimensions[2];
            //an array to store a block's i, j and k coordinates within the grid according to the engineering notation
            int[] block_coordinates = new int[3];
            //A variable to store block's data
            GridBlock block;

            //A variable representing the grid array of blocks
            GridBlock[] grid = new GridBlock[0];
            if (scheme == NumberingScheme.All)
            {
                //Grid array size is equal to all the block "including in-active blocks"
                grid = new GridBlock[x * y * z];
            }
            else if (scheme == NumberingScheme.Active_Only)
            {
                //Grid array size is equal to the number of active-only blocks
                grid = new GridBlock[x * y * z - inactive_blocks.Length];
            }


            //A general loop counter
            int counter = 0;
            //A block counter
            //This variable is used only with the "assignBlockOrdering_ActiveOnly" method to keep track of the number of active blocks added to the grid
            int block_counter = 0;

            //A loop to iterate over all the blocks in the grid according to the engineering notation
            for (int k = 0; k < z; k++)
            {
                for (int j = 0; j < y; j++)
                {
                    for (int i = 0; i < x; i++)
                    {
                        block = new GridBlock();
                        //assign the values of the block coordinates
                        block.x = i; block.y = j; block.z = k;

                        //set block type "either Inactive or normal"
                        if (inactive_blocks.Contains(counter))
                        {
                            block.type = GridBlock.Type.Inactive;
                        }

                        //set the block coordinates array that will be passed to other methods
                        block_coordinates[0] = i; block_coordinates[1] = j; block_coordinates[2] = k;

                        //###########################################################################################

                        if (scheme == NumberingScheme.All)
                        {
                            //Natural ordering for the entire grid "both active and in-active blocks"
                            RectangularBlockNumbering.assignBlockOrdering_Natural(block, counter, block_coordinates, grid_dimensions, inactive_blocks);
                        }
                        else if (scheme == NumberingScheme.Active_Only)
                        {
                            //Natural ordering for the grid "active blocks only"
                            if (block.type == GridBlock.Type.Inactive)
                            {
                                //increment the general loop counter and skip this block
                                counter += 1;
                                continue;
                            }

                            RectangularBlockNumbering.assignBlockOrdering_ActiveOnly(block, counter, block_counter, block_coordinates, grid_dimensions, inactive_blocks);
                        }

                        //###########################################################################################

                        //increment counter at the end of the loop
                        counter += 1;
                        //this statement adds the block to the grid array
                        grid[block_counter] = block;
                        //only increment block_counter when a block is added to the grid to keep track of how many blocks have been added
                        block_counter += 1;
                    }
                }
            }

            return(grid);
        }
Пример #7
0
 public static double calculate_BHP(GridBlock block)
 {
     return(block.pressure - (block.well_flow_rate / block.well_transmissibility));
 }