Patent Description:
In today's oil and gas industry, wells that are deviated are most common and more often than not, deviated to horizontal - meaning an inclination of about <NUM>-<NUM> degrees. There are a number of established plays that utilize mass planning and targeting for horizontal drilling like the SAGD (steam assisted gravity drainage) in Canada and the Marcellus, Hornriver and Barnett shale gas plays. In order to optimize the number of wells to completely exploit one of these plays, companies are planning hundreds, and in some case thousands, of wells for an entire asset in a defined area, which is often very time-consuming and requires numerous resources. There are therefore, numerous types of resource plays that require horizontal laterals to be positioned and spaced to fill either a regular or irregular shape lease or unit boundary. Two specific plays that utilize the placement of horizontal laterals are shale and heavy oil plays. The objective is to maximize the coverage within this area based on lateral constraints, such as min/max lateral lengths, lateral spacing and heel/toe, heel/heel or toe/toe spacing. In SAGD (Steam Assisted Gravity Drainage) applications, these laterals are in pairs with the upper lateral being the steam injector and the lower lateral being the oil producer. Companies often rely on conventional technology to help accomplish this objective and as a result are often limited with respect to the number of scenarios that can be analyzed. Once the drilling operation has commenced and information from wells being drilled are coming in from the field, engineers, once again, rely on conventional technology to update the plan based on actual data and are limited in their options for re-distributing the remaining laterals. This process can easily take months to complete depending on the size of the field and the number of wells that are being planned.

There is therefore, a need for a more efficient process that will significantly reduce the cost of planning horizontal wells by reducing the time to plan their horizontal laterals within a limited pre-defined boundary while addressing the same concerns addressed in the conventional process.

<CIT> discloses ranging methods for developing wellbores in subsurface formations.

<CIT> discloses an automated bore planning method and apparatus for horizontal directional drilling.

Embodiments of the present invention therefore, meet the above needs and overcomes one or more deficiencies in the prior art by providing systems and methods for creating targets for horizontal wells within a limited pre-defined boundary based upon different patterns for the horizontal wells.

In a first aspect of the present invention, there is provided a method according to Claim <NUM>.

In a second aspect of the present invention, there is provided a non-transitory program carrier device according to Claim <NUM>.

Additional aspects, advantages and embodiments of the invention will become apparent to those skilled in the art from the following description of the various embodiments and related drawings.

The present invention is described below with references to the accompanying drawings in which like elements are referenced with like referenced numerals, and in which:.

The subject matter of the preferred embodiments is described with specificity however, is not intended to limit the scope of the invention. The subject matter thus, might also be embodied in other ways to include different steps, or combinations of steps, similar to the ones described herein, in conjunction with other present or future technologies. Although the term "step" may be used herein to describe different elements of methods employed, the term should not be interpreted as implying any particular order among or between various steps herein disclosed unless otherwise expressly limited by the description to a particular order. While the following description refers to oil and gas wells, the systems and methods of the present invention are not limited thereto and may also be applied to other industries to achieve similar results.

The present invention addresses several key areas for positioning targets for horizontal wells within a limited pre-defined boundary. The first assumes pads/platforms can be positioned anywhere, i.e. flat lands, little to no environmental restrictions, non-populated areas, etc. In this case, boundaries can be filled to maximize coverage. In mountainous areas where there are grade/relief issues, or in environmentally sensitive or heavily populated areas, the positioning of pads is limited and often fixed. In this case, the present invention will maximize the lateral coverage based on the fixed positioning of pads. It is also common when doing horizontal design work to have at least one well already drilled that establishes a pattern that the rest of the wells must match. This often happens with the acquisition of actual data which invalidates the current planned horizontal lateral configuration (i.e. spacing and/or lengths). In other cases, there may be no previously drilled wells, but an exact azimuth that must be used. In yet other cases, there is a general knowledge of the desired azimuth, but some flexibility over the exact azimuth. The present invention allows for various combinations of these situations to be honored when positioning targets for horizontal wells.

Referring now to <FIG>, a flowchart of one embodiment of a method for implementing the present invention is illustrated. The method <NUM> generally illustrates a workflow for determining which algorithm to use for creating targets for horizontal wells based upon a particular pattern and/or criteria. Four pattern types of horizontal targets can be generated. A concentric pattern orients horizontal target pairs tangentially around a circular shape. A radial pattern orients horizontal target pairs outward but perpendicular to a circular shape. A unidirectional pattern forces target pairs to adhere to a Heel-Toe Heel-Toe scheme whereas a bidirectional pattern forces target pairs to adhere to a Toe Heel Heel Toe scheme. Heel is used to refer to the entry point (or landing point) of the horizontal section whereas the Toe is used to indicate the termination of the horizontal well or endpoint of the horizontal lateral. After the preferred algorithm is determined, the method <NUM> reduces a collection of pairs of target (x,y) locations, which may then be processed by a method well known in the art for creating horizontal laterals from the location pairs (targets). Targets are just points that, when connected, form a horizontal lateral section. This horizontal lateral section, when connected to the origin by some trajectory, is commonly referred to as a horizontal well. Therefore, a horizontal lateral is just an incomplete horizontal well (thus, a stub). V, which is used in reference to <FIG> and other related figures, is a collection of collections of target locations and may also be referred to as a single collection, a set or an array of points. The individual collections each represent one or more pairs of target locations so there will always be an even number of them.

In step <NUM>, the method <NUM> determines if the pattern type is concentric. If the pattern type is concentric, then go to step <NUM>. If the pattern type if not concentric, then go to step <NUM>.

In step <NUM>, V is set equal to "findPerpendicularTargetLocations(Center Location,Radius). " The algorithm "findPerpendicularTargetLocations(CenterLocation, Radius)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> determines if the pattern type is radial. If the pattern type is radial, then go to step <NUM>. If the pattern type is not radial, then go to step <NUM>.

In step <NUM>, V is set equal to "findRadialTargetLocations(CenterLocation,Initial Plans). " The algorithm "findRadialTargetLocations(CenterLocation,InitialPlans)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> determines if the pattern type is bidirectional or unidirectional. If the pattern type is bidirectional or unidirectional, then go to step <NUM>. If the pattern type is not bidirectional or unidirectional, then go to step <NUM>.

In step <NUM>, the method <NUM> determines if the reference well is not equal to null. If the reference well is not equal to null, then go to step <NUM>. If the reference well is equal to null, then go to step <NUM>. Step <NUM> therefore, determines if the bidirectional or unidirectional pattern is required to line up with a reference well. If the pattern is required to line up on a reference well, then the algorithm in step <NUM> is called with that reference well. If the pattern is not required to line up on a reference well, then the algorithm in step <NUM> is called to determined which offset and azimuth provides the best coverage.

In step <NUM>, V is set equal to "findTargetLocations(ReferenceWell). " The algorithm "findTargetLocations(ReferenceWell)" is illustrated in <FIG>.

In step <NUM>, V is set equal to "findOptimalTargetLocations. " The algorithm "findOptimalTargetLocations" is located in <FIG>.

In step <NUM>, any method well known in the art for creating targets from the location pairs calculated in steps <NUM>, <NUM>, <NUM> or <NUM> may be used. An exemplary illustration of what the results might look like after performing steps <NUM> and <NUM> is shown in <FIG>, which is a plan view of an irregular boundary filled in with horizontal targets connected by horizontal laterals. It is clear that the pattern type is bidirectional and the reference well was null according to step <NUM>.

Referring now to <FIG>, one embodiment of the "findPerpendicularTarget Locations(CenterLocation,MaxRadius)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> generally creates collections of the location pairs in concentric circles, starting at the maximum radius and working inward until no target location pairs are produced.

In step <NUM>, Radius is set equal to MaxRadius, Starting Angle is set equal to zero and V is initialized as an empty collection.

In step <NUM>, V1 is set equal to "createTargetsForRadius(CenterLocation,Radius, StartingAngle). " The algorithm "createTargetsForRadius(CenterLocation,Radius,StartingAngle)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> determines if V1 is not empty. If V1 is not empty, then go to step <NUM>. If V1 is empty, then go to step <NUM>.

In step <NUM>, Location A is set equal to the first element of V1.

In step <NUM>, Location B is set equal to the second element of V1.

In step <NUM>, Location C is set equal to the midpoint of segment AB.

In step <NUM>, Radius is set equal to the distance from CenterLocation to Location C-WellSpacing. In steps <NUM>-<NUM>, the next radius inward is computed by taking the midpoint of a straight line between the first two points in the collection of location pairs and computing the distance from the CenterLocation, which represents a predetermined location for the pattern to be centered upon, to location C and subtracting the preferred WellSpacing distance. In this manner, no point on a well in one of the concentric circles will be closer than the desired WellSpacing to any point on a well in one of the other concentric circles.

In step <NUM>, Starting Angle is incremented by <NUM> degrees. In this manner, the wells in the concentric circles will overlap each other by not having a common starting point. Although <NUM> degrees is used because it is a prime number that does not divide into <NUM>, other numbers may work equally well.

In step <NUM>, the method <NUM> determines if the Radius is greater than zero. If the Radius is greater than zero, then go to step <NUM> where the method <NUM> is repeated from step <NUM>. If the Radius is not greater than zero, then go to step <NUM>.

In step <NUM>, the method <NUM> returns V to step <NUM> in <FIG>.

Referring now to <FIG>, one embodiment of the "CreateTargetsForRadius (CenterLocation,Radius,StartingAngle)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> computes a well length and spacing length in degrees rather than distance. For the spacing length, this would be the angle of an arc whose chord would be the desired spacing distance of that radius. For the well length, the calculations are more complex because the actual well length can vary. Once the two angular values have been determined in steps <NUM> and <NUM>, it is a simple matter of creating points around a circle - beginning with StartingAngle and proceeding around <NUM> degrees until the next point returns to the starting location. The angular distance would increase alternating between the angular well length and the angular spacing distance.

In step <NUM>, V is initialized as an empty collection.

In step <NUM>, LengthAngle is set equal to "computeAngularWellLengthFor Radius(Radius). " The algorithm "computeAngularWellLengthForRadius(Radius)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> determines if LengthAngle is less than zero. If LengthAngle is less than zero, which represents an error condition, then go to step <NUM>. If LengthAngle is not less than zero, then go to step <NUM>.

In step <NUM>, SpacingAngle is set equal to "findAngleOnCircle(Radius,ToeHeel Spacing)" using the angle of an arc whose chord would be the desired spacing distance at that radius.

In step <NUM>, nlats is set equal to <NUM>/(LengthAngle+SpacingAngle), Spacing Angle is set equal to (<NUM>/nlats)-LengthAngle and Angle is set equal to StartingAngle. In this manner, the number of laterals that can be created is equal to <NUM>/(the angular length of one lateral+the angular spacing distance). If, for example, each lateral was <NUM> degrees of the circle and there was a three degree spacing between laterals, then for a full circle, there would be <NUM> laterals (<NUM>/(<NUM>+<NUM>)=<NUM>). Because the spacing angle is approximate, an exact value for SpacingAngle may be obtained by dividing <NUM> by the integer number of laterals and subtracting angular length from that result. If, instead, the angular length of the laterals was <NUM>, then the SpacingAngle would be <NUM> so that the combination would result in an even <NUM> degrees.

In step <NUM>, variable I is initialized to equal zero. If I is less than nlats, then increase I by <NUM> and go to step <NUM>. If I is not less than nlats, then go to step <NUM>. Nlats is the number of laterals that were computed in step <NUM>. Therefore, the loop is repeated nlats number of times.

In step <NUM>, create a point Radius distance North of CenterLocation and rotate it clockwise by Angle. In this manner, a point is created that is a specified number of degrees clockwise from North of another point and a certain distance along that vector.

In step <NUM>, the point created in step <NUM> is added to V.

In step <NUM>, increment Angle by LengthAngle and create a point that is a Radius distance North of CenterLocation and rotate it clockwise by Angle. In this manner, a point is created that is a specified number of degrees clockwise from North of another point and a certain distance along that vector.

In step <NUM>, the point created in step <NUM> is added to V and Angle is set equal to Angle+SpacingAngle. Angle is the current angle (i.e., the angle at which the last point was created) and SpacingAngle is the preferred amount of movement around the circle before creating the next point.

In step <NUM>, the method <NUM> determines if Angle is less than <NUM> degrees+the StartingAngle and I is less than nlats. If Angle is less than <NUM>+the StartingAngle and I is less than nlats, then go to step <NUM> where the method <NUM> repeats at step <NUM> until the conditions in step <NUM> are no longer met. If Angle is not less than <NUM>+the StartingAngle and I is not less than nlats, then go to step <NUM>.

Referring now to <FIG>, one embodiment of the "ComputeAngularWellLength ForRadius(Radius)" algorithm for step <NUM> in <FIG> is illustrated. In general the method <NUM> converts minimum lateral length, maximum lateral length and toe heel spacing from distances to angles through a chord to angle calculation.

In step <NUM>, MinAngularLength is set equal to find AngleOnCircle(Radius, MinimumLateralLength) using techniques well known in the art. Find AngleOnCircle represents an angle equal to <NUM>*arcsine (chord distance/(<NUM>*radius)).

In step <NUM>, MaxAngularLength is set equal to findAngleOnCircle(Radius, MaximumLateralLength) using techniques well known in the art.

In step <NUM>, the method <NUM> determines if MaxAngularLength is less than zero. If MaxAngularLength is less than zero, then go to step <NUM>. If MaxAngularLength is not less than zero, then go to step <NUM>.

In step <NUM>, MaxLength is set equal to MaximumLateralLength-<NUM>.

In step <NUM>, MaxAngularLength is set equal to findAngleOnCircle(Radius,Max Length) using techniques well known in the art.

In step <NUM>, MaxLength is set equal to MaxLength-<NUM>.

In step <NUM>, the method <NUM> determines if MaxLength is greater than Minimum LateralLength and if MaxAngularLength is less than zero. If MaxLength is greater than MinimumLateralLength and MaxAngularLength is less than zero, then go to step <NUM> where the method <NUM> is repeated from step <NUM>. If MaxLength is not greater than MinimumLateralLength and MaxAngularLength is not less than zero, then go to step <NUM>.

In step <NUM>, the method <NUM> determines if MaxAngularLength is less than zero. If MaxAngularLength is less than zero, then go to step <NUM>. If MaxAngularLength is not less than zero, then go to step <NUM>. The process in steps <NUM> through <NUM> addresses situations where, for a particular radius, maximum lateral length is too long to convert to a chord length. When this happens, the method <NUM> keeps subtracting from maximum length until either an angular length can be computed or maximum length is less than or equal to minimum lateral length.

In step <NUM>, SpacingAngle is set equal to findAngleOnCircle(Radius,ToeHeel Spacing) using techniques well known in the art.

In step <NUM>, Length is set equal to "computeWellLengthForDistance(<NUM>-SpacingAngle,MinAngularLength,MaxAngularLength,SpacingAngle,SpacingAngle). " The algorithm "computeWellLengthForDistance(<NUM>-SpacingAngle,MinAngular Length,MaxAngularLength,SpacingAngle,SpacingAngle)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> returns Length to step <NUM> in <FIG>.

In step <NUM>, the method <NUM> returns -<NUM> to step <NUM> in <FIG>.

Referring now to <FIG>, one embodiment of the "ComputeWellLengthFor Distance(Distance,MinLength,MaxLength,Spacing1,Spacing2)" algorithm for step <NUM> in <FIG> and steps <NUM>, <NUM> in <FIG> is illustrated. The method <NUM> is generally used to calculate the best well length to use to fill a particular distance, given a minimum and a maximum possible length and two spacing distances that should be used in alternating fashion. Although the distances are normally actual distances, angles may be used as well.

In step <NUM>, the method <NUM> determines if Distance is less than MinLength-Point1. If Distance is less than MinLength-Point1, then go to step <NUM>. If Distance is not less than MinLength-Point1, then go to step <NUM>.

In step <NUM>, the method <NUM> returns zero to steps <NUM>, <NUM> or <NUM>.

In step <NUM>, the method <NUM> determines if Distance is less than or equal to Max Length. If Distance is less than or equal to MaxLength, then go to step <NUM>. If Distance is not less than or equal to MaxLength, then go to step <NUM>.

In step <NUM>, the method <NUM> returns Distance to steps <NUM>, <NUM> or <NUM>.

In step <NUM>, the method <NUM> determines if Distance is less than or equal to Max Length+Spacing1. If Distance is less than or equal to MaxLength+Spacing1, then go to step <NUM>. If Distance is not less than or equal to MaxLength+Spacing1, then go to step <NUM>.

In step <NUM>, the method <NUM> returns MaxLength to steps <NUM>, <NUM> or <NUM>.

Steps <NUM> through <NUM> are used to handle situations where the distance to be filled is smaller than the maximum length+the first spacing value. The method <NUM> generally assumes that there will be pairs of laterals, each of the same length and each pair of laterals will be separated from itself by Spacing1 and separated from the next pair of laterals by Spacing2.

In step <NUM>, TestDistance is set equal to Distance-((i*Spacing1)+((i-<NUM>)*Spacing <NUM>)). The computation in step <NUM> starts with successive numbers of paired laterals (from one up) by first subtracting all the spacing that would be required. Length checks are then performed in steps <NUM> through <NUM>. If the distance, with the spacing removed divided by the number of pairs (*<NUM>) is smaller than the maximum length, then it will be used or the minimum length will be used if it is actually smaller.

In step <NUM>, the method <NUM> determines if TestDistance/(i*<NUM>) is less than Min Length. If TestDistance/(i*<NUM>) is less than MinLength, then go to step <NUM>. If Test Distance/(i*<NUM>) is not less than MinLength, then go to step <NUM>.

In step <NUM>, the method returns MinLength to steps <NUM>, <NUM> or <NUM>.

In step <NUM>, the method <NUM> determines if TestDistance/(i*<NUM>) is less than or equal to MaxLength. If TestDistance/(i*<NUM>) is less than or equal to MaxLength, then go to step <NUM>. If TestDistance/(i*<NUM>) is not less than or equal to MaxLength, then go to step <NUM>.

In step <NUM>, the method <NUM> returns TestDistance/(i*<NUM>) to steps <NUM>, <NUM> or <NUM>.

In step <NUM>, TestDistance is set equal to TestDistance-Spacing2. In steps <NUM> through <NUM>, the assumption is made that there will not be an even number of laterals, and the last one will be only half of a pair (i.e. "i" pairs+one extra).

In step <NUM>, the method <NUM> determines if TestDistance/((i*<NUM>)+<NUM>) is less than MinLength. If TestDistance/((i*<NUM>)+<NUM>) is less than MinLength, then go to step <NUM>. If TestDistance/((i*<NUM>)+<NUM>) is not less than MinLength, then go to step <NUM>.

In step <NUM>, the method <NUM> returns MinLength to steps <NUM>, <NUM> or <NUM>.

In step <NUM>, the method <NUM> determines if TestDistance/((i*<NUM>)+<NUM>) is less than or equal to MaxLength. If TestDistance/((i*<NUM>)+<NUM>) is less than or equal to MaxLength, then go to step <NUM>. If TestDistance/((i*<NUM>)+<NUM>) is not less than or equal to MaxLength, then go to step <NUM>.

In step <NUM>, the method <NUM> returns TestDistance/((i*<NUM>)+<NUM>) to steps <NUM>, <NUM> or <NUM>.

In step <NUM>, variable i is initialized to equal zero. If i is less than or equal to <NUM>, then increase i by one and go to step <NUM>. If i is not less than or equal to <NUM>, then go to step <NUM>. The variable (i) represents the number of laterals that will fill up a predetermined linear distance.

Referring now to <FIG>, one embodiment of the "findRadialTargetLocations (CenterLocation,InitialPlans)" algorithm for step <NUM> in <FIG> is illustrated.

In step <NUM>, AngleIncr is set equal to <NUM>/InitialPlans. The InitialPlans is a predetermined initial number of plans (i.e. the size of the first set of plans radiating outwards), which is used to divide into <NUM> to obtain the initial angle increment.

In step <NUM>, a table of previous azimuths is initialized in order to keep from using the same azimuth multiple times.

In step <NUM>, Angle is initialized to equal AngleIncr. If Angle is greater than one, then divide Angle by two and go to step <NUM>. If Angle is not greater than one, then go to step <NUM>. AngleIncr is the initial separation between laterals. With each pass in the loop, Angle (the current separation) will be reduced in half. One (<NUM>) degree is used as a cutoff, but it could be another preferred number.

In step <NUM>, Distance is set equal to "findDistanceWhereSpacingWorksFor Degrees(Angle). " The algorithm "findDistanceWhereSpacingWorksForDegrees(Angle)" is illustrated in <FIG>. For a given angle in well spacing distance, there is a radius that can be used as the landing points for a sequence of wells that will be both the spacing distance apart at the landing point and that angular distance apart around the circle. Thus, a value for the distance (radius) is computed as a result of step <NUM>.

In step <NUM>, Azimuth is initialized to equal Angle. If Azimuth is less than <NUM>+ Angle, then increase the Azimuth by AngleIncr and go to step <NUM> where the method <NUM> repeats at step <NUM> until the conditions in step <NUM> are no longer met. If Azimuth is not less than <NUM>+Angle, then go to step <NUM>. This is a simple loop that increments Azimuth from its starting position (Angle) by AngleIncr until it becomes greater than or equal to Angle+<NUM>.

In step <NUM>, the method <NUM> determines if Azimuth was previously used. If Azimuth was previously used, then go to step <NUM>. If Azimuth was not previously used, then go to step <NUM>. In this manner, the Azimuth is checked against the table of previous azimuths to keep from using the same azimuth multiple times.

In step <NUM>, Azimuth is added to the table of previous azimuths.

In step <NUM>, V1 is set equal to "createTargetsForPoint(CenterLocation,Distance, Azimuth+AzimuthOffset). " The algorithm "createTargetsForPoint(CenterLocation, Distance,Azimuth+AzimuthOffset)" is illustrated in <FIG>. This algorithm is called for each azimuth around the circle (incrementing by Angle) that has not been used.

In step <NUM>, V1 is added to V and AngleIncr is set equal to Angle. In this manner, the method <NUM> is repeated until Angle is less than or equal to one in step <NUM>.

Referring now to <FIG>, one embodiment of the "FindDistanceWhereSpacing WorksForDegrees(Angle)" algorithm for step <NUM> in <FIG> is illustrated.

In step <NUM>, the method <NUM> determines if Angle is less than <NUM> degrees. If Angle is less than <NUM> degrees, then go to step <NUM>. If Angle is not less than <NUM> degrees, then go to step <NUM>. The method <NUM> therefore, effectively chooses between two trigonometric calculations (step <NUM> or step <NUM>) depending upon whether the angle requested is greater than <NUM> degrees.

In step <NUM>, the method <NUM> returns WellSpacing/Sine(Angle) to step <NUM> in <FIG>. Step <NUM> therefore, returns a standard computation for a radius, given the angle and chord length of an arc, using well spacing as the chord length.

In step <NUM>, the method <NUM> returns WellSpacing/(<NUM>*Sine(Angle/<NUM>)) to step <NUM> in <FIG>. Step <NUM> therefore, is used to compute a radius for angles less than <NUM> degrees.

Referring now to <FIG>, one embodiment of the "CreateTargetsForPoint(Point, Distance,Azimuth)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> creates two points extending from an initial point at a predetermined azimuth and then calls an algorithm in step <NUM> with those two points to get the actual sets of heal/toe locations. The two points are created at the initial radius and the maximum radius. This is done by creating points at those distances due North of the CenterLocation and rotating them.

In step <NUM>, create a point Distance North of Point and set equal to Point1.

In step <NUM>,. Point1 is rotated around Point by Azimuth.

In step <NUM>, create a point MaximumDistance North of Point and set equal to Point2.

In step <NUM>, Point2 is rotated around Point by Azimuth.

In step <NUM>, the "extract Target Locations along Segment (V, Point <NUM>, Point <NUM>)" algorithm is executed. The algorithm "extract Target Locations along Segment (V, Point <NUM>, Point <NUM>)" is illustrated in <FIG>. Optionally, other techniques well known in the art for creating two points at an initial radius and a maximum radius may be used.

Referring now to <FIG>, one embodiment of the "FindTargetLocations (ReferenceWell)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> uses a reference well to determine the azimuth and offset to be used in the "FindTarget Locations(Offset,Azimuth)" algorithm called in step <NUM>. Initially the method <NUM> extracts a point and azimuth at the end (total depth or TD) of the reference well. The method <NUM> then projects a line (Line1) running through the center location of the project area, perpendicular to the azimuth at another point (Point1) that is a maximum distance along that line from the center location. Point1 is the same point that is used for measurements in step <NUM>. The method <NUM> then projects another line (Line2) running along the azimuth from the point that was extracted from the reference well. The intersection of Line1 and Line2 is Point <NUM>. The distance between Point0 and Point1 is the offset distance from the original point. In order to get the proper offset distance to pass into step <NUM>, however, a predetermined well spacing distance must be subtracted from the offset distance until the offset distance is less than the well spacing distance.

In step <NUM>, Point is set equal to Point at TD of ReferenceWell.

In step <NUM>, Azimuth is set equal to Azimuth at TD of ReferenceWell.

At step <NUM>, Line1 is created as a line running horizontally through the center location (CenterLocation) of the project area.

In step <NUM>, Line1 is rotated by Azimuth.

In step <NUM>, Point1 is created as a Point MaxDistance along Line1 from Center Location.

In step <NUM>, Line2 is created as a line running vertically through Point.

In step <NUM>, Line2 is rotated by Azimuth.

In step <NUM>, Point0 is set equal to the intersection of Line1 and Line2.

In step <NUM>, Offset is set equal to Distance between Point0 and Point1.

In step <NUM>, the method <NUM> determines if Offset is greater than Wellspacing. If Offset if greater than Wellspacing, then go to step <NUM>. If Offset is not greater than Wellspacing, then go to step <NUM>.

In step <NUM>, Offset is set equal to Offset-WellSpacing and returns to step <NUM>.

In step <NUM>, V is set equal to "FindTargetLocations(Offset,Azimuth). " The algorithm "FindTargetLocations(Offset,Azimuth)" is illustrated in <FIG>.

Referring now to <FIG>, one embodiment of the "FindTargetLocations(Offset,Azimuth)" algorithm for step <NUM> in <FIG> and step <NUM> in <FIG> is illustrated. The method <NUM> generally projects a line (Line1) running perpendicular to the azimuth through the center location of the project area. The method <NUM> starts at a point (Point1) that is the computed maximum distance along the projected perpendicular line from the center location. The method <NUM> further places a point every well spacing distance along that line until it reaches the computed maximum distance on the other side of the center location. At each of these points, the "CreateTargetsForPoint(Point)" algorithm in step <NUM> is called to get a list of heel/toe pairs that were computed along the azimuth at that point. If that list is not empty, the method <NUM> adds it to the overall list (V), which is returned in step <NUM>.

In step <NUM>, Line1 is created as a line running horizontally through Center Location.

In step <NUM>, Distance is set equal to <NUM>*MaxDistance.

In step <NUM>, Current Position is set equal to Offset.

In step <NUM>, Point is created as Point CurrentPosition along Line1 from Point1.

In step <NUM>, Vector V1 is set equal to "CreateTargetsForPoint(Point). " The algorithm "CreateTargetsForPoint(Point)" is illustrated in <FIG>.

In step <NUM>, CurrentPosition is set equal to CurrentPosition + WellSpacing.

In step <NUM>, the method <NUM> determines if CurrentPosition is less than Distance. If CurrentPosition is less than Distance, then go step <NUM>, where the method <NUM> is repeated. If CurrentPosition is not less than Distance, then go to step <NUM>.

In step <NUM>, V is returned to step <NUM> in <FIG> or <NUM> in <FIG>.

Referring now to <FIG>, one embodiment of the "CreateTargetsForPoint (Point)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> generally creates a line through point at azimuth orientation. Points are extracted where this line intersects the boundary of the area that will be filled using the algorithm in step <NUM>. If there are any points extracted, then the extracted points may be modified by adding any points where they come within WellDistance of existing plans (if desired). For any remaining points, one of two algorithms for extracting the actual target locations in steps <NUM> or <NUM> from those sets of points may be used. If, for example, matching existing pad locations is desired, then the algorithm in step <NUM> may be used. Otherwise, the algorithm in step <NUM> may be used to derive an optimal set of target locations.

In step <NUM>, Line1 is created as a line running vertically through Point.

In step <NUM>, Point1 and Point2 are set as endpoints of Line1.

In step <NUM>, V is set equal to "ExtractPointsAlongLine(Point1,Point2). " The algorithm "ExtractPointsAlongLine(Point1,Point2)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> determines if V is not empty. If V is not empty, then go to step <NUM>. If V is empty, then go to step <NUM>.

In step <NUM>, the "ProcessExisting(V)" algorithm is executed. One embodiment of the "ProcessExisting(V)" algorithm is illustrated in <FIG>.

In step <NUM>, Location1 is set equal to V[i-<NUM>] and Location2 is set equal to V[i].

In step <NUM>, the method <NUM> determines if UsePadLocations is true. If Use PadLocations is true, then go to step <NUM>. If UsePadLocations is not true, then go to step <NUM>.

In step <NUM>, the "ExtractTargetLocationsAlongSegmentUsingPadLocations (Vout,Location1,Location2)" is executed. One embodiment of the "ExtractTarget LocationsAlongSegmentUsingPadLocations(Vout,Location1,Location2)" algorithm is illustrated in <FIG> and <FIG>.

In step <NUM>, the "ExtractTargetLocationsAlongSegment(Vout,Location1,Location2)" algorithm is executed. One embodiment of the "ExtractTargetLocationsAlong Segment(Vout,Location1,Location2)" algorithm is illustrated in <FIG>.

In step <NUM>, variable i is initialized to equal <NUM>. If i is less than V. size(), then increase i by <NUM> and go to step <NUM> where the method <NUM> is repeated. If i is not less than V. size(), then go to step <NUM>.

In step <NUM>, the method <NUM> returns Vout to step <NUM> in <FIG>. Vout is a collection of target locations.

Referring now to <FIG>, one embodiment of the "FindOptimalTargetLocations()" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> calls the "Find TargetLocations(Offset)" algorithm in a loop using various offset values to find the best offset. The method <NUM> also can do this for a range of azimuths, if necessary. In most cases, however, the azimuth is preferably fixed so that the "FindTargetLocations(Offset)" algorithm in step <NUM> is only executed once. The set of target locations found within each iteration of the inner loop (steps <NUM> through <NUM>) is evaluated based upon a simple accumulation of the distances between the heel and toe of each target location pair within that set. If that length is found to be larger than the previous MaximumLength, the MaximumLength is updated and the set of target locations is stored so that when all iterations have been run, the best set of target pair locations (VMax) can be returned to step <NUM> in <FIG>.

In step <NUM>, Increment is set equal to WellSpacing/<NUM>.

In step <NUM>, MaximumLength is set equal to zero.

In step <NUM>, AzimuthIncrement is set equal to Maximum(<NUM>(MaxAzimuth-Min Azimuth)/<NUM>).

In step <NUM>, Azimuth is initialized to equal MinAzimuth. If Azimuth is less than or equal to MaxAzimuth, then increase Azimuth by AzimuthIncrement and go to step <NUM>. If Azimuth is not less than or equal to MaxAzimuth, then go to step <NUM>.

In step <NUM>, Offset is initialized to equal zero. If Offset is less than Well Spacing, then increase Offset by Increment and go to <NUM>. If Offset is not less than WellSpacing, then go to step <NUM>.

In step <NUM>, Length is set equal to "evaluateTargetLocations(V)," which effectively runs a total for the lengths of every heel/toe pair to get a total footage for this set of target locations. Optionally, this algorithm could be run to obtain a total number of pairs or a largest average length.

In step <NUM>, the method <NUM> determines if Length is greater than Maximum Length. If Length is greater than MaximumLength, then go to step <NUM>. If Length is not greater than MaximumLength, then go to step <NUM>, where the method <NUM> repeats at step <NUM> until the conditions in step <NUM> are no longer met.

In step <NUM>, MaximumLength is set equal to Length and Vmax is set equal to V.

In step <NUM>, the method <NUM> returns VMax to step <NUM> in <FIG>.

Referring now to <FIG>, one embodiment of the "ProcessExisting(V)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> searches for point where the line from the first point in V to the last point in V crosses an existing plan. When such a point is found, two points are inserted into the collection, one WellSpacing before the intersection point and one WellSpacing after the intersection point. If the collection of points becomes larger than ten, then there are too many crossings and V is cleared before returning to step <NUM> in <FIG>.

In step <NUM>, Point1 is set equal to the first element of V.

In step <NUM>, Point2 is set equal to the last element of V.

In step <NUM>, Line1 is created as a segment from Point1 to Point2.

In step <NUM>, a loop is started for each existing plan beginning with step <NUM> through step <NUM>. Once V is greater than ten or there are no more plans, the loop exits and the method <NUM> returns to step <NUM> in <FIG>.

In step <NUM>, PointA is created as a landing point and PointB is created as a point at total depth (TD).

In step <NUM>, the method <NUM> determines if Line1 intersects segment PointA-PointB. If Line1 intersects segment PointA-PointB, then go to step <NUM>. If Line1 does not intersect segment PointA-PointB, then go to step <NUM> where the method <NUM> is repeated for another existing plan or returns to step <NUM> if there are no more plans.

In step <NUM>, Distance is set equal to the distance between Point1 and Intersection, which is the intersection of Line1 and segment PointA-PointB.

In step <NUM>, Location1 is created as a point Distance-WellSpacing along Line1.

In step <NUM>, Location2 is created as point Distance+WellSpacing along Line1.

In step <NUM>, Location1 and Location2 are inserted into V, which is ordered by distance from Point1.

In step <NUM>, the method <NUM> determines if the Size of V is greater than <NUM>. If the Size of V is greater than <NUM>, then go to step <NUM>. If the Size of V is not greater than <NUM>, then go to step <NUM> as the method <NUM> is repeated for another existing plan or returns to step <NUM> if there are no more plans.

In step <NUM>, the method <NUM> returns to step <NUM>.

Referring now to <FIG>, one embodiment of the "ExtractPointsAlongLine (Point1,Point2)" algorithm in <FIG> is illustrated. The method <NUM> generally takes two points and uses the algorithm (IsGood) in step <NUM> and step <NUM> to determine whether a particular point is in an acceptable area for targeting and to derive a set of intersection points such that the area between the first and second point will be in the acceptable area, the area between the second and third point will be out of the acceptable area, and so on. If there are no points along the line between Point1 and Point <NUM> that are in the acceptable area, then the set (V) that is returned in step <NUM> will be empty.

In step <NUM>, Increment is set equal to <NUM>, MinimumDistance is set equal to <NUM> and LastLocation is set equal to Point1.

In step <NUM>, LastGood is set equal to IsGood(LastLocation). In this manner, the previous point tested can be tracked to determine whether it was in the acceptable area for targeting or out of the acceptable area for targeting. IsGood(LastLocation) therefore, may be any means well known in the art for deciding whether a particular x,y location (point) is a valid location for horizontal drilling and may include, for example, using boundaries and/or grids.

In step <NUM>, the method <NUM> determines whether LastGood is true. If Last Good is true, then go to step <NUM>. If LastGood is not true, then go to step <NUM>.

In step <NUM>, Point1 is added to V. If the initial point is good, then LastGood is true and the initial point will be added to the set (V).

In step <NUM>, TotalDistance is set equal to distance from Point1 to Point2.

In step <NUM>, Distance is initialized to equal Increment. If Distance is less than TotalDistance, then increase Distance by Increment and go to step <NUM>. If Distance is not less than TotalDistance, then go to step <NUM>.

In step <NUM>, Point is created as a point distance along a line from Point1 to Point2.

In step <NUM>, CurrentGood is set equal to IsGood(Point).

In step <NUM>, the method <NUM> determines if CurrentGood does not equal Last Good. If CurrentGood does not equal LastGood, then go step <NUM>. If CurrentGood equals LastGood, then go to step <NUM>. In this manner, the method <NUM> searches for the boundary points where a point on one side will be good and a point on the other side will be bad.

In step <NUM>, the method <NUM> determines if LastGood is true. If LastGood is true, then go to step <NUM>. If LastGood is not true, then go to step <NUM>. In this manner, the method <NUM> searches for the boundary points where a point on one side will be good and a point on the other side will be bad. Since the method <NUM> for searching the boundary works based upon an ordered set of a good point and a bad point, it is ordered one way when going from good to bad according to step <NUM>, and it is ordered another way when going from bad to good according to step <NUM>.

In step <NUM>, getIntercept(Point,LastLocation,MinimumDistance) is added to V. The getIntercept(Point,LastLocation,MinimumDistance) algorithm may employ techniques well known in the art for finding the point along a line where the acceptance criteria goes from good to bad within a specified minimum distance.

In step <NUM>, getIntercept(LastLocation,Point,MinimumDistance) is added to V. The getIntercept(Point,LastLocation,MinimumDistance) algorithm may employ techniques well known in the art for finding the point along a line where the acceptance criteria goes from good to bad within a specified minimum distance.

In step <NUM>, LastGood is set equal to CurrentGood and LastLocation is set equal to Point.

In step <NUM>, the method <NUM> determines if IsGood(Point) is true. If IsGood (Point) is true, then go to step <NUM>. If IsGood(Point) is not true, then go to step <NUM>.

Referring now to <FIG>, one embodiment of the "ExtractTargetLocations AlongSegment(Vout,Location1,Location2)" algorithm for step <NUM> in <FIG> and step <NUM> in <FIG> is illustrated. The method <NUM> generally takes some interval between two points and divides it into a set of equal length heel/toe pairs that follow certain spacing rules. The spacing values can be either a toeheel distance if the wells are to be laid out in a heel-toe (i.e., all facing the same direction) or a heelheel and a toetoe distance if the wells are to be laid out in a toe-heel heel-toe sequence. The latter sequence is typically used when a drilling pad is to be placed between the two heels, so the heelheel spacing is typically a fairly large value to allow for the wells to build to horizontal in both directions. In addition to the fixed spacing's and the computed well length that is somewhere between a predetermined minimum and maximum lateral length, there is often additional space remaining. This space will either be divided equally between the two ends or all placed at the beginning of the sequence or the end of the sequence depending upon the justification value determined in steps <NUM>-<NUM>. The remaining space is addressed by setting the initial CurrentPosition in step <NUM>. If the pattern type is bidirectional (toe-heel heel-toe), each iteration will create up to four locations (for two laterals). Otherwise, each iteration will only create a maximum of two locations (one lateral).

In step <NUM>, Distance is set equal to distance from Location1 to Location2.

In step <NUM>, WellLength is set equal to "computeWellLengthForDistance (Distance). " The algorithm "computeWellLengthForDistance(Distance)" is illustrated in <FIG>.

In step <NUM>, the method <NUM> determines if WellLength equals zero. If Well Length equals zero, then go to step <NUM>. If WellLength does not equal zero, then go to step <NUM>.

In step <NUM>, the method <NUM> returns to step <NUM> or step <NUM>.

In step <NUM>, an algorithm for ComputeLeftover(Distance,WellLength) is executed. Using techniques well known in the art, the leftover amount is computed by taking the total distance and successively subtracting the distance for the well length and either the HeelHeelSpacing, the ToeToeSpacing or the HeelToeSpacing as appropriate, until an amount that is greater than or equal to zero and less than the well length+the appropriate spacing is achieved.

In step <NUM>, the method <NUM> determines if Justification is LEFT. If Justification is LEFT, then go to step <NUM>. If Justification is not LEFT, then go to step <NUM>.

In step <NUM>, CurrentPosition is set equal to zero.

In step <NUM>, the method <NUM> determines if Justification is RIGHT. If Justification is RIGHT, then go to step <NUM>. If Justification is not RIGHT, then go to step <NUM>.

In step <NUM>, CurrentPosition is set equal to LeftOver.

In step <NUM>, CurrentPosition is set equal to LeftOver/<NUM>.

In step <NUM>, the method <NUM> determines if CurrentPosition+WellLength is greater than Distance. If CurrentPosition+WellLength is greater than Distance, then go to step <NUM>, If CurrentPosition+WellLength is not greater than Distance, then go to step <NUM>.

In step <NUM>, WellLength is set equal to Distance-CurrentPosition.

In step <NUM>, the method <NUM> determines if WellLength is less than Minimum LateralLength. If WellLength is less than MinimumLateralLength, then go to step <NUM>. If WellLength is not less than MinimumLateralLength, then go to step <NUM>.

In step <NUM>, Location is created as a Point CurrentPosition from Point1 along Line1.

In step <NUM>, Location is added to Vout.

In step <NUM>, CurrentPosition is incremented by WellLength.

In step <NUM>, the method <NUM> determines if the PatternType is BIDIRECTIONAL. If the PatternType is BIDIRECTIONAL, then go to step <NUM>, If the Pattern Type is not BIDIRECTIONAL, then go to step <NUM>.

In step <NUM>, CurrentPosition is incremented by ToeHeelSpacing.

In step <NUM>, CurrentPosition is incremented by HeelHeelSpacing.

In step <NUM>, CurrentPosition is incremented by ToeToeSpacing.

In step <NUM>, the method <NUM> is repeated in a loop while CurrentPosition is less than Distance and is repeated at step <NUM>. If CurrentPosition is not less than Distance, then the loop command in step <NUM> proceeds to step <NUM>.

Referring now to <FIG>, one embodiment of the "ComputeWellLengthFor Distance(Distance)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> generally checks to determine if the PatternType is BIDIRECTIONAL and then calls the "ComputeWellLengthForDistance" algorithm for either HeelHeelSpacing and ToeToe Spacing or just ToeHeelSpacing as the spacing parameters.

In step <NUM>, the method <NUM> determines if the PatternType is BIDIRETIONAL. If the PatternType is BIDIRETIONAL, then go to step <NUM>. If the PatternType is not BIDIRETIONAL, then go to step <NUM>.

In step <NUM>, the "ComputeWellLengthForDistance(Distance,MinimumLateral Length,MaximumLateralLength, HeelHeelSpacing,ToeToeSpacing)" algorithm is executed. One embodiment of this algorithm is illustrated in <FIG>, which is described hereinabove.

In step <NUM>, the method <NUM> returns WellLength to step <NUM> in <FIG>.

In step <NUM>, the "ComputeWellLengthForDistance(Distance,MinimumLateral Length,MaximumLateralLength, ToeHeelSpacing,ToeHeelSpacing)" algorithm is executed. On embodiment of this algorithm is illustrated in <FIG>, which is described hereinabove.

Referring now to <FIG> and <FIG>, one embodiment of the "Extract TargetLocationsAlongSegmentUsingPadLocations(Vout,Location1,Location2)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> addresses the need to honor specific pad locations when planning lateral wells. Rather than attempting to fit as many lateral wells as possible between the multiple pad locations, the method <NUM> identifies points along the line between Location1 and Location2 that are both far enough from each end of that line to meet the minimum lateral length restrictions and close enough to one of the pad locations to be reached from that pad without being so close to the pad that there is no room to build a lateral well to <NUM> degrees.

In step <NUM>, Distance is set equal to distance between Location1 and Location2.

In step <NUM>, the method <NUM> determines if Distance is less than Minimum LateralLength. If Distance is less than MinimumLateralLength, then go to step <NUM>. If Distance is not less than MinimumLateralLength, then go to step <NUM>. This step checks to make sure that the distance between the two points (Location1 and Location2) is at least as large as the MinimumLateralLength.

In step <NUM>, Distance1 is set equal to "FindFirstDirectionalHeel(Location1, Location2). " The algorithm "FindFirstDirectionalHeel(Location1,Location2)" is illustrated in <FIG>. This step locates the first directional heel distance along the line. This is the distance to the first location along the line that can serve as the landing point for a lateral well that is heading in the same direction as the line segment. This distance is represented by Distance1. Distance1 may equal Distance in step <NUM> (i.e., the total distance between Location1 and Location2 if FindFirstDirectionalHeel was unsuccessful.

In step <NUM>, the method <NUM> determines if the Pattern is BIDIRECTIONAL. If the Pattern is BIDIRECTIONAL, then go to step <NUM>. If the Pattern is not BIDIRECTIONAL, then go to step <NUM> in <FIG>. Therefore, if the Pattern is BIDIRECTIONAL, the method <NUM> will identify the point along the line prior to the Distance1 point at which it will start searching in the other direction for the opposite facing lateral well.

In step <NUM>, NewDistance is set equal to Distance1.

In step <NUM>, the method <NUM> determines if Distance1 is less than Distance. If Distance1 is less than Distance, then go to step <NUM>. If Distance1 is not less than Distance, then go to step <NUM>.

In step <NUM>, NewDistance is set equal to NewDistance-HeelHeelSpacing.

In step <NUM>, NewPoint is created as a point NewDistance Along a line between Location1 and Location2. This point (NewPoint) is now used in the algorithm for step <NUM> as the first point.

In step <NUM>, Distance1 is set equal to "FindFirstDirectionalHeel(NewPoint, Location1). " The algorithm "FindFirstDirectionalHeel(NewPoint,Location1)" is illustrated in <FIG>.

In step <NUM>, Distance2 is set equal to New Distance-Distance1. Distance2 therefore, is the distance from Point1 to the first possible landing point along the segment from NewPoint to Point1.

In step <NUM>, the method <NUM> determines if Distance2 is greater than zero. If Distance2 is greater than zero, then go to step <NUM>. If Distance2 is not greater than zero, then go to step <NUM> in <FIG>. Therefore, if Distance2 is zero, no landing point was found.

In step <NUM>, Length is set equal to Distance2-MaximumLateralLength.

In step <NUM>, the method <NUM> determines if the Length is less than zero. If Length is less than zero, then go to step <NUM>. If Length is not less than zero, then go to step <NUM>.

In step <NUM>, Length is set equal to zero.

In step <NUM>, Heel is created as a point Distance2 along a line between Location <NUM> and Location2.

In step <NUM>, the method <NUM> determines if Distance2-Length is greater than or equal to MinimumLateralLength. If Distance2-Length is greater than or equal to MinimumLateralLength, then go to step <NUM>. If Distance2-Length is not greater than or equal to MinimumLateralLength, then go to step <NUM>.

In step <NUM>, Toe is created as a point Length along a line between Location1 and Location2 and Heel and Toe are each added to Vout.

In step <NUM>, the "CheckForOverlappingToes(Vout,Heel)" algorithm is executed. This algorithm is executed to determine if there is still a way to plan a lateral well. One embodiment of this algorithm is illustrated in <FIG>.

In step <NUM>, NewDistance is set equal to zero.

In step <NUM>, Heel is created as a point Distance1 along a line between Location <NUM> and Location2 and Length is set equal to Distance1+MaximumLateralLength.

In step <NUM>, the method <NUM> determines if the Length is less than Distance. If Length is less than Distance, then go to step <NUM>. If Length is not less than Distance, then go to step <NUM>.

In step <NUM>, Length is set equal to Distance.

In step <NUM>, the method <NUM> determines if Length-Distance1 is greater than or equal to MinimumLateralLength. If Length-Distance1 is greater than or equal to MinimumLateralLength, then go to step <NUM>. If Length-Distance1 is not greater than or equal to MinimumLateralLength, then go to step <NUM>.

In step <NUM>, Toe is created as a point Length along a line between Location1 and Location2, Heel and Toe are each added to Vout, and NewDistance is set equal to Length + ToeToeSpacing.

In step <NUM>, the method <NUM> determines if NewDistance is greater than zero. If NewDistance is greater than zero, then go to step <NUM>. If NewDistance is not greater than zero, then go to step <NUM>.

In step <NUM>, NewPoint is created as a point NewDistance along a line between Location1 and Location2.

In step <NUM>, the "ExtractTargetLocationsAlongSegmentUsingPadLocations (Vout,NewPoint,Location2)" algorithm is executed. Basically, the method <NUM> is called recursively for (Vout,NewPoint,Location2).

Referring now to <FIG>, one embodiment of the "FindFirstDirectionalHeel (Location1,Location2)" algorithm for step <NUM> and step <NUM> in <FIG> is illustrated. The method <NUM> generally looks for the first point along the line segment that could be used as a heel or landing point, based upon a set of known pad locations. Method <NUM> incrementally traverses the line segment.

In step <NUM>, Increment is set equal to <NUM>. Other increments may be used, however, depending upon the desired accuracy and performance efficiency.

In step <NUM>, DesiredAzimuth is set equal to Azimuth from Location1 to Location2.

In step <NUM>, CurrentPosition is initialized to equal zero. If CurrentPosition is less than Distance, then increase CurrentPosition by Increment and go to step <NUM>. If CurrentPosition is not less than Distance, then go to step <NUM>.

In step <NUM>, Point is created as a point CurrentPosition along a line between Location1 and Location2.

In step <NUM>, a loop is started for each pad in a pre-defined project beginning with step <NUM> through step <NUM>. Each pad is checked against the Point created in step <NUM> and after all of the pads in the project are checked against that Point, the control loops back to step <NUM> to define another Point and check each pad against that Point.

In step <NUM>, PadDistance is set equal to Distance from point to Pad.

In step <NUM>, the method <NUM> determines if PadDistance is greater than MaximumLandingDistance. If PadDistance is greater than MaximumLandingDistance, then go to step <NUM>. If PadDistance is not greater than MaximumLandingDistance, then go to step <NUM>. MaximumLandingDistance is defined as the number of slots in the pad divided by two (for each direction sideways) and dividing by two again if there are stacked lateral wells, and dividing by two again if the pattern is bidirectional. The result is multiplied by WellSpacing. Therefore, a pad with eight slots that is bidirectional, but not stacked, will have a maximum landing distance of <NUM>*WellSpacing so it can extend out far enough to pick up two lateral wells in each direction on each side for a total of eight, which matches the number of slots.

In step <NUM>, the method <NUM> determines if PadDistance is less than Minimum LandingDistance. If PadDistance is less than MinimumLandingDistance, then go to step <NUM>. If PadDistance is not less than MinimumLandingDistance, then go to step <NUM>. MinimumLandingDistance is the distance that it takes for the well to build to a vertical position. MinimumLandingDistance therefore, may be designed as one-half of the Heel HeelSpacing since the HeelHeelSpacing is intended to be the distance that it takes two wells building in opposite directions to reach <NUM> degrees.

In step <NUM>, Azimuth is set equal to Azimuth from Pad to point.

In step <NUM>, DeltaAzimuth is set to Absolute value of Azimuth-Desired Azimuth.

In step <NUM>, MaximumDelta is set equal to <NUM>-ArcSine(MinimumLanding Distance/PadDistance). This computation is intended to create landing points that line up a straight line perpendicular to the desired Azimuth instead of in an arc around the pad.

In step <NUM>, the method <NUM> determines if DeltaAzimuth is greater than MaximumDelta. If DeltaAzimuth is greater than MaximumDelta, then go to step <NUM>. If DeltaAzimuth is not greater than MaximumDelta, then go to step <NUM>.

In step <NUM>, the method <NUM> determines if Segment from Pad to Point intersects any hazards. If Segment from Pad to Point intersects any hazards, then go to step <NUM>. If Segment from Pad to Point does not intersect any hazards, then go to step <NUM>.

In step <NUM>, the method <NUM> returns CurrentPosition to step <NUM> or step <NUM> in <FIG>. CurrentPosition is the current distance along the segment between Location1 and Location2. Since it is being returned, it is the distance at the first point checked that is the proper distance and at an acceptable angle from a pad. If unsuccessful, the total length of the segment (distance) is returned in step <NUM>.

In step <NUM>, the method <NUM> returns Distance to step <NUM> or step <NUM> in <FIG>.

Referring now to <FIG>, one embodiment of the "CheckForOverlappingtoes (Vout,Heel)" algorithm for step <NUM> in <FIG> is illustrated. The method <NUM> generally addresses the special-case situation where a particular landing point for reverse-facing lateral well cannot be planned because the previously-planned forward-facing lateral well was planned to be a maximum lateral length from heel to toe and there is not enough distance between the two heels for a maximum lateral length lateral well, plus a minimum lateral length lateral well, plus the toe toe spacing distance, but there is enough room for two minimum lateral length (or greater) lateral wells plus the toe toe spacing. The method <NUM> therefore, generally establishes that the second to last location in the set Vout is the heel of a heel toe pair that is both in the same line as the new reverse-facing heel, and is an appropriate distance for the toes to be adjusted. Once this is established, then it is a simple matter to remove the last two, subtract the toe toe spacing from the distance between the two heels and divide the difference by two to get the lengths for the two lateral wells and create new toe points at that distance from the two heels. Both new toes and the new heel can then be added to the set Vout.

In step <NUM>, the method <NUM> determines if the Size of Vout is less than <NUM>. If the Size of Vout is less than <NUM>, then go to step <NUM>. If the Size of Vout is not less than <NUM>, then go to step <NUM>.

In step <NUM>, LocationH is set equal to the second to last element of Vout and LocationT is set equal to the last element of Vout.

In step <NUM>, the method <NUM> determines if Azimuth from LocationH to Heel is not equal to Azimuth from LocationT to Heel. If Azimuth from LocationH to Heel is not equal to Azimuth from LocationT to Heel, then go to step <NUM>. If Azimuth from LocationH to Heel is equal to Azimuth from LocationT to Heel, then go to step <NUM>.

In step <NUM>, the method <NUM> determines if Distance from LocationT to Heel is greater than MinimumLateralLength+ToeToeSpacing. If Distance from LocationT to Heel is greater than MinimumLateralLength+ToeToeSpacing, then go to step <NUM>. If Distance from LocationT to Heel is not greater than MinimumLateralLength+ToeToe Spacing, then go to step <NUM>.

In step <NUM>, Distance is set equal to Distance from LocationH to Heel.

In step <NUM>, the method <NUM> determines if Distance is less than (<NUM>*Minimum LateralLength)+ToeToeSpacing. If Distance is less than (<NUM>*MinimumLateralLength)+ ToeToeSpacing, then go to step <NUM>. If Distance is not less than (<NUM>*MinimumLateral Length)+ToeToeSpacing, then go to step <NUM>.

In step <NUM>, Length is set equal to (Distance-ToeToeSpacing)/<NUM>.

In step <NUM>, LocationT is removed from Vout.

In step <NUM>, LocationT is created as a point Length along segment from LocationH to Heel.

The present invention therefore, enables boundary areas to be filled with either single or stacked horizontal laterals. Initially, concentric and radial horizontal laterals can also be generated using the present invention. Pre-defined parameters dictate the geometry and orientation that will be used to position and fill in the boundary area. Internal boundary areas can be defined such that horizontal laterals could be truncated, if necessary. Additionally, if there is faulting in the boundary area, faults could be used to terminate horizontal laterals and start new horizontal laterals a certain distance from the fault. The present invention also permits horizontal laterals to be placed on a specific subsurface grid for proper depth placement and can be offset from same if necessary to maintain a specific distance from an oil/water contact, for example. Unilateral and bilateral direction can be specified and in the latter case, recommended heel/heel separation can be computed to insure optimal position for pads.

The present invention may be implemented through a computer-executable program of instructions, such as program modules, generally referred to as software applications or application programs executed by a computer. The software may include, for example, routines, programs, objects, components, and data structures that perform particular tasks or implement particular abstract data types. The software forms an interface to allow a computer to react according to a source of input. AssetPlanner™, which is a commercial software application marketed by Landmark Graphics Corporation, may be used as an interface application to implement the present invention. The software may also cooperate with other code segments to initiate a variety of tasks in response to data received in conjunction with the source of the received data. The software may be stored and/or carried on any variety of memory media such as CD-ROM, magnetic disk, bubble memory and semiconductor memory (e.g., various types of RAM or ROM). Furthermore, the software and its results may be transmitted over a variety of carrier media such as optical fiber, metallic wire and/or through any of a variety of networks such as the Internet.

Moreover, those skilled in the art will appreciate that the invention may be practiced with a variety of computer-system configurations, including hand-held devices, multiprocessor systems, microprocessor-based or programmable-consumer electronics, minicomputers, mainframe computers, and the like. Any number of computer-systems and computer networks are acceptable for use with the present invention. The invention may be practiced in distributed-computing environments where tasks are performed by remote-processing devices that are linked through a communications network. In a distributed-computing environment, program modules may be located in both local and remote computer-storage media including memory storage devices. The present invention may therefore, be implemented in connection with various hardware, software or a combination thereof, in a computer system or other processing system.

Referring now to <FIG>, a block diagram of a system for implementing the present invention on a computer is illustrated. The system includes a computing unit, sometimes referred to as a computing system, which contains memory, application programs, a database, a viewer, ASCII files, a client interface, a video interface and a processing unit. The computing unit is only one example of a suitable computing environment and is not intended to suggest any limitation as to the scope of use or functionality of the invention.

The memory primarily stores the application programs, which may also be described as program modules containing computer-executable instructions, executed by the computing unit for implementing the present invention described herein and illustrated in <FIG>. The memory therefore, includes OpenWorks™, which may be used as a database to supply data and/or store data results such as, for example, subsurface grids and surface elevations. ASCII files may also be used to supply data and/or store the data results. The memory also includes AssetView™, which may be used as a viewer to display the data and data results such as, for example, map images, surface and subsurface grids loaded from Open Works™ into AssetView™ that are used to define the lease or acreage boundaries. The horizontal targeting module in AssetPlanner™ uses pre-defined lease, acreage or grid boundaries to determine the spacing and positioning requirements for the horizontal laterals - also referred to as targets or target pairs. Subsurface 3D grids loaded into AssetView™ may also be used as boundaries. In one application, for example, polygonal areas may be drawn directly in AssetView™ and defined as boundaries using the client interface and TracPlanner™. In another application, for example, a polygonal area could also be defined directly in TracPlanner™ using the client interface or by importing from the ASCII file as specified by the client interface. Once the boundaries are defined, the client interface may be used to enter horizontal targeting parameters. These parameters dictate the desired horizontal pattern type, lengths, spacing and azimuth, which are processed by the horizontal targeting module in AssetPlanner™ to generate the desired horizontal targeting pattern. The desired horizontal targeting pattern therefore, is used to position horizontal laterals (or target pairs) within the boundaries. The horizontal targeting module processes the foregoing data using the methods described herein and illustrated in <FIG> to generate the desired horizontal targeting pattern(s). TracPlanner™, AssetView™ and - OpenWorks™ are commercial software application marketed by Landmark Graphics Corporation.

Although the computing unit is shown as having a generalized memory, the computing unit typically includes a variety of computer readable media. By way of example, and not limitation, computer readable media may comprise computer storage media. The computing system memory may include computer storage media in the form of volatile and/or nonvolatile memory such as a read only memory (ROM) and random access memory (RAM). A basic input/output system (BIOS), containing the basic routines that help to transfer information between elements within the computing unit, such as during start-up, is typically stored in ROM. The RAM typically contains data and/or program modules that are immediately accessible to and/or presently being operated on by the processing unit. By way of example, and not limitation, the computing unit includes an operating system, application programs, other program modules, and program data.

The components shown in the memory may also be included in other removable/nonremovable, volatile/nonvolatile computer storage media or they may be implemented in the computing unit through application program interface ("API"), which may reside on a separate computing unit connected through a computer system or network. For example only, a hard disk drive may read from or write to nonremovable, nonvolatile magnetic media, a magnetic disk drive may read from or write to a removable, non-volatile magnetic disk, and an optical disk drive may read from or write to a removable, nonvolatile optical disk such as a CD ROM or other optical media. Other removable/non-removable, volatile/non-volatile computer storage media that can be used in the exemplary operating environment may include, but are not limited to, magnetic tape cassettes, flash memory cards, digital versatile disks, digital video tape, solid state RAM, solid state ROM, and the like. The drives and their associated computer storage media discussed above provide storage of computer readable instructions, data structures, program modules and other data for the computing unit.

A client may enter commands and information into the computing unit through the client interface, which may be input devices such as a keyboard and pointing device, commonly referred to as a mouse, trackball or touch pad. Input devices may include a microphone, joystick, satellite dish, scanner, or the like. These and other input devices are often connected to the processing: unit through a system bus, but may be connected by other interface and bus structures, such as a parallel port or a universal serial bus (USB).

A monitor or other type of display device may be connected to the system bus via an interface, such as a video interface. A graphical user interface ("GUI") may also be used with the video interface to receive instructions from the client interface and transmit instructions to the processing unit. In addition to the monitor, computers may also include other peripheral output devices such as speakers and printer, which may be connected through an output peripheral interface.

Although many other internal components of the computing unit are not shown, those of ordinary skill in the art will appreciate that such components and their interconnection are well known.

Claim 1:
A computer-implemented method of determining subsurface target locations for horizontal wells to be drilled within a predetermined boundary, which comprises:
selecting a reference well within the predetermined boundary;
determining a first point and an azimuth direction at total depth of the reference well;
creating a first line that is perpendicular to the azimuth direction and passes through a center location of the predetermined boundary;
creating a second point on the first line at a maximum distance from the center location within the predetermined boundary;
determining an offset distance, based on a predetermined well spacing distance and an initial offset distance along the first line between the second point and a third point defined by an intersection of the first line and a second line running along the azimuth direction from the first point, by subtracting the predetermined well spacing distance from the offset distance until the offset distance is less than the predetermined well spacing distance;
creating a series of points along the first line beginning at a point which is offset by the offset distance from the second point on the first line until reaching twice the maximum distance, each point in the series of points being separated from another point in the series of points by the predetermined well spacing distance; and
computing a list of heel/toe pairs for each point in the series of points and adding the list for each point in the series of points to a collection of lists comprising heel/toe pairs as each list is computed, the collection of lists representing the target locations within the predetermined boundary, each heel and toe pair representing a horizontal lateral section of a horizontal well to be drilled,
wherein computing a list of heel/toe pairs for a selected point in the series of points comprises:
creating a third line through the selected point along the azimuth direction;
extracting points at which the third line intersects the predetermined boundary; and
dividing the interval between the points at which the third line intersects the predetermined boundary into a set of equal length heel/toe pairs according to a spacing rule.