Skip to content

OpenFOAM e-bike aero/CHT case (SKELETON — not runnable as-is)

Starting point for the real CFD back end of ebike_openfoam_aero_rom.py. The numerics are complete (fvSchemes, fvSolution with residual controls, k-omega-SST fields with wall functions), but there is no bike geometry: blockMeshDict describes an empty 20 x 4 x 3 m tunnel, and the bike patch referenced by forceCoeffs, 0/U and the turbulence fields only exists after the snappyHexMesh step below. Do not "fix" that by deleting the patch references: an empty tunnel converges happily to Cd ~ 0 and would poison the downstream ROM with a plausible-looking zero.

To make it a real case: 1. Geometry: put a watertight bike+rider STL at constant/triSurface/bike.stl, run surfaceFeatureExtract, write a snappyHexMeshDict with boundary layers on the bike surface (this is where the y+ battle is fought; the shipped fields assume wall functions, y+ ~ 30-300), then blockMesh && snappyHexMesh -overwrite. 2. Domain checks before trusting any number: blockage = Aref / tunnel cross-section = 0.6 / 12 = 5% — at the guideline ceiling; widen the tunnel or correct for blockage. Verify mesh independence (three refinements) and that residual controls, not endTime, terminate the run. 3. Drag map: simpleFoam; read Cd from postProcessing/forceCoeffs/0/coefficient.dat; CdA = Cd * Aref. 4. Convection map: add a solid region (battery/motor) and switch to chtMultiRegionFoam; integrate wall heat flux over the component surface, divide by (T_surface - T_air). That yields hA in W/K for the exposed* surface — if the component sits inside a frame bag/casing, the enclosure dominates and must be part of the solid region, otherwise the CHT number will exceed the vehicle model's effective conductance by ~10x. 5. Yaw sweep: rotating only the inlet U vector is NOT sufficient in this channel (the slip side walls would fight a yawed freestream). Either rotate the geometry per yaw point, or switch the side patches to inlet/outlet pairs consistent with the yawed freestream. 6. Wire the sweep into OpenFOAMBackend.evaluate (case-per-point, parse results), then run with EBIKE_USE_OPENFOAM=1.