import React from 'react'; import { centrifugalPumpState, } from '../../../animations/mechanics'; import type { MachineAnimationModule } from '../../../animations/types'; import { FlowArrow, MachinePart, Shaft, } from './primitives'; import { EngineeringBaseplate, PartLabels, getPartVisualProps, } from './proceduralSceneHelpers'; import type { ProceduralMachineDefinition, ProceduralMachineModule, ProceduralMachineSceneProps, } from './types'; const definition: ProceduralMachineDefinition = { id: 'centrifugal-pump', slug: 'centrifugal-pump', title: 'Centrifugal Pump', subtitle: 'Impeller-driven pressure rise through volute casing', category: 'Pumps & Fluid Systems', difficulty: 'Beginner', summary: 'A radial-flow pump illustrating impeller rotation, inlet suction, outlet discharge, and cavitation risk.', description: 'Centrifugal pumps convert shaft power into fluid kinetic energy with a rotating impeller. The volute casing then diffuses the high-speed flow into pressure at the outlet.', keywords: ['pump', 'fluid', 'impeller', 'volute', 'cavitation'], complexity: 5, dateAdded: '2025-02-04', typicalRpm: '1,450–3,600 RPM', facts: [ { label: 'Energy conversion', value: 'Velocity to pressure', detail: 'The impeller adds velocity; the volute and diffuser recover pressure.', }, { label: 'Failure mode', value: 'Cavitation', detail: 'If inlet pressure falls below vapor pressure, bubbles form and collapse destructively.', }, { label: 'Flow type', value: 'Radial discharge', detail: 'Fluid enters axially near the eye and exits radially through the volute.', }, { label: 'Applications', value: 'Water, coolant, process fluids', detail: 'Centrifugal pumps dominate clean-fluid transfer and circulation services.', }, ], parts: [ { id: 'volute-casing', name: 'Volute casing', description: 'Spiral housing that collects flow and converts velocity head to pressure.', material: 'Cast iron / stainless steel', labelPosition: [-1.55, 1.08, 0.82], defaultOpacity: 0.44, }, { id: 'impeller', name: 'Impeller', description: 'Rotating bladed wheel that accelerates liquid radially outward.', material: 'Bronze / stainless steel', labelPosition: [0.75, 0.55, 0.82], }, { id: 'shaft', name: 'Pump shaft', description: 'Driven shaft transferring motor torque to the impeller.', material: 'Stainless steel', labelPosition: [1.72, -0.2, 0.62], }, { id: 'inlet', name: 'Suction inlet', description: 'Axial entry passage feeding fluid into the impeller eye.', labelPosition: [-1.75, -0.42, 0.68], }, { id: 'outlet', name: 'Discharge outlet', description: 'Tangential outlet where pressurized flow leaves the volute.', labelPosition: [0.7, 1.52, 0.68], }, { id: 'inlet-flow', name: 'Inlet flow', description: 'Blue arrows show low-pressure liquid entering the pump eye.', labelPosition: [-2.3, -0.8, 0.65], }, { id: 'outlet-flow', name: 'Outlet flow', description: 'Bright arrows show higher-pressure discharge leaving the volute.', labelPosition: [1.35, 1.7, 0.65], }, { id: 'cavitation-bubbles', name: 'Cavitation indicator', description: 'Pulsing bubbles at the impeller eye indicate rising cavitation risk at high RPM.', labelPosition: [-0.42, -0.35, 0.85], }, ], cameraPresets: [ { id: 'iso', label: 'Isometric', position: [3.7, 2.6, 4.1], target: [0, 0, 0], fov: 42 }, { id: 'front', label: 'Flow path', position: [0, 0.4, 5.2], target: [0, 0.2, 0], fov: 38 }, { id: 'outlet', label: 'Volute outlet', position: [3.4, 2.4, 2.7], target: [0.2, 0.35, 0], fov: 42 }, ], tour: { id: 'tour-centrifugal-pump', machineId: 'centrifugal-pump', title: 'Trace liquid through a centrifugal pump', description: 'See inlet suction, impeller acceleration, volute pressure recovery, and cavitation warning.', steps: [ { id: 'suction', title: 'Fluid enters the eye', body: 'Low-pressure fluid is drawn axially into the impeller eye through the suction inlet.', durationSeconds: 4, partIds: ['inlet', 'inlet-flow'], camera: { position: [-3.2, 1.2, 3.7], target: [-0.35, -0.1, 0], duration: 1.1 }, rpm: 1050, }, { id: 'impeller', title: 'Impeller adds kinetic energy', body: 'Curved vanes fling liquid outward, increasing velocity and angular momentum.', durationSeconds: 4.5, partIds: ['impeller', 'shaft'], camera: { position: [0.8, 1.4, 4.7], target: [0, 0, 0], duration: 1.1 }, rpm: 1450, }, { id: 'volute', title: 'Volute recovers pressure', body: 'The growing volute area slows the flow and converts velocity into discharge pressure.', durationSeconds: 4.5, partIds: ['volute-casing', 'outlet', 'outlet-flow'], camera: { position: [3.1, 2.2, 3.2], target: [0.25, 0.4, 0], duration: 1.1 }, rpm: 1450, }, { id: 'cavitation', title: 'Cavitation risk', body: 'At excessive speed or low inlet pressure, vapor bubbles can form near the eye and damage blades.', durationSeconds: 4, partIds: ['cavitation-bubbles', 'impeller'], camera: { position: [-1.6, 1.0, 4.4], target: [-0.15, 0, 0], duration: 1.1 }, rpm: 2800, }, ], }, relatedMachineIds: ['four-stroke-petrol-engine', 'ball-bearing', 'wankel-rotary-engine'], }; function partProps( partId: string, props: ProceduralMachineSceneProps, explodeDirection: [number, number, number] = [0, 0, 0], ) { return { partId, registerPart: props.registerPart, explodeDirection, explodedDistance: props.explodedDistance ?? 0, onSelectPart: props.onSelectPart, onHoverPart: props.onHoverPart, ...getPartVisualProps(partId, props), }; } export const centrifugalPumpAnimation: MachineAnimationModule = { id: 'centrifugal-pump-flow-cycle', machineId: 'centrifugal-pump', label: 'Impeller and volute flow animation', version: '1.0.0', defaultRpm: 1450, minRpm: 120, maxRpm: 3600, cycleRevolutions: 1, cycleSteps: 12, loop: true, supportsReverse: true, reducedMotionStrategy: 'slow', update(context) { const state = centrifugalPumpState(context.shaftAngle, context.rpm, context.cycleProgress); const impeller = context.getPart('impeller'); const shaft = context.getPart('shaft'); const inletFlow = context.getPart('inlet-flow'); const outletFlow = context.getPart('outlet-flow'); const cavitation = context.getPart('cavitation-bubbles'); if (impeller) impeller.rotation.z = -state.impellerAngle; if (shaft) shaft.rotation.x = -state.impellerAngle; if (inletFlow) { inletFlow.position.x = -1.85 + state.flowPhase * 0.48; inletFlow.scale.setScalar(0.86 + state.outletPressure * 0.24); } if (outletFlow) { outletFlow.position.x = 0.62 + state.flowPhase * 0.36; outletFlow.position.y = 1.22 + state.flowPhase * 0.18; outletFlow.scale.setScalar(0.9 + state.outletPressure * 0.38); } if (cavitation) { cavitation.visible = state.cavitationRisk > 0.05; cavitation.scale.setScalar(0.45 + state.cavitationRisk * 0.85); } context.setPartOpacity('cavitation-bubbles', state.cavitationRisk); context.setPhaseLabel( state.cavitationRisk > 0.35 ? `Cavitation warning — inlet vapor bubbles rising (${Math.round(state.cavitationRisk * 100)}%)` : `Discharge pressure indicator ${Math.round(state.outletPressure * 100)}%`, ); context.clearHighlights(); if (state.cavitationRisk > 0.35) context.highlightParts(['cavitation-bubbles', 'impeller'], 0.9); else context.highlightParts(['impeller', 'outlet-flow'], 0.65); }, }; export function CentrifugalPumpScene(props: ProceduralMachineSceneProps): JSX.Element { return ( {Array.from({ length: 6 }, (_, index) => { const angle = (index / 6) * Math.PI * 2; return ( ); })} {Array.from({ length: 7 }, (_, index) => ( ))} ); } export const centrifugalPump: ProceduralMachineModule = { definition, animationModule: centrifugalPumpAnimation, Scene: CentrifugalPumpScene, };