SURF Field Layout Design
Use this skill to turn a well count, a reservoir footprint and a water depth into
a placed and routed subsea layout: drill centres, wells, Xmas trees, templates
and manifolds, PLEMs, riser bases, the host, and every flowline, riser and
umbilical between them — each line sized on velocity and each item carrying a
latitude and longitude so the result drops straight into a map or a GIS.
It is the design counterpart to neqsim-subsea-layout-geometry, which screens a
layout that already exists. Use this skill first to create the layout, then that
skill to screen step-outs, and neqsim-pipe-route-profile to put the routes on a
real seabed profile.
When to Use
- A concept study needs a subsea architecture before any layout drawing exists.
- The number of drill centres, templates and Xmas trees must follow from the
well count and the slots per template.
- The host has to be placed relative to the field, and the riser base with it.
- A flowline architecture must be chosen: a round-trip-piggable dual loop, one
dedicated line per drill centre, or a daisy chain.
- Flowline, riser and injection-line sizes are needed at a screening level.
- Total flowline, riser and umbilical lengths are needed for a SURF cost
estimate.
- The layout must be georeferenced — on a licence block, on a map, as GeoJSON.
- A production-network or flow-assurance model needs node positions and segment
lengths.
Do not use it for detailed routing, crossing design, on-bottom stability,
free-span, expansion, installation or mooring analysis.
Inputs
| Group |
Fields |
| Identity and position |
field_name, centre_latitude_deg, centre_longitude_deg, water_depth_m |
| Wells |
producers, water_injectors, gas_injectors, slots_per_template, slot_spacing_m |
| Footprint |
reservoir_length_km, reservoir_width_km, field_axis_bearing_deg, injector_offset_km, seabed_slope_deg |
| Host |
host_type, host_offset_km, host_bearing_deg, riser_base_offset_m |
| Architecture |
production_architecture (dual_loop, single_line, daisy_chain) |
| Sizing |
design_liquid_rate_m3_per_s, design_water_injection_rate_m3_per_s, design_gas_injection_rate_am3_per_s, densities, target velocities |
Rates are actual volumetric rates at the flowing condition, not standard
volumes. Convert a standard rate with the formation volume factor before passing
it in, or the sizing is wrong by that factor.
Outputs
nodes — wells, Xmas trees, templates/manifolds, PLEMs, riser base and host,
each with a tag, local east/north, latitude, longitude and water depth.
lines — every flowline, injection line, umbilical and riser, with its
service, type, endpoints, length and selected size.
summary — drill-centre and tree counts, architecture, maximum step-out, and
total flowline, umbilical and riser lengths.
to_geojson() — a WGS84 FeatureCollection of points, lines and the reservoir
outline, ready for any map or GIS.
warnings and assumptions — what was assumed and what a reviewer must check.
render_field_illustration(...) — a presentation-grade reservoir-to-host
cutaway carrying the study's headline numbers (see below).
Presentation Illustration
plot_reservoir_3d is the engineering view — labelled axes, a schematic
reservoir box. render_field_illustration is the communication view: the
block diagram for a decision-gate slide. It draws the sea, the water column, the
seabed, the subsurface, a real gridded structural horizon coloured by depth,
every well from its tree to its drain, the flowlines, the host and its risers.
The point of the function is that the picture and the analysis cannot drift
apart. Headline numbers are passed as KeyFact objects, each carrying the
calculation that produced it, and are rendered as a grouped callout column. If a
number changes in the model it changes on the slide, and the slide says where it
came from.
from surf_field_layout_design import (
KeyFact, Seabed, horizon_from_model_grid, render_field_illustration,
)
horizon = horizon_from_model_grid(
top_surface_values, # flattened reservoir grid, x fastest
nx=70, ny=30, dx_m=100.0, dy_m=100.0,
origin_east_m=-5650.0, origin_north_m=0.0,
axis_bearing_deg=78.2, # true bearing of the model +x axis
contact_depth_m_tvdmsl=3054.8, # draws the hydrocarbon closure
attribution="OPM Flow structural model",
)
render_field_illustration(
layout, well_paths, "field.png",
horizon=horizon,
seabed=Seabed(east_m=e, north_m=n, depth_m=d, attribution="EMODnet DTM"),
key_facts=[
KeyFact("Gas initially in place", "6.12", "GSm3",
"OPM Flow structural model", "RESERVOIR"),
KeyFact("Flowline size", "8 in", "",
"46% of the API RP 14E limit", "SURF"),
],
title="Brime / Nokken to Gullfaks C",
)
horizon_from_model_grid rotates a reservoir model grid onto a true bearing
using the same axis convention as the layout: for a field-axis bearing $b$,
$$
\text{east} = \ell \sin b + a \cos b, \qquad
\text{north} = \ell \cos b - a \sin b
$$
with $\ell$ along-axis and $a$ across-axis. Getting this backwards silently
mirrors the field; the unit tests assert the along-axis run reproduces the
requested bearing.
Open Map and Sea Data
geodata registers openly licensed sources and plans read-only requests. It
never opens a connection of its own: execute returns the plan as a manifest
unless the caller supplies its own fetch adapter, so the same code runs in a
sandbox and on a connected workstation.
| Source |
Use |
Licence |
| EMODnet Bathymetry |
seabed depth over the field, European seas |
CC BY 4.0 |
| GEBCO grid |
global bathymetry fallback |
free, attribution required |
| NOAA ETOPO |
global relief fallback |
public domain |
| Sodir FactMaps |
quadrants, blocks, wellbores, discoveries, fields, facilities, pipelines |
NLOD |
| Sodir FactPages |
wellbore coordinates and field records as tables |
NLOD |
| Natural Earth |
coastline for a locator map |
public domain |
| Copernicus Marine, MET Norway NORA3 |
wave, wind and current statistics for the host heading |
CC BY 4.0 / open |
from surf_field_layout_design import plan_layout_data_package, execute, attribution_block
plan = plan_layout_data_package(west=24.0, south=73.0, east=26.0, north=74.0)
manifest = execute(plan) # offline: returns the plan only
manifest = execute(plan, fetch=my_read_only_get) # connected: retrieves it
print(attribution_block(["emodnet_bathymetry", "sodir_factmaps"]))
Reproduce the attribution lines on any map you publish.
Norwegian blocks
quadrant_bounds("7324") returns the quadrant box, which is exact north of
62 degN: the label is the latitude of the southern edge and the longitude of the
western edge, spanning one degree by two. block_bounds("7324/8") divides that
into twelve 15-by-40-arc-minute blocks — but the numbering direction is a
documented assumption, not a calculation, and the returned dictionary says so.
Take the real position from the open Sodir wellbore layer and use the block box
only for orientation.
Engineering Method
Drill centres. Wells of each service are grouped into templates of
slots_per_template slots, and the resulting drill centres are spaced evenly
over 70 % of the reservoir length along the field axis. Water injectors are
offset down one flank and gas injectors up the other by injector_offset_km.
This is geometry, not a sweep study.
Host and riser base. The host sits host_offset_km from the field centre on
host_bearing_deg; the riser base PLEM sits riser_base_offset_m short of it on
the reverse bearing. Riser length is the straight riser-base-to-host distance
with a 25 % lazy-wave allowance.
Architecture. dual_loop runs two legs through the production drill centres
in opposite order, giving a round-trip pigging loop. single_line gives one
dedicated line per drill centre. daisy_chain runs one line through them all and
is flagged as not round-trip piggable.
Line sizing. The smallest standard nominal size whose velocity stays under
both the target velocity and the API RP 14E erosional velocity,
$$
v_e = \frac{1.22,c}{\sqrt{\rho}}
$$
with $v_e$ in m/s, $\rho$ in kg/m³ and $c = 100$ for continuous service. Inner
diameter follows a fixed diameter-to-wall ratio of 20; that is a screening
geometry, not a pressure-containment design.
Python Usage Pattern
from surf_field_layout_design import design_surf_layout, plot_layout_map
layout = design_surf_layout(
field_name="Example field",
centre_latitude_deg=73.375,
centre_longitude_deg=25.0,
water_depth_m=400.0,
producers=8,
water_injectors=6,
gas_injectors=2,
slots_per_template=4,
reservoir_length_km=6.0,
reservoir_width_km=3.1,
field_axis_bearing_deg=30.0,
host_offset_km=2.5,
host_bearing_deg=270.0,
production_architecture="dual_loop",
design_liquid_rate_m3_per_s=28500.0 / 86400.0,
design_water_injection_rate_m3_per_s=20000.0 / 86400.0,
design_gas_injection_rate_am3_per_s=0.63e6 * 0.012 / 86400.0,
)
print(layout.summary["drill_centres"], layout.summary["flowline_length_km"], "km")
plot_layout_map(layout, "layout_map.png")
open("layout.geojson", "w").write(json.dumps(layout.to_geojson()))
Handing the layout on
- Flow assurance and hydraulics. Each
Line gives the endpoints, length and
inner diameter that neqsim.process.equipment.pipeline.PipeBeggsAndBrills
needs; take the elevation profile from neqsim-pipe-route-profile or an open
bathymetry grid rather than the flat default.
- Production network. Drill centres map to a
Mixer manifold and wells to
WellFlow inflow, as in neqsim-production-network-routing.
- Cost.
flowline_length_km, umbilical_length_km, riser_length_km and
the tree, template and PLEM counts are the quantity take-off a SURF cost
estimate needs.
- Screening. Feed the node list to
neqsim-subsea-layout-geometry for
step-out and tie-back distance checks.
Validation Checklist
Common Mistakes
| Symptom |
Cause |
Fix |
| Flowlines come out far too small |
Standard rates passed where actual rates are expected |
Multiply by the formation volume factor first |
| Only one drill centre for many wells |
slots_per_template left at a large value |
Set the real slot count per template |
| The reservoir outline does not line up with the drill centres |
field_axis_bearing_deg changed but the footprint not re-checked |
The outline follows the same axis; check the footprint dimensions |
| Riser length equals the water depth |
Riser configuration allowance ignored |
The skill adds 25 % for a lazy wave; replace with a real riser analysis |
| Umbilical length looks short |
Umbilicals are routed host-to-drill-centre in a straight line |
Add a routing allowance, or route via the real corridor |
| The block box does not match the operator's map |
The block numbering assumption |
Take the position from the Sodir wellbore layer |
| The illustrated field is mirrored about its axis |
axis_bearing_deg sign or the east/north convention |
East leads with $\sin$, north with $\cos$; check the along-axis run reproduces the bearing |
| Numbers on the slide disagree with the report |
Facts typed into the figure by hand |
Pass them as KeyFact read from the results file |
| Hand-off hydraulics say the tie-back is infeasible |
Beggs & Brill used on a low-liquid-fraction wet-gas line |
Re-run with TwoFluidPipe before abandoning the concept |
| Cooldown reports no hydrate risk on a wet line |
The fluid file carries no water component |
Check isWaterPresent(); load with EclipseFluidReadWrite.read(file, true) |
Limitations
- Screening geometry only: straight-line routes, no obstacle avoidance, no
crossings, no corridor or approach design.
- Drill-centre placement is geometric spacing, not a well-placement or sweep
optimisation.
- No on-bottom stability, free-span, expansion, buckling, installation, mooring
or riser-response analysis.
- Wall thickness follows a fixed D/t ratio and is not a pressure design.
- Line sizing is a velocity check only; no pressure-drop, slugging, erosion-rate
or thermal calculation.
- Met-ocean sources are registered but the host heading is not calculated.
- The illustration is a communication aid: well trajectories are screening
geometry, the host is a glyph, and matplotlib's 3D engine does not depth-sort
intersecting surfaces, so read positions from the data, not off the picture.
- No proprietary or confidential data is used.
Related NeqSim Functionality
The screening geometry this skill produces is meant to be replaced by real
calculations. These are the classes that do it.
neqsim.process.equipment.pipeline.RouteProfile — turns a survey into the mesh
either pipe model wants. fromDepths handles the sign convention,
withRiser appends the riser, resample gives a uniform mesh, and
getLowPointKp returns the terrain-slug traps.
neqsim.process.equipment.pipeline.TwoFluidPipe — mechanistic two-fluid
flowline and riser hydraulics. Prefer it over PipeBeggsAndBrills for a
wet-gas tie-back: the Beggs & Brill two-phase friction multiplier is
extrapolated well below its calibration floor at low liquid fraction and
over-predicts the pressure drop. Always assert isSteadyStateConverged()
and getSteadyStateIterationsUsed() > 1.
neqsim.process.equipment.pipeline.PipeBeggsAndBrills — correlation check.
CalculationMode.CALCULATE_INLET_PRESSURE with setOutletPressure(...) solves
the tie-back question directly: what inlet does the host's arrival pressure
demand? Read the answer from getSolvedInletPressure().
neqsim.process.mechanicaldesign.subsea.FlowlineSizeSelector — replaces this
skill's velocity screen with a full API RP 14E candidate table. Evaluate it at
the arrival condition, where the mixture is least dense.
neqsim.process.equipment.subsea.SubseaWell.calculateShutInWellheadPressure —
the static-column pressure that sets the flowline design pressure.
neqsim.process.equipment.reservoir.WellFlow — well inflow at each tree.
neqsim.process.mechanicaldesign.pipeline.DnvStF101PipelineDesignCalculator —
replaces this skill's D/t screening geometry with a real pressure design.
neqsim.process.mechanicaldesign.subsea.TiebackThermalDesign — sweeps wall
thickness against insulation together, because the steel is part of the
cooldown thermal mass: a thinner wall needs more insulation for the same
no-touch time.
neqsim.pvtsimulation.flowassurance.SurfCooldownAnalyzer — no-touch time.
A fluid with no water reports NO_HYDRATE_RISK with an unbounded
no-touch time, which is right for a dry gas and indistinguishable from a wet
line whose file is missing water. Check isWaterPresent(), or
setRequireWater(true) to make it a gate. Add water with
EclipseFluidReadWrite.read(file, true), and never call setMixingRule after
read (it wipes the file's BIC block).
neqsim.process.mechanicaldesign.subsea.SURFCostEstimator — turns the quantity
take-off into a CAPEX estimate.
- The NeqSim MCP
runPipeline and runFieldEconomics tools.
Related Skills
neqsim-subsea-layout-geometry — screens step-outs and tie-back distances for
the layout produced here.
neqsim-pipe-route-profile — turns the routes here into an elevation profile.
neqsim-bathymetry-profile-screening — processes the open bathymetry grid
this skill plans the request for.
neqsim-production-network-routing — takes the drill centres and wells through
manifolds and flowlines to an arrival pressure.
neqsim-step-out-screening — checks the tie-back distance and arrival pressure.
neqsim-reservoir-model-builder — supplies the well count and the plateau rate.
neqsim-capex-opex-screening — turns the quantity take-off into a cost.
References
1---2name: neqsim-surf-field-layout-design3description: Design a screening subsea (SURF) field layout and place the host from open map, bathymetry and licence-block data: group wells into drill centres, place Xmas trees, templates, manifolds, PLEMs and riser bases, position an FPSO or fixed host, route and size every production, injection, service, umbilical and riser line, export the result as georeferenced GeoJSON and a map, and render a presentation-grade reservoir-to-host cutaway that carries the study's headline numbers. USE WHEN: a task needs a field layout designed rather than an existing one screened - deciding how many drill centres and templates are needed, where the host should sit, which flowline architecture to use (loop, single line or daisy chain), what size the flowlines and risers should be, how long the umbilicals are, a georeferenced layout to hand to flow assurance, cost estimation or a NeqSim production-network model, or a decision-gate illustration of the whole system from reservoir to host.4---56# SURF Field Layout Design78Use this skill to turn a well count, a reservoir footprint and a water depth into9a placed and routed subsea layout: drill centres, wells, Xmas trees, templates10and manifolds, PLEMs, riser bases, the host, and every flowline, riser and11umbilical between them — each line sized on velocity and each item carrying a12latitude and longitude so the result drops straight into a map or a GIS.1314It is the design counterpart to `neqsim-subsea-layout-geometry`, which screens a15layout that already exists. Use this skill first to create the layout, then that16skill to screen step-outs, and `neqsim-pipe-route-profile` to put the routes on a17real seabed profile.1819## When to Use2021- A concept study needs a subsea architecture before any layout drawing exists.22- The number of drill centres, templates and Xmas trees must follow from the23 well count and the slots per template.24- The host has to be placed relative to the field, and the riser base with it.25- A flowline architecture must be chosen: a round-trip-piggable dual loop, one26 dedicated line per drill centre, or a daisy chain.27- Flowline, riser and injection-line sizes are needed at a screening level.28- Total flowline, riser and umbilical lengths are needed for a SURF cost29 estimate.30- The layout must be georeferenced — on a licence block, on a map, as GeoJSON.31- A production-network or flow-assurance model needs node positions and segment32 lengths.3334Do not use it for detailed routing, crossing design, on-bottom stability,35free-span, expansion, installation or mooring analysis.3637## Inputs3839| Group | Fields |40| --- | --- |41| Identity and position | `field_name`, `centre_latitude_deg`, `centre_longitude_deg`, `water_depth_m` |42| Wells | `producers`, `water_injectors`, `gas_injectors`, `slots_per_template`, `slot_spacing_m` |43| Footprint | `reservoir_length_km`, `reservoir_width_km`, `field_axis_bearing_deg`, `injector_offset_km`, `seabed_slope_deg` |44| Host | `host_type`, `host_offset_km`, `host_bearing_deg`, `riser_base_offset_m` |45| Architecture | `production_architecture` (`dual_loop`, `single_line`, `daisy_chain`) |46| Sizing | `design_liquid_rate_m3_per_s`, `design_water_injection_rate_m3_per_s`, `design_gas_injection_rate_am3_per_s`, densities, target velocities |4748Rates are **actual** volumetric rates at the flowing condition, not standard49volumes. Convert a standard rate with the formation volume factor before passing50it in, or the sizing is wrong by that factor.5152## Outputs5354- `nodes` — wells, Xmas trees, templates/manifolds, PLEMs, riser base and host,55 each with a tag, local east/north, latitude, longitude and water depth.56- `lines` — every flowline, injection line, umbilical and riser, with its57 service, type, endpoints, length and selected size.58- `summary` — drill-centre and tree counts, architecture, maximum step-out, and59 total flowline, umbilical and riser lengths.60- `to_geojson()` — a WGS84 FeatureCollection of points, lines and the reservoir61 outline, ready for any map or GIS.62- `warnings` and `assumptions` — what was assumed and what a reviewer must check.63- `render_field_illustration(...)` — a presentation-grade reservoir-to-host64 cutaway carrying the study's headline numbers (see below).6566## Presentation Illustration6768`plot_reservoir_3d` is the engineering view — labelled axes, a schematic69reservoir box. `render_field_illustration` is the **communication** view: the70block diagram for a decision-gate slide. It draws the sea, the water column, the71seabed, the subsurface, a real gridded structural horizon coloured by depth,72every well from its tree to its drain, the flowlines, the host and its risers.7374The point of the function is that the picture and the analysis cannot drift75apart. Headline numbers are passed as `KeyFact` objects, each carrying the76calculation that produced it, and are rendered as a grouped callout column. If a77number changes in the model it changes on the slide, and the slide says where it78came from.7980```python81from surf_field_layout_design import (82 KeyFact, Seabed, horizon_from_model_grid, render_field_illustration,83)8485horizon = horizon_from_model_grid(86 top_surface_values, # flattened reservoir grid, x fastest87 nx=70, ny=30, dx_m=100.0, dy_m=100.0,88 origin_east_m=-5650.0, origin_north_m=0.0,89 axis_bearing_deg=78.2, # true bearing of the model +x axis90 contact_depth_m_tvdmsl=3054.8, # draws the hydrocarbon closure91 attribution="OPM Flow structural model",92)9394render_field_illustration(95 layout, well_paths, "field.png",96 horizon=horizon,97 seabed=Seabed(east_m=e, north_m=n, depth_m=d, attribution="EMODnet DTM"),98 key_facts=[99 KeyFact("Gas initially in place", "6.12", "GSm3",100 "OPM Flow structural model", "RESERVOIR"),101 KeyFact("Flowline size", "8 in", "",102 "46% of the API RP 14E limit", "SURF"),103 ],104 title="Brime / Nokken to Gullfaks C",105)106```107108`horizon_from_model_grid` rotates a reservoir model grid onto a true bearing109using the **same axis convention as the layout**: for a field-axis bearing $b$,110111$$112\text{east} = \ell \sin b + a \cos b, \qquad113\text{north} = \ell \cos b - a \sin b114$$115116with $\ell$ along-axis and $a$ across-axis. Getting this backwards silently117mirrors the field; the unit tests assert the along-axis run reproduces the118requested bearing.119120## Open Map and Sea Data121122`geodata` registers openly licensed sources and plans read-only requests. It123**never opens a connection of its own**: `execute` returns the plan as a manifest124unless the caller supplies its own `fetch` adapter, so the same code runs in a125sandbox and on a connected workstation.126127| Source | Use | Licence |128| --- | --- | --- |129| EMODnet Bathymetry | seabed depth over the field, European seas | CC BY 4.0 |130| GEBCO grid | global bathymetry fallback | free, attribution required |131| NOAA ETOPO | global relief fallback | public domain |132| Sodir FactMaps | quadrants, blocks, wellbores, discoveries, fields, facilities, pipelines | NLOD |133| Sodir FactPages | wellbore coordinates and field records as tables | NLOD |134| Natural Earth | coastline for a locator map | public domain |135| Copernicus Marine, MET Norway NORA3 | wave, wind and current statistics for the host heading | CC BY 4.0 / open |136137```python138from surf_field_layout_design import plan_layout_data_package, execute, attribution_block139140plan = plan_layout_data_package(west=24.0, south=73.0, east=26.0, north=74.0)141manifest = execute(plan) # offline: returns the plan only142manifest = execute(plan, fetch=my_read_only_get) # connected: retrieves it143print(attribution_block(["emodnet_bathymetry", "sodir_factmaps"]))144```145146Reproduce the attribution lines on any map you publish.147148### Norwegian blocks149150`quadrant_bounds("7324")` returns the quadrant box, which is exact north of15162 degN: the label is the latitude of the southern edge and the longitude of the152western edge, spanning one degree by two. `block_bounds("7324/8")` divides that153into twelve 15-by-40-arc-minute blocks — but the **numbering direction is a154documented assumption**, not a calculation, and the returned dictionary says so.155Take the real position from the open Sodir wellbore layer and use the block box156only for orientation.157158## Engineering Method159160**Drill centres.** Wells of each service are grouped into templates of161`slots_per_template` slots, and the resulting drill centres are spaced evenly162over 70 % of the reservoir length along the field axis. Water injectors are163offset down one flank and gas injectors up the other by `injector_offset_km`.164This is geometry, not a sweep study.165166**Host and riser base.** The host sits `host_offset_km` from the field centre on167`host_bearing_deg`; the riser base PLEM sits `riser_base_offset_m` short of it on168the reverse bearing. Riser length is the straight riser-base-to-host distance169with a 25 % lazy-wave allowance.170171**Architecture.** `dual_loop` runs two legs through the production drill centres172in opposite order, giving a round-trip pigging loop. `single_line` gives one173dedicated line per drill centre. `daisy_chain` runs one line through them all and174is flagged as not round-trip piggable.175176**Line sizing.** The smallest standard nominal size whose velocity stays under177both the target velocity and the API RP 14E erosional velocity,178179$$180v_e = \frac{1.22\,c}{\sqrt{\rho}}181$$182183with $v_e$ in m/s, $\rho$ in kg/m³ and $c = 100$ for continuous service. Inner184diameter follows a fixed diameter-to-wall ratio of 20; that is a screening185geometry, **not** a pressure-containment design.186187## Python Usage Pattern188189```python190from surf_field_layout_design import design_surf_layout, plot_layout_map191192layout = design_surf_layout(193 field_name="Example field",194 centre_latitude_deg=73.375,195 centre_longitude_deg=25.0,196 water_depth_m=400.0,197 producers=8,198 water_injectors=6,199 gas_injectors=2,200 slots_per_template=4,201 reservoir_length_km=6.0,202 reservoir_width_km=3.1,203 field_axis_bearing_deg=30.0,204 host_offset_km=2.5,205 host_bearing_deg=270.0,206 production_architecture="dual_loop",207 design_liquid_rate_m3_per_s=28500.0 / 86400.0,208 design_water_injection_rate_m3_per_s=20000.0 / 86400.0,209 design_gas_injection_rate_am3_per_s=0.63e6 * 0.012 / 86400.0,210)211212print(layout.summary["drill_centres"], layout.summary["flowline_length_km"], "km")213plot_layout_map(layout, "layout_map.png")214open("layout.geojson", "w").write(json.dumps(layout.to_geojson()))215```216217### Handing the layout on218219- **Flow assurance and hydraulics.** Each `Line` gives the endpoints, length and220 inner diameter that `neqsim.process.equipment.pipeline.PipeBeggsAndBrills`221 needs; take the elevation profile from `neqsim-pipe-route-profile` or an open222 bathymetry grid rather than the flat default.223- **Production network.** Drill centres map to a `Mixer` manifold and wells to224 `WellFlow` inflow, as in `neqsim-production-network-routing`.225- **Cost.** `flowline_length_km`, `umbilical_length_km`, `riser_length_km` and226 the tree, template and PLEM counts are the quantity take-off a SURF cost227 estimate needs.228- **Screening.** Feed the node list to `neqsim-subsea-layout-geometry` for229 step-out and tie-back distance checks.230231## Validation Checklist232233- [ ] The field position comes from an open wellbore or discovery record, not234 from the block-grid assumption.235- [ ] Design rates are actual volumetric rates at the flowing condition.236- [ ] Every line size is inside the target velocity and the erosional limit, or237 the deviation is explained.238- [ ] The flowline architecture matches the pigging and shutdown philosophy.239- [ ] The seabed is a real bathymetry grid, not the flat default, before any240 route length or riser length is used for cost or hydraulics.241- [ ] The host offset respects the safety zone and the drill-centre envelope.242- [ ] Wall thickness has been replaced by a real pressure design.243- [ ] Every number on a published illustration is a `KeyFact` with its source,244 and matches the calculation it claims to come from.245- [ ] A qualified subsea engineer has reviewed the layout.246247## Common Mistakes248249| Symptom | Cause | Fix |250| --- | --- | --- |251| Flowlines come out far too small | Standard rates passed where actual rates are expected | Multiply by the formation volume factor first |252| Only one drill centre for many wells | `slots_per_template` left at a large value | Set the real slot count per template |253| The reservoir outline does not line up with the drill centres | `field_axis_bearing_deg` changed but the footprint not re-checked | The outline follows the same axis; check the footprint dimensions |254| Riser length equals the water depth | Riser configuration allowance ignored | The skill adds 25 % for a lazy wave; replace with a real riser analysis |255| Umbilical length looks short | Umbilicals are routed host-to-drill-centre in a straight line | Add a routing allowance, or route via the real corridor |256| The block box does not match the operator's map | The block numbering assumption | Take the position from the Sodir wellbore layer |257| The illustrated field is mirrored about its axis | `axis_bearing_deg` sign or the east/north convention | East leads with $\sin$, north with $\cos$; check the along-axis run reproduces the bearing |258| Numbers on the slide disagree with the report | Facts typed into the figure by hand | Pass them as `KeyFact` read from the results file |259| Hand-off hydraulics say the tie-back is infeasible | Beggs & Brill used on a low-liquid-fraction wet-gas line | Re-run with `TwoFluidPipe` before abandoning the concept |260| Cooldown reports no hydrate risk on a wet line | The fluid file carries no water component | Check `isWaterPresent()`; load with `EclipseFluidReadWrite.read(file, true)` |261262## Limitations263264- Screening geometry only: straight-line routes, no obstacle avoidance, no265 crossings, no corridor or approach design.266- Drill-centre placement is geometric spacing, not a well-placement or sweep267 optimisation.268- No on-bottom stability, free-span, expansion, buckling, installation, mooring269 or riser-response analysis.270- Wall thickness follows a fixed D/t ratio and is not a pressure design.271- Line sizing is a velocity check only; no pressure-drop, slugging, erosion-rate272 or thermal calculation.273- Met-ocean sources are registered but the host heading is not calculated.274- The illustration is a communication aid: well trajectories are screening275 geometry, the host is a glyph, and matplotlib's 3D engine does not depth-sort276 intersecting surfaces, so read positions from the data, not off the picture.277- No proprietary or confidential data is used.278279## Related NeqSim Functionality280281The screening geometry this skill produces is meant to be replaced by real282calculations. These are the classes that do it.283284- `neqsim.process.equipment.pipeline.RouteProfile` — turns a survey into the mesh285 either pipe model wants. `fromDepths` handles the sign convention,286 `withRiser` appends the riser, `resample` gives a uniform mesh, and287 `getLowPointKp` returns the terrain-slug traps.288- `neqsim.process.equipment.pipeline.TwoFluidPipe` — mechanistic two-fluid289 flowline and riser hydraulics. Prefer it over `PipeBeggsAndBrills` for a290 wet-gas tie-back: the Beggs & Brill two-phase friction multiplier is291 extrapolated well below its calibration floor at low liquid fraction and292 over-predicts the pressure drop. Always assert `isSteadyStateConverged()`293 **and** `getSteadyStateIterationsUsed() > 1`.294- `neqsim.process.equipment.pipeline.PipeBeggsAndBrills` — correlation check.295 `CalculationMode.CALCULATE_INLET_PRESSURE` with `setOutletPressure(...)` solves296 the tie-back question directly: what inlet does the host's arrival pressure297 demand? Read the answer from `getSolvedInletPressure()`.298- `neqsim.process.mechanicaldesign.subsea.FlowlineSizeSelector` — replaces this299 skill's velocity screen with a full API RP 14E candidate table. Evaluate it at300 the **arrival** condition, where the mixture is least dense.301- `neqsim.process.equipment.subsea.SubseaWell.calculateShutInWellheadPressure` —302 the static-column pressure that sets the flowline design pressure.303- `neqsim.process.equipment.reservoir.WellFlow` — well inflow at each tree.304- `neqsim.process.mechanicaldesign.pipeline.DnvStF101PipelineDesignCalculator` —305 replaces this skill's D/t screening geometry with a real pressure design.306- `neqsim.process.mechanicaldesign.subsea.TiebackThermalDesign` — sweeps wall307 thickness against insulation together, because the steel is part of the308 cooldown thermal mass: a thinner wall needs more insulation for the same309 no-touch time.310- `neqsim.pvtsimulation.flowassurance.SurfCooldownAnalyzer` — no-touch time.311 A fluid with **no water** reports `NO_HYDRATE_RISK` with an unbounded312 no-touch time, which is right for a dry gas and indistinguishable from a wet313 line whose file is missing water. Check `isWaterPresent()`, or314 `setRequireWater(true)` to make it a gate. Add water with315 `EclipseFluidReadWrite.read(file, true)`, and never call `setMixingRule` after316 `read` (it wipes the file's BIC block).317- `neqsim.process.mechanicaldesign.subsea.SURFCostEstimator` — turns the quantity318 take-off into a CAPEX estimate.319- The NeqSim MCP `runPipeline` and `runFieldEconomics` tools.320321## Related Skills322323- `neqsim-subsea-layout-geometry` — screens step-outs and tie-back distances for324 the layout produced here.325- `neqsim-pipe-route-profile` — turns the routes here into an elevation profile.326- `neqsim-bathymetry-profile-screening` — processes the open bathymetry grid327 this skill plans the request for.328- `neqsim-production-network-routing` — takes the drill centres and wells through329 manifolds and flowlines to an arrival pressure.330- `neqsim-step-out-screening` — checks the tie-back distance and arrival pressure.331- `neqsim-reservoir-model-builder` — supplies the well count and the plateau rate.332- `neqsim-capex-opex-screening` — turns the quantity take-off into a cost.333334## References335336- API RP 14E, *Design and Installation of Offshore Production Platform Piping337 Systems* — erosional velocity.338- DNV-ST-F101 *Submarine pipeline systems* and DNV-RP-F109/F105 for the design339 checks this skill deliberately does not perform.340- EMODnet Bathymetry: https://emodnet.ec.europa.eu/en/bathymetry341- GEBCO: https://www.gebco.net/342- Norwegian Offshore Directorate FactMaps: https://factmaps.sodir.no/343- Natural Earth: https://www.naturalearthdata.com/344- Copernicus Marine Service: https://marine.copernicus.eu/345- MET Norway NORA3 hindcast: https://thredds.met.no/346- NeqSim: https://github.com/equinor/neqsim