Skip to content

Commit

Permalink
Add options to normalize length of welbore for cases where wellbore c…
Browse files Browse the repository at this point in the history
…urve length differ from recorded drilled length. (#415)

Add options to set tension and arc division for curve
Fixed some reference system tests
  • Loading branch information
HavardNJ authored Jan 22, 2021
1 parent c0c7958 commit 86f715c
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 36 deletions.
55 changes: 30 additions & 25 deletions src/control/IntersectionReferenceSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export class IntersectionReferenceSystem {

private setPath(path: number[][], options: ReferenceSystemOptions = {}): void {
this.options = options;
const { calculateDisplacementFromBottom } = this.options;
const { arcDivisions, tension, calculateDisplacementFromBottom } = this.options;

this.path = path;

Expand All @@ -81,9 +81,9 @@ export class IntersectionReferenceSystem {
curve: new CurveInterpolator(path),
trajectory: new CurveInterpolator(
path.map((d: number[]) => [d[0], d[1]]),
{ tension: TENSION, arcDivisions: ARC_DIVISIONS },
{ tension: tension || TENSION, arcDivisions: arcDivisions || ARC_DIVISIONS },
),
curtain: new CurveInterpolator(this.projectedPath, { tension: TENSION, arcDivisions: ARC_DIVISIONS }),
curtain: new CurveInterpolator(this.projectedPath, { tension: tension || TENSION, arcDivisions: arcDivisions || ARC_DIVISIONS }),
};

const trajVector = this.getTrajectoryVector();
Expand All @@ -105,10 +105,10 @@ export class IntersectionReferenceSystem {
*/
project(length: number): number[] {
const { curtain } = this.interpolators;
const { calculateDisplacementFromBottom } = this.options;
const { normalizedLength, calculateDisplacementFromBottom } = this.options;

const normalizedLength = (length - this._offset) / this.length;
const l = calculateDisplacementFromBottom ? 1 - normalizedLength : normalizedLength;
const factor = (length - this._offset) / (normalizedLength || this.length);
const l = calculateDisplacementFromBottom ? 1 - factor : factor;

const t = clamp(l, 0, 1);
const p = curtain.getPointAt(t);
Expand Down Expand Up @@ -157,19 +157,20 @@ export class IntersectionReferenceSystem {
* Map a displacement back to length along the curve
*/
unproject(displacement: number): number {
const { calculateDisplacementFromBottom } = this.options;
const { normalizedLength, calculateDisplacementFromBottom } = this.options;
const displacementFromStart = calculateDisplacementFromBottom ? this.displacement - displacement : displacement;
const length = normalizedLength || this.length;

if (displacementFromStart < 0) {
return displacementFromStart;
}
if (displacementFromStart > this.displacement) {
return this.length + (displacementFromStart - this.displacement);
return length + (displacementFromStart - this.displacement);
}

const ls = this.interpolators.curtain.lookupPositions(displacementFromStart, 0, 1);
if (ls && ls.length) {
return ls[0] * this.length + this._offset;
return ls[0] * length + this._offset;
}
return null;
}
Expand Down Expand Up @@ -259,26 +260,30 @@ export class IntersectionReferenceSystem {
/**
* Generate a set of coordinates along the trajectory of the curve
*/
getExtendedTrajectory(steps: number, extensionStart = DEFAULT_START_EXTEND_LENGTH, extensionEnd = DEFAULT_END_EXTEND_LENGTH): Trajectory {
if (!isFinite(extensionStart) || extensionStart < 0.0) {
throw new Error('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive extensionStart parameter');
getExtendedTrajectory(
numPoints: number,
startExtensionLength = DEFAULT_START_EXTEND_LENGTH,
endExtensionLength = DEFAULT_END_EXTEND_LENGTH,
): Trajectory {
if (!isFinite(startExtensionLength) || startExtensionLength < 0.0) {
throw new Error('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive startExtensionLength parameter');
}
if (!isFinite(extensionEnd) || extensionEnd < 0.0) {
throw new Error('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive extensionEnd parameter');
if (!isFinite(endExtensionLength) || endExtensionLength < 0.0) {
throw new Error('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive endExtensionLength parameter');
}

const totalLength = this.displacement + extensionStart + extensionEnd;
const preSteps = Math.floor((extensionStart / totalLength) * steps);
const curveSteps = Math.max(Math.ceil((this.displacement / totalLength) * steps), 1);
const postSteps = steps - curveSteps - preSteps;
const totalLength = this.displacement + startExtensionLength + endExtensionLength;
const startExtensionNumPoints = Math.floor((startExtensionLength / totalLength) * numPoints);
const curveSteps = Math.max(Math.ceil((this.displacement / totalLength) * numPoints), 1);
const endExtensionNumPoints = numPoints - curveSteps - startExtensionNumPoints;

const points = [];

const refStart = new Vector2(this.interpolators.trajectory.getPointAt(0.0));
const startVec = new Vector2(this.startVector);
const preStep = extensionStart / preSteps;
for (let i = preSteps; i > 0; i--) {
const f = i * preStep;
const startExtensionStepLength = startExtensionLength / startExtensionNumPoints;
for (let i = startExtensionNumPoints; i > 0; i--) {
const f = i * startExtensionStepLength;
const point = refStart.add(startVec.scale(f));
points.push(point.toArray());
}
Expand All @@ -287,14 +292,14 @@ export class IntersectionReferenceSystem {

const refEnd = new Vector2(this.interpolators.trajectory.getPointAt(1.0));
const endVec = new Vector2(this.endVector);
const postStep = extensionEnd / postSteps;
for (let i = 1; i < postSteps; i++) {
const f = i * postStep;
const endExtensionStepLength = endExtensionLength / (endExtensionNumPoints - 1); // -1 so last point is at end of extension
for (let i = 1; i < endExtensionNumPoints; i++) {
const f = i * endExtensionStepLength;
const point = refEnd.add(endVec.scale(f));
points.push(point.toArray());
}

const offset = -extensionStart;
const offset = -startExtensionLength;

return { points, offset };
}
Expand Down
3 changes: 3 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ export interface Trajectory {
}

export interface ReferenceSystemOptions {
normalizedLength?: number;
arcDivisions?: number;
tension?: number;
trajectoryAngle?: number;
calculateDisplacementFromBottom?: boolean;
}
Expand Down
58 changes: 47 additions & 11 deletions test/reference-system.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { degrees } from '@equinor/videx-math';
import { IntersectionReferenceSystem } from '../src';

const wp = [
Expand All @@ -16,7 +17,7 @@ function dist(a: number[], b: number[]): number {
describe('Reference system', () => {
let rs: IntersectionReferenceSystem;
beforeEach(() => {
rs = new IntersectionReferenceSystem(wp);
rs = new IntersectionReferenceSystem(wp, { trajectoryAngle: 0 });
});
it('should set path on creation', () => {
expect(rs.path).not.toEqual(undefined);
Expand Down Expand Up @@ -82,16 +83,15 @@ describe('Reference system', () => {
expect(trajectory.points.length).toEqual(100);
});

/* TODO: Issue is now solved and tests can be fixed and uncommented
* Jest failed previously due to not finding Vector2 constructor.

it('should have same distance between points in extended trajectory', () => {
const trajectory = rs.getExtendedTrajectory(200, 500.0, 500.0);
const firstDistance = dist(trajectory.points[0], trajectory.points[1]);
let lastPoint = trajectory.points[1];
for(let i = 2; i < trajectory.points.length; i++){
const point = trajectory.points[i];
const currentDistance = dist(point, lastPoint);
expect(currentDistance).toBeCloseTo(firstDistance);
expect(currentDistance).toBeCloseTo(firstDistance, 0);
lastPoint = point;
}
});
Expand All @@ -102,16 +102,16 @@ describe('Reference system', () => {
expect(startExtend).toBeCloseTo(500.0);
expect(endExtend).toBeCloseTo(500.0);
});
*/

it('should throw error when parameters are negative', () => {
expect(() => {
const trajectory = rs.getExtendedTrajectory(100, -50.0, 500.0);
}).toThrow('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive extensionStart parameter');
}).toThrow('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive startExtensionLength parameter');
expect(() => {
const trajectory = rs.getExtendedTrajectory(100, 50.0, -500.0);
}).toThrow('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive extensionEnd parameter');
}).toThrow('Invalid parameter, getExtendedTrajectory() must be called with a valid and positive endExtensionLength parameter');
});
/*

it('should work for vertical wellbore', () => {
const verticalPosLog = [
[30, 40, 100],
Expand All @@ -127,8 +127,44 @@ describe('Reference system', () => {
const endExtend = dist(trajectory.points[99], irs.interpolators.trajectory.getPointAt(1.0));
expect(startExtend).toBeCloseTo(1500.0);
expect(endExtend).toBeCloseTo(1500.0);
const angle = Math.atan((trajectory.points[99][0] - trajectory.points[0][0]) / (trajectory.points[99][1] - trajectory.points[0][1]));
expect(endExtend).toBeCloseTo(45.0);
const angle = degrees(Math.atan((trajectory.points[99][0] - trajectory.points[0][0]) / (trajectory.points[99][1] - trajectory.points[0][1])));
expect(angle).toBeCloseTo(45.0);
});

it('should project to right depths on vertical wellbores', () => { // Note: this is used for picks
const verticalPosLog = [
[30, 40, 50],
[30, 40, 6500],
];
const options = {trajectoryAngle: 45.0};
const irs = new IntersectionReferenceSystem(verticalPosLog, options);
irs.offset = 50;

expect(irs.project(0)[1]).toBeCloseTo(50);
expect(irs.project(7000)[1]).toBeCloseTo(6500);

expect(irs.project(200)[1]).toBeCloseTo(200);
expect(irs.project(6000)[1]).toBeCloseTo(6000);

});

it('should project to right depths on vertical wellbores with negative offset', () => { // Note: this is used for picks
const verticalPosLog = [
[80, 40, -25],
[80, 40, 5000],
];
const options = {trajectoryAngle: 45.0};
const irs = new IntersectionReferenceSystem(verticalPosLog, options);
irs.offset = -25;

expect(irs.project(-100)[1]).toBeCloseTo(-25);
expect(irs.project(0)[1]).toBeCloseTo(0);
expect(irs.project(7000)[1]).toBeCloseTo(5000);

expect(irs.project(200)[1]).toBeCloseTo(200);
expect(irs.project(4000)[1]).toBeCloseTo(4000);

});
*/


});

0 comments on commit 86f715c

Please sign in to comment.