# Slip-on flange

ASME B16.5 slip-on flange on a pipe stub: short tapered hub, bore B a little over the pipe OD, drilled bolt holes, RF / FF / RTJ facing. The pipe end is set back from the face by the inside fillet weld leg (the smaller of the wall and 6 mm) and an outside fillet weld closes the hub end, as ASME B31.3 Fig. 328.5.2B shows. Hub length Y comes from the B16.5 slip-on table for each class. Where B16.5 has no slip-on flange (Class 1500 above NPS 2-1/2, Class 2500), the next lower class that has one is used.

**Standards:** ASME B16.5, ASME B31.3, ASME B16.20

## Installation

```bash
npx -y https://decktwin.com/cli/deck-twin-0.2.2.tgz add slip-on-flange
```

Copies `piping/slip-on-flange.tsx`, any helper files it imports and the shared `lib/` into `src/components/deck-twin/`. Needs `three`, `@react-three/fiber` and `@react-three/drei`.

## Usage

```tsx
import { Canvas } from '@react-three/fiber'
import { OrbitControls } from '@react-three/drei'
import { Stage } from './components/deck-twin/lib/stage'
import { SlipOnFlange } from './components/deck-twin/piping/slip-on-flange'

export default function Scene() {
  return (
    <Canvas shadows camera={{ position: [8, 5, 9], fov: 35 }}>
      <Stage>
        <SlipOnFlange />
      </Stage>
      <OrbitControls makeDefault />
    </Canvas>
  )
}
```

## Props

| Prop | Type | Default | Range |
| --- | --- | --- | --- |
| `nps` | `number (NPS, in)` | `4` |  |
| `rating` | `150 \| 300 \| 600 \| 900 \| 1500 \| 2500` | `150` |  |
| `facing` | `"RF" \| "FF" \| "RTJ"` | `"RF"` |  |
| `schedule` | `"10" \| "20" \| "40" \| "STD" \| "80" \| "XS" \| "160" \| "XXS" \| "10S" \| "40S" \| "80S"` | `"40"` |  |
| `stub` | `number (m)` | `0.2` | 0 – 1 |
| `tag` | `string` | `""` |  |
| `...group` | position, rotation, scale… |  |  |

## Ports

Flange faces in the component's local frame, metres. Origin: pipe centreline, flow along X.

| Id | Label | Position | Direction | Size | Class |
| --- | --- | --- | --- | --- | --- |
| `A` | Flange face | 0.000, 0.000, 0.000 | -1, 0, 0 | 4" | 150 |

## P&ID

In section: a flange with a short hub slid over the pipe, the pipe end set back from the face, with fillet welds inside the bore and at the hub. On P&IDs a short bar across the line.

tag SO · ASME B16.5 flange types drawn in half-section (GA / isometric detail convention); on P&IDs every flange is a short bar

Pipe passing into the flange bore with two fillet welds = slip-on. Weld-neck has a long tapered hub and one butt weld.

Piping class / flange bill of materials (ASME B16.5) fields and the props they set:

| Field | Prop |
| --- | --- |
| Nominal size | `nps` |
| Pressure class | `rating` |
| Facing | `facing` |
| Pipe schedule | `schedule` |
| Tag number | `tag` |

## Typical suppliers

All Metals & Forge Group. The geometry is generic and sized from public standards. It is not vendor CAD.

## Source

`piping/slip-on-flange.tsx`. This is the component file only: it imports shared code, so install it with the command above rather than pasting it alone. https://decktwin.com/r/slip-on-flange.json has every file.

```tsx
// Slip-on flange: ASME B16.5 SO flange slid over the pipe with the pipe end set back, inside and outside fillet welds per ASME B31.3.
import type { Kit } from '../lib/kit'
import { KitMesh, useKit, type GroupProps } from '../lib/mesh'
import { port, type Port } from '../lib/ports'
import { pipeOD, pipeWall, type Rating, type Schedule } from '../lib/standards'
import { arc, definedRating, facingHeight, filletWeld, looseFlange, marking, pipeStub, seg, type Facing } from './_flanges'

export interface SlipOnFlangeProps {
  /** nominal pipe size, inches (B16.5 slip-on: 1/2–24) */
  nps?: number
  rating?: Rating
  facing?: Facing
  schedule?: Schedule
  /** pipe stub behind the hub, m */
  stub?: number
  /** stamped marking, empty for the standard marking */
  tag?: string
}

export const defaults = { nps: 4, rating: 150 as Rating, facing: 'RF' as Facing, schedule: '40' as Schedule, stub: 0.2, tag: '' }

// Port A is the gasket face at the origin, pointing -X; hub and pipe run along +X.
export function ports(p: SlipOnFlangeProps = {}): Port[] {
  const { nps, rating } = { ...defaults, ...p }
  const n = Math.min(nps, 24)
  return [port('A', 'Flange face', [0, 0, 0], [-1, 0, 0], n, definedRating('SO', n, rating))]
}

export function SlipOnFlange({ nps = defaults.nps, rating = defaults.rating, facing = defaults.facing, schedule = defaults.schedule, stub = defaults.stub, tag = defaults.tag, ...group }: SlipOnFlangeProps & GroupProps) {
  const data = useKit((k) => build(k, Math.min(nps, 24), definedRating('SO', Math.min(nps, 24), rating), facing, schedule, Math.max(0, stub), tag), [nps, rating, facing, schedule, stub, tag])
  return (
    <group {...group}>
      <KitMesh data={data} />
    </group>
  )
}

export default SlipOnFlange

function build(k: Kit, nps: number, rating: Rating, facing: Facing, schedule: Schedule, stub: number, tag: string) {
  const h = facingHeight(facing, nps, rating)
  const base: [number, number, number] = [h, 0, 0]
  const dir: [number, number, number] = [-1, 0, 0]
  const i = looseFlange(k, base, dir, { kind: 'SO', nps, rating, facing, schedule, marking: tag || marking('SO', nps, rating, facing) })
  const ro = pipeOD(nps) / 2
  const wt = pipeWall(nps, schedule)
  const ri = ro - wt
  // B31.3: inside fillet no larger than the wall or 6 mm; pipe end set back so the weld stays clear of the face
  const leg = Math.min(wt, 0.006)
  const yEnd = -leg - 0.0015
  const L = i.Y + yEnd + stub
  pipeStub(k, [h - yEnd, 0, 0], [1, 0, 0], L, nps, schedule, 'open', stub > 0 ? 'bevel' : 'square')
  const n = seg(ro * 2)
  k.lathe('flangeSteel', [[i.B, yEnd + leg], ...arc(i.B, yEnd, leg, Math.PI / 2, Math.PI, 4).slice(1, -1).map(([r, y]) => [r + leg * 0.12, y + leg * 0.12] as [number, number]), [i.B - leg, yEnd]], base, dir, n)
  k.lathe('machined', [[i.B - leg, yEnd], [ri, yEnd]], base, dir, n)
  // outside fillet at the hub end: 1.4 x wall, limited by the hub
  filletWeld(k, base, dir, ro, -i.Y, Math.min(wt * 1.4, 0.014), n)
}
```
