kcl-samples → battery-module-cooling-plate
battery-module-cooling-plate

KCL
// Battery Module Cooling Plates
// A battery module cooling plate is a thermal management component used in battery packs—particularly in electric vehicles (EVs), energy storage systems, and other high-power applications—to regulate the temperature of individual battery cells or entire modules.
// Define units
@settings(defaultLengthUnit = mm)
// Define number of coolings per side
numberOfCoolingsPerSide = 5
// Define at least 3 coolings per side
assert(
numberOfCoolingsPerSide,
isGreaterThanOrEqual = 3,
isLessThan = 100,
error = "Number of coolings should be between 3 and 100",
)
// thickness of the channels
thickness = 17
thickness2 = thickness * 2
// depth of the channels
csgCuttingDepthThicknessOfChannel = 5
// connector dimensions
connectorLength = thickness + 10
// widths for the cooling sketch channels
w1 = 30
w2 = w1 * 2
w5 = w1 * 5
totalWidth = w1 * 5
legLength = w2
overLap = w1 - thickness
// compute the width of the sketches side by side
widthOfCoolingSketches = (w5 + thickness + overLap) * numberOfCoolingsPerSide
offsetX = thickness2
// compute the offset to the edge of the base plate
heightOfCoolingSketch = w1 + overLap + thickness
// dimensions of the plate
plateWidth = widthOfCoolingSketches + w2 + thickness + overLap + offsetX + connectorLength
plateHeight = 200
plateThickness = 10
// initial sketch positions
startX = plateWidth / 2 - offsetX - connectorLength
startY = (thickness + w1) / 2
// compute the offset to the edge of the base plate
edgeOfBasePlate = -(plateWidth / 2)
startHeadOfCoolingY = -startX - heightOfCoolingSketch + widthOfCoolingSketches - overLap + heightOfCoolingSketch
sketchXy = startSketchOn(XY)
fn getOverlap(@id) {
return overLap
}
// index the margins for the lengths of the cooling sketches
overlapMargins = map([0 .. numberOfCoolingsPerSide - 2], f = getOverlap)
margins = push(overlapMargins, item = -thickness)
// Dimensions for the mounting holes
mountingRadius = 6
mountingBuffer = 5 + mountingRadius
// Create the base plate to be cut
basePlateExtruded = startProfile(sketchXy, at = [-plateWidth / 2, plateHeight / 2])
|> angledLine(angle = 0, length = plateWidth, tag = $rectangleSegmentA001)
|> angledLine(angle = segAng(rectangleSegmentA001) - 90, length = plateHeight)
|> angledLine(angle = segAng(rectangleSegmentA001), length = -segLen(rectangleSegmentA001))
|> line(endAbsolute = [profileStartX(), profileStartY()])
|> close()
|> extrude(length = plateThickness)
// Get extruded END face of the base plate to sketch on
basePlateEndFace = startSketchOn(basePlateExtruded, face = END)
fn coolingSketch(plane, startPoint, legLength, margin) {
coolingSketch = startProfile(plane, at = startPoint)
|> xLine(length = -legLength)
|> yLine(length = w1 - thickness)
|> xLine(length = w2)
|> yLine(length = w1 + thickness)
|> xLine(length = -w5 - thickness)
|> yLine(length = -w1 - thickness)
|> xLine(length = w2)
|> yLine(length = -w1 + thickness)
|> xLine(length = -legLength - margin)
|> yLine(length = -thickness)
|> xLine(length = legLength + margin + thickness)
|> yLine(length = w1 + thickness)
|> xLine(length = -w2)
|> yLine(length = w1 - thickness)
|> xLine(length = w5 - thickness)
|> yLine(length = -(w1 - thickness))
|> xLine(length = -w2)
|> yLine(length = -w1 - thickness)
|> xLine(length = legLength + thickness)
|> close()
return coolingSketch
}
fn coolingSketchNoArms(plane, startPoint) {
coolingSketch = startProfile(plane, at = startPoint)
|> yLine(length = w1 - thickness)
|> xLine(length = w2)
|> yLine(length = w1 + thickness)
|> xLine(length = -w5 - thickness)
|> yLine(length = -w1 - thickness)
|> xLine(length = w2)
|> yLine(length = -w1 + thickness)
|> yLine(length = -thickness)
|> xLine(length = thickness)
|> yLine(length = w1 + thickness)
|> xLine(length = -w2)
|> yLine(length = w1 - thickness)
|> xLine(length = w5 - thickness)
|> yLine(length = -(w1 - thickness))
|> xLine(length = -w2)
|> yLine(length = -w1 - thickness)
|> xLine(length = thickness)
|> close()
return coolingSketch
}
fn drawCoolingSketch(@id) {
return coolingSketch(
plane = basePlateEndFace,
startPoint = [
startX - (totalWidth * id) - (w1 * id),
startY
],
legLength = legLength,
margin = margins[id],
)
|> extrude(length = -csgCuttingDepthThicknessOfChannel)
}
fn drawCoolingSketchFlipped(@id) {
return coolingSketch(
plane = basePlateEndFace,
startPoint = [
startX - (totalWidth * id) - (w1 * id),
startY
],
legLength = legLength,
margin = margins[id],
)
|> rotate(roll = 0, pitch = 0, yaw = 180)
|> translate(x = 0, y = 0, z = 0)
|> scale(x = -1, y = 1, z = 1)
|> extrude(length = -csgCuttingDepthThicknessOfChannel)
}
// Create mounting holes
mount1 = circle(
basePlateEndFace,
center = [
-plateWidth / 2 + mountingBuffer,
plateHeight / 2 - mountingBuffer
],
radius = mountingRadius,
)
|> extrude(length = -plateThickness)
mount2 = circle(
basePlateEndFace,
center = [
-(-plateWidth / 2 + mountingBuffer),
plateHeight / 2 - mountingBuffer
],
radius = mountingRadius,
)
|> extrude(length = -plateThickness)
mount3 = circle(
basePlateEndFace,
center = [
-(-plateWidth / 2 + mountingBuffer),
-(plateHeight / 2 - mountingBuffer)
],
radius = mountingRadius,
)
|> extrude(length = -plateThickness)
mount4 = circle(
basePlateEndFace,
center = [
-plateWidth / 2 + mountingBuffer,
-(plateHeight / 2 - mountingBuffer)
],
radius = mountingRadius,
)
|> extrude(length = -plateThickness)
// Draw one half of the cooling sketchs
coolings = map([0 .. numberOfCoolingsPerSide - 1], f = drawCoolingSketch)
// Draw the other mirrored half of cooling sketchs
coolingsFlipped = map([0 .. numberOfCoolingsPerSide - 1], f = drawCoolingSketchFlipped)
// Draw the cooling sketch that connects both halves
headOfTableCooling = coolingSketchNoArms(plane = basePlateEndFace, startPoint = [0, 0])
|> rotate(roll = 0, pitch = 0, yaw = 90)
|> translate(x = startY, y = startHeadOfCoolingY, z = 0)
|> extrude(length = -csgCuttingDepthThicknessOfChannel)
// Extend the ends of the cooling sketch
connector1 = startProfile(basePlateEndFace, at = [startX, startY])
|> xLine(length = connectorLength)
|> yLine(length = -thickness)
|> xLine(length = -connectorLength)
|> line(endAbsolute = [profileStartX(), profileStartY()])
|> close()
|> extrude(length = -csgCuttingDepthThicknessOfChannel)
connector2 = startProfile(basePlateEndFace, at = [startX, startY])
|> xLine(length = connectorLength)
|> yLine(length = -thickness)
|> xLine(length = -connectorLength)
|> line(endAbsolute = [profileStartX(), profileStartY()])
|> close()
|> rotate(roll = 0, pitch = 0, yaw = 180)
|> translate(x = 0, y = 0, z = 0)
|> scale(x = -1, y = 1, z = 1)
|> extrude(length = -csgCuttingDepthThicknessOfChannel)