# Socket-weld flange

Small-bore ASME B16.5 socket-weld flange (NPS 1/2–3, to 2-1/2 in Class 900 / 1500). The socket bore and depth come from B16.5, the pipe-stop shoulder steps down to the schedule bore, and the inserted pipe stands 1.6 mm off the shoulder as an expansion gap before the outside fillet weld. RF / FF / RTJ facing, real bolt holes.

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

## Installation

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

Copies `piping/socket-weld-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 { SocketWeldFlange } from './components/deck-twin/piping/socket-weld-flange'

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

## Props

| Prop | Type | Default | Range |
| --- | --- | --- | --- |
| `nps` | `number (NPS, in)` | `2` |  |
| `rating` | `150 \| 300 \| 600 \| 900 \| 1500 \| 2500` | `600` |  |
| `facing` | `"RF" \| "FF" \| "RTJ"` | `"RF"` |  |
| `schedule` | `"40" \| "80" \| "160" \| "XXS" \| "40S" \| "80S"` | `"80"` |  |
| `stub` | `number (m)` | `0.15` | 0 – 0.6 |
| `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 | 2" | 600 |

## P&ID

In section: a small-bore flange with a socket the pipe slides into against a shoulder (small gap at the bottom), and one fillet weld at the hub. On P&IDs a short bar on a small-bore (≤ 2") line.

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

Socket-weld is small-bore only (NPS ½–3). Threaded flanges show thread hatching in the bore instead of a weld.

Piping class / flange bill of materials (ASME B16.5, B16.11) 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/socket-weld-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/socket-weld-flange.json has every file.

```tsx
// Socket-weld flange: ASME B16.5 SW flange (NPS 1/2–3) with socket bore, pipe-stop shoulder, 1.6 mm expansion gap and outside fillet weld 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 { pipeWall, pipeOD, type Rating, type Schedule } from '../lib/standards'
import { facingHeight, filletWeld, looseFlange, marking, pipeStub, type Facing } from './_flanges'

export interface SocketWeldFlangeProps {
  /** nominal pipe size, inches (1/2–3; 1/2–2-1/2 in Class 900 / 1500) */
  nps?: number
  rating?: Rating
  facing?: Facing
  /** pipe schedule; sets the bore below the socket */
  schedule?: Schedule
  /** pipe inserted into the socket, m (0 for the bare flange) */
  stub?: number
  tag?: string
}

export const defaults = { nps: 2, rating: 600 as Rating, facing: 'RF' as Facing, schedule: '80' as Schedule, stub: 0.15, tag: '' }

export const clampNps = (nps: number, rating: Rating) => Math.min(Math.max(nps, 0.5), rating >= 900 ? 2.5 : 3)
const clampRating = (r: Rating): Rating => (r > 1500 ? 1500 : r)

// Port A is the gasket face at the origin, pointing -X; the socket opens along +X.
export function ports(p: SocketWeldFlangeProps = {}): Port[] {
  const { nps, rating } = { ...defaults, ...p }
  return [port('A', 'Flange face', [0, 0, 0], [-1, 0, 0], clampNps(nps, clampRating(rating)), clampRating(rating))]
}

export function SocketWeldFlange({ nps = defaults.nps, rating = defaults.rating, facing = defaults.facing, schedule = defaults.schedule, stub = defaults.stub, tag = defaults.tag, ...group }: SocketWeldFlangeProps & GroupProps) {
  const r = clampRating(rating)
  const data = useKit((k) => build(k, clampNps(nps, r), r, facing, schedule, Math.max(0, stub), tag), [nps, r, facing, schedule, stub, tag])
  return (
    <group {...group}>
      <KitMesh data={data} />
    </group>
  )
}

export default SocketWeldFlange

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: 'SW', nps, rating, facing, schedule, marking: tag || marking('SW', nps, rating, facing, `SCH ${schedule}`) })
  if (stub <= 0) return
  // pipe bottomed in the socket then backed off 1.6 mm (B31.3 expansion gap)
  const yEnd = -i.Y + i.D - 0.0016
  pipeStub(k, [h - yEnd, 0, 0], [1, 0, 0], stub + (i.Y - i.D + 0.0016), nps, schedule, 'square', 'bevel')
  filletWeld(k, base, dir, pipeOD(nps) / 2, -i.Y, Math.max(0.003, Math.min(pipeWall(nps, schedule) * 1.25, 0.012)))
}
```
