Fluids

The tutorial demonstrates how various fluids like 'mud', 'spacer fluid',etc. can be displayed in a wellbore using different fill styles. Fluids can be displayed in vertical and deviated mode.

# Fluids in Vertical Schematics

The section shows how to add several fluid components to a wellbore. Note that all the fluids are expected to look different from each other, so a 'subset' property for e.g 'Mud', 'Spacer Fluid'(which is optional in general case) is used when a 'fluid' component is being added to wellbore data collection. This subset property is later used by wellBoreNode.setRenderingHints(renderingHints) to render fluid's subsets with their corresponding fill colors.

import { MultiDiameterComponentFactoryRegistry } from "@int/geotoolkit/schematics/factory/MultiDiameterComponentFactoryRegistry.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { ViewMode } from "@int/geotoolkit/schematics/scene/WellBoreNode.ts";
import { LocationType } from "@int/geotoolkit/schematics/labeling/LocationType.ts";
import { AnimationStyle } from "@int/geotoolkit/attributes/AnimationStyle.ts";
import { CompositeSchematicsWidget } from "@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts";
import { getWellBoreData, mud, mudLevelFr } from "/src/code/Schematics/Fluids/wellboreData_fluids.ts";
import { FixedTrackWidthStrategy } from "@int/geotoolkit/schematics/FixedTrackWidthStrategy.ts";
let intervalID;
let plot = null;
const createScene = (canvas) => {
  const factoryRegistry = new MultiDiameterComponentFactoryRegistry();
  const wellBoreData = getWellBoreData();
  const depths = [3780.9, 5100.1, 5350, 7768.8, 9220];
  const markers = depths.map((depth) => ({
    "name": "marker",
    "data": {
      "description": depth.toString(),
      "geometry": { "depth": depth }
    }
  }));
  wellBoreData.addComponents(markers);
  const widget = new CompositeSchematicsWidget({
    "wellborenode": {
      "viewmode": ViewMode.Regular,
      "data": wellBoreData,
      "registry": factoryRegistry,
      "renderinghints": {
        "fluid": {
          "Mud": { "fillstyle": { "color": "rgb(191,127,127)" } },
          "Spacer Fluid": { "fillstyle": { "color": "rgb(113,244,151)" } },
          "Head Slurry": { "fillstyle": { "color": "rgb(127,127,127)" } },
          "Tail Slurry": { "fillstyle": { "color": "rgb(80,80,80)" } }
        }
      }
    },
    "annotationssizes": {
      "north": 0,
      "south": 0,
      "east": 0,
      "west": 0
    },
    "labeling": {
      "connectorshape": null,
      "locationmap": [
        { "component": ["marker"], "location": LocationType.Left }
      ]
    },
    "trackwidthstrategy": new FixedTrackWidthStrategy(100),
    "gap": {
      "bottom": {
        "visible": true,
        "size": 15
      },
      "top": {
        "visible": true,
        "size": 15
      }
    }
  });
  plot = new Plot({
    "root": widget,
    "canvaselement": canvas
  });
  if (!AnimationStyle.isAnimationEnabled())
    return;
  const step = 50;
  const mudDepthTo = mud["data"]["geometry"]["depth"]["to"];
  const mudID = mud["data"]["id"];
  intervalID = window.setInterval(() => {
    if (!wellBoreData)
      return;
    let curLevelFrom = mud["data"]["geometry"]["level"]["from"];
    if (curLevelFrom + step > mudDepthTo) {
      curLevelFrom = mudLevelFr;
    } else {
      curLevelFrom += step;
    }
    wellBoreData.updateComponents({
      "name": "fluid",
      "data": {
        "id": mudID,
        "geometry": {
          "level": {
            "from": curLevelFrom
          }
        }
      }
    });
  }, 250);
};
const disposeScene = () => {
  clearInterval(intervalID);
  if (plot) {
    plot.dispose();
  }
};
export { createScene, disposeScene };

createScene(document.querySelector('[ref="plot"]'));

# Fluids in Deviated Schematics

The section demonstrates how to display a wellbore with several fluid components in a deviated mode.

import { MultiDiameterComponentFactoryRegistry } from "@int/geotoolkit/schematics/factory/MultiDiameterComponentFactoryRegistry.ts";
import { Plot } from "@int/geotoolkit/plot/Plot.ts";
import { ViewMode } from "@int/geotoolkit/schematics/scene/WellBoreNode.ts";
import { Trajectory2d } from "@int/geotoolkit/deviation/Trajectory2d.ts";
import { LocationType } from "@int/geotoolkit/schematics/labeling/LocationType.ts";
import { Mode } from "@int/geotoolkit/schematics/labeling/Mode.ts";
import { CompositeSchematicsWidget, DisplayMode } from "@int/geotoolkit/schematics/widgets/CompositeSchematicsWidget.ts";
import { AnimationStyle } from "@int/geotoolkit/attributes/AnimationStyle.ts";
import { getWellBoreData, mud, mudLevelFr } from "/src/code/Schematics/Fluids/wellboreData_fluids.ts";
let intervalID;
let plot = null;
const createScene = (canvas) => {
  const factoryRegistry = new MultiDiameterComponentFactoryRegistry();
  const wellBoreData = getWellBoreData();
  const depths = [3780.9, 5100.1, 5350, 7768.8, 9220];
  const markers = depths.map((depth) => ({
    "name": "marker",
    "data": {
      "description": depth.toString(),
      "geometry": { "depth": depth }
    }
  }));
  wellBoreData.addComponents(markers);
  const geometryBounds = wellBoreData.getGeometryBounds();
  const minDepth = geometryBounds.getTop();
  const maxDepth = geometryBounds.getBottom();
  const trajectory = new Trajectory2d({
    "data": {
      "x": [0, 0, 1500],
      "y": [0, 2500, 5e3],
      "d": [minDepth, (minDepth + maxDepth) / 2, maxDepth]
    }
  });
  const labelingOptions = {
    "locationmap": [
      { "component": ["marker"], "location": LocationType.Left }
    ],
    "connectorshape": null,
    "defaultlocation": LocationType.Auto,
    "mode": Mode.Trajectory
  };
  const widget = new CompositeSchematicsWidget({
    "data": {
      "elements": wellBoreData,
      "trajectory": trajectory
    },
    "annotationssizes": {
      "north": 0,
      "south": 0,
      "east": 0,
      "west": 0
    },
    "wellborenode": {
      "renderinghints": {
        "fluid": {
          "Mud": { "fillstyle": { "color": "rgb(191,127,127)" } },
          "Spacer Fluid": { "fillstyle": { "color": "rgb(113,244,151)" } },
          "Head Slurry": { "fillstyle": { "color": "rgb(127,127,127)" } },
          "Tail Slurry": { "fillstyle": { "color": "rgb(80,80,80)" } }
        }
      },
      "viewmode": ViewMode.Regular,
      "registry": factoryRegistry
    },
    "deviation": {
      "trackwidth": 100
    },
    "labeling": labelingOptions,
    "tools": {
      "crosshair": {
        "enabled": false
      },
      "tooltip": {
        "enabled": false
      }
    },
    "gap": {
      "left": {
        "size": "80px",
        "linestyle": null
      },
      "right": {
        "size": "0px",
        "linestyle": null
      },
      "top": {
        "size": "10px",
        "visible": true,
        "linestyle": null
      },
      "bottom": {
        "size": "40px",
        "visible": true,
        "linestyle": null
      }
    }
  });
  widget.setDisplayMode(DisplayMode.Deviated);
  plot = new Plot({
    "canvaselement": canvas,
    "root": widget
  });
  widget.fitToBounds();
  if (!AnimationStyle.isAnimationEnabled())
    return;
  const step = 50;
  const mudDepthTo = mud["data"]["geometry"]["depth"]["to"];
  const mudID = mud["data"]["id"];
  intervalID = window.setInterval(() => {
    if (!wellBoreData)
      return;
    let curLevelFrom = mud["data"]["geometry"]["level"]["from"];
    if (curLevelFrom + step > mudDepthTo) {
      curLevelFrom = mudLevelFr;
    } else {
      curLevelFrom += step;
    }
    wellBoreData.updateComponents({
      "name": "fluid",
      "data": {
        "id": mudID,
        "geometry": {
          "level": {
            "from": curLevelFrom
          }
        }
      }
    });
  }, 250);
};
const disposeScene = () => {
  clearInterval(intervalID);
  if (plot) {
    plot.dispose();
  }
};
export { createScene, disposeScene };

createScene(document.querySelector('[ref="plot"]'));