Geometry and volumes
Construction intervals give everything needed to estimate materials: how much gravel to order, how much grout to mix, how wide the drawing must be. These functions read the construction blocks of a Well in the format's units, meters for depth and millimeters for diameter, and return cubic meters.
Gravel pack and seal
import { calculateHoleFillVolume, formatNumber } from '@welldot/utils';
const gravel = calculateHoleFillVolume('gravel_pack', well);
const seal = calculateHoleFillVolume('seal', well);
formatNumber(gravel, { fractionDigits: 2, suffix: 'm³' }); // '1.88 m³'
formatNumber(seal, { fractionDigits: 2, suffix: 'm³' }); // '0.39 m³'
calculateHoleFillVolume(type, well) adds up every hole_fill interval of that type ('gravel_pack' or 'seal', the two values of the closed vocabulary in HoleFill). For each interval it takes the annulus at the fill's diameter and subtracts any casing or screen that overlaps it, so the result is the net volume of material.
For one interval, use calculateHoleFillSegmentVolume(holeFill, well):
import { calculateHoleFillSegmentVolume } from '@welldot/utils';
for (const fill of well.hole_fill) {
console.log(
fill.type,
fill.from,
fill.to,
calculateHoleFillSegmentVolume(fill, well),
);
}
Cylinders
calculateCylindricVolume(diameter, height) is the volume in m³ of a cylinder with a diameter in millimeters and a height in meters:
import { calculateCylindricVolume } from '@welldot/utils';
calculateCylindricVolume(254, 60); // 3.04 m³: a 10 in hole, 60 m deep
calculateCylindricVolume(168.3, 1); // 0.022 m³ per meter of 6 in casing
Useful for drilling fluid volumes, well disinfection doses or the water stored in the casing.
Depths
getProfileLastItemsDepths(well) returns the deepest point of each block, in a fixed order: lithology, fractures, caves, bore hole, hole fill, reduction, surface case, well case, well screen. An empty block gives 0.
import { getProfileLastItemsDepths } from '@welldot/utils';
Math.max(...getProfileLastItemsDepths(well)); // the deepest recorded point, geology included
For the drilled depth from construction only, use calculatedWellDepth from @welldot/core. The difference matters when a lithology log goes deeper than the finished well. Depths and intervals explains well_depth.
Diameters
import { getProfileDiamValues } from '@welldot/utils';
const diameters = getProfileDiamValues(well); // every diameter in mm, both ends of each reduction
const widest = Math.max(...diameters); // to scale a cross-section
getProfileDiamValues accepts any object with the construction arrays (the Constructive type), and a Well is one. getConstructivePropertySummary(well, property) is the general form: one named property pulled from every construction component, undefined where a component has no such field.
Centralizers
The spec stores centralizers as an interval and a spacing, and forbids storing their count (Centralizer). getCentralizerDepths derives the positions:
import { getCentralizerDepths } from '@welldot/utils';
getCentralizerDepths({ from: 10, to: 58, spacing: 12, type: 'spring_bow' });
// [10, 22, 34, 46, 58]
Without a spacing it returns only the two ends.