Skip to content
FlowScript templates

Engineering — 2^k factorial design of experiments

A 2^3 full factorial on a laser weld, with the main effects and the interaction computed FROM the run matrix by selector rather than typed out of the analysis package. Typed FlowScript for reliability engineering. Keywords: FMEA, failure mode, RPN, reliability.

Template previewFlowScript
Lap-shear strength by laser power — all 24 weldsFigure: Lap-shear strength by laser power — all 24 welds. Violin plot. Horizontal axis: Value (N), linear scale, from 300 to 550. 2 series. 2.6 kW (401.5 N, interval 381.5 to 419, n = 12); 3.4 kW (483 N, interval 468.75 to 490, n = 12). Observations: n = 24 observations. Uncertainty: the interquartile range. Not stated in the figure data: axes, effect. 2.6 kW: n = 12, median 402 (IQR 382 to 419), mean 400 (SD 25), range 358 to 439, density bandwidth 13.8495 by the silverman rule. 3.4 kW: n = 12, median 483 (IQR 469 to 490), mean 481 (SD 20), range 449 to 519, density bandwidth 8.6250 by the silverman rule. 2.6 kW: Bandwidth h = 13.85 by the silverman rule. Both rules of thumb are derived for normal data and OVER-SMOOTH a multimodal density: if the violin's shape is the claim, show it at two bandwidths or say which one you chose. 2.6 kW: Quartiles by Hyndman–Fan type 7; the fences use the same definition, so the box and the outlier rule cannot disagree. 3.4 kW: Bandwidth h = 8.625 by the silverman rule. Both rules of thumb are derived for normal data and OVER-SMOOTH a multimodal density: if the violin's shape is the claim, show it at two bandwidths or say which one you chose. 3.4 kW: Quartiles by Hyndman–Fan type 7; the fences use the same definition, so the box and the outlier rule cannot disagree.Lap-shear strength by laser power — all 24 welds2.6 kW: kernel density, h = 13.8495 (silverman rule)2.6 kW: median 402, hinges 382 and 419, whiskers to 358 and 439 (1.5×IQR), mean 400mean 400.0002.6 kW: all 12 observation(s), jittered vertically by a seeded hash of each value399 N412 N425 N358 N371 N384 N417 N428 N439 N374 N389 N404 N2.6 kWn = 12, median 402 [382–419]3.4 kW: kernel density, h = 8.6250 (silverman rule)3.4 kW: median 483, hinges 469 and 490, whiskers to 449 and 519 (1.5×IQR), mean 481mean 480.7503.4 kW: all 12 observation(s), jittered vertically by a seeded hash of each value470 N486 N502 N449 N465 N481 N485 N502 N519 N455 N470 N485 N3.4 kWn = 12, median 483 [469–490]300350400450500550Value (N)Raincloud (Allen et al. 2019): half violin = Gaussian kernel density; box = median, hinges and Tukey 1.5×IQR whiskers with the mean as a diamond; points= every individual observation. The points are the data; the cloud and the box are summaries of them.Bandwidth by the silverman rule of thumb: 2.6 kW h = 13.8495; 3.4 kW h = 8.6250. A density's silhouette depends on its bandwidth as much as on itsdata, and both rules of thumb are derived for normal data — they OVER-smooth a genuinely multimodal density. If the shape is the claim, show it at twobandwidths.Vertical offsets in the rain are a deterministic hash of each observation's own value, its position in the list, and a seed taken from the block and group ids— never a random number. The same document therefore draws the same cloud on every machine and every run, and the offset carries no information.1 palette colour(s) darkened or lightened to clear 3:1 against the panel.

Make it your own.

// A 2^3 full factorial on a laser weld, with the main effects and the
// interaction computed FROM the run matrix by selector rather than typed
// out of the analysis package.
//
// The response is lap-shear strength of a copper tab to busbar weld in an
// EV battery module; the three factors are laser power, weld speed and
// shield-gas flow, each at two levels, three replicates per corner. Every
// effect below is a difference of means over the runs at the high and low
// level of one factor — which is what a main effect IS — so a corrected
// run moves the effect, its interval and the predicted optimum together.
//
// The interval is the same width for every effect because the design is
// balanced: half-width = t x 2s / sqrt(N), which depends on the design and
// the residual spread but not on which factor is being estimated. The
// figure shows the raw welds behind the largest of those effects, because
// a difference of means is only worth reading next to the spread it came
// from.

factorial_design weld_doe {
  title: "Laser welding of Cu tab to busbar — 2^3 factorial"
  design: "2^3 full factorial, 3 replicates, run order randomised, single operator, one coil of tab material"
  response: "Lap-shear strength at break"
  runs: 8
  replicates: 3
  total_runs: = runs * replicates
  blocking: "None. All 24 welds cut from one coil on one shift."
  pooled_sd: 14.6 N
  df_error: 16
  t_critical: 2.1199 source "Student t, two-sided 95%, 16 df"
  effect_se: = 2 * pooled_sd / sqrt(total_runs)
  effect_ci_half: = t_critical * effect_se
  grand_mean: = mean(kind:doe_run, "strength") * 1[N]
  specification: 450 N
}

factor laser_power {
  of: weld_doe
  name: "A — laser power"
  low: 2.6 kW
  high: 3.4 kW
  rationale: "Below 2.6 kW the weld does not key into the busbar; above 3.4 kW spatter contaminates the cell can."
}

factor weld_speed {
  of: weld_doe
  name: "B — weld speed"
  low: 120 mm/s
  high: 180 mm/s
  rationale: "180 mm/s is the takt the line needs; 120 mm/s is the current setting."
}

factor shield_gas {
  of: weld_doe
  name: "C — shield gas flow, argon"
  low: 12 L/min
  high: 20 L/min
  rationale: "Argon is metered per module and is a real running cost, so the effect is worth knowing even if it is small."
}

// The run matrix. Levels are written as plain numbers so the selectors
// below can match on them; the units for those levels live on the factor
// blocks above, stated once each.
doe_run run_1 {
  power: 2.6
  speed: 120
  gas: 12
  strength: 412
  sd: 13.0
  n: 3
}

doe_run run_2 {
  power: 3.4
  speed: 120
  gas: 12
  strength: 486
  sd: 16.0
  n: 3
}

doe_run run_3 {
  power: 2.6
  speed: 180
  gas: 12
  strength: 371
  sd: 13.0
  n: 3
}

doe_run run_4 {
  power: 3.4
  speed: 180
  gas: 12
  strength: 465
  sd: 16.0
  n: 3
}

doe_run run_5 {
  power: 2.6
  speed: 120
  gas: 20
  strength: 428
  sd: 11.0
  n: 3
}

doe_run run_6 {
  power: 3.4
  speed: 120
  gas: 20
  strength: 502
  sd: 17.0
  n: 3
}

doe_run run_7 {
  power: 2.6
  speed: 180
  gas: 20
  strength: 389
  sd: 15.0
  n: 3
}

doe_run run_8 {
  power: 3.4
  speed: 180
  gas: 20
  strength: 470
  sd: 15.0
  n: 3
}

// Each effect is a difference of means over the runs at the two levels of
// one factor, selected out of the matrix above. The interval is the same
// width for all four because the design is balanced.
effect effect_power {
  of: weld_doe
  label: "A — laser power, 2.6 to 3.4 kW"
  measure: md
  scale: identity
  unit: "N"
  direction: benefit
  point: = (mean(where(kind:doe_run, power == 3.4), "strength") - mean(where(kind:doe_run, power == 2.6), "strength")) * 1[N]
  lo: = point - weld_doe.effect_ci_half
  hi: = point + weld_doe.effect_ci_half
  level: 0.95
  df: 16
}

effect effect_speed {
  of: weld_doe
  label: "B — weld speed, 120 to 180 mm/s"
  measure: md
  scale: identity
  unit: "N"
  direction: harm
  point: = (mean(where(kind:doe_run, speed == 180), "strength") - mean(where(kind:doe_run, speed == 120), "strength")) * 1[N]
  lo: = point - weld_doe.effect_ci_half
  hi: = point + weld_doe.effect_ci_half
  level: 0.95
  df: 16
}

effect effect_gas {
  of: weld_doe
  label: "C — shield gas, 12 to 20 L/min"
  measure: md
  scale: identity
  unit: "N"
  direction: benefit
  point: = (mean(where(kind:doe_run, gas == 20), "strength") - mean(where(kind:doe_run, gas == 12), "strength")) * 1[N]
  lo: = point - weld_doe.effect_ci_half
  hi: = point + weld_doe.effect_ci_half
  level: 0.95
  df: 16
}

effect effect_power_speed {
  of: weld_doe
  label: "AB — power by speed interaction"
  measure: md
  scale: identity
  unit: "N"
  direction: none
  point: = 0.5 * ((mean(where(kind:doe_run, power == 3.4 and speed == 180), "strength") - mean(where(kind:doe_run, power == 2.6 and speed == 180), "strength")) - (mean(where(kind:doe_run, power == 3.4 and speed == 120), "strength") - mean(where(kind:doe_run, power == 2.6 and speed == 120), "strength"))) * 1[N]
  lo: = point - weld_doe.effect_ci_half
  hi: = point + weld_doe.effect_ci_half
  level: 0.95
  df: 16
}

// All 24 welds, split at the factor that matters. The corner means above
// are the summaries of these values; the pooled standard deviation the
// intervals rest on is the root mean square of the eight corner s values.
distribution weld_strength {
  title: "Lap-shear strength by laser power — all 24 welds"
  kind: raincloud
  unit: "N"
  whisker: tukey
  jitter: true
  n: 24

  group power_low {
    label: "2.6 kW"
    values: [399, 412, 425, 358, 371, 384, 417, 428, 439, 374, 389, 404]
    n: 12
    mean: 400.00
  }

  group power_high {
    label: "3.4 kW"
    values: [470, 486, 502, 449, 465, 481, 485, 502, 519, 455, 470, 485]
    n: 12
    mean: 480.75
  }
}

// The setting the effects imply: high power, low speed, high gas. The
// prediction uses half of each effect because the effects are stated per
// full step from low to high.
doe_prediction best_setting {
  of: weld_doe
  setting: "3.4 kW, 120 mm/s, 20 L/min argon"
  predicted_strength: = weld_doe.grand_mean + effect_power.point / 2 - effect_speed.point / 2 + effect_gas.point / 2 - effect_power_speed.point / 2
  observed_at_setting: 502 N
  margin_over_specification: = predicted_strength - weld_doe.specification
  confirmation: "Six confirmation welds at this setting averaged 498 N, inside the prediction interval."
}

note takt_conflict {
  text: "Speed is the only factor the line cares about and the only one with a negative effect: running at the takt the line needs costs about 33 N of strength. The confirmation runs still clear the 450 N specification at 180 mm/s and 3.4 kW, so the answer is more power rather than a slower line."
  anchor: weld_doe
}

view strength: raincloud(weld_strength)

caption strength_caption {
  of: strength
  title: "Lap-shear strength at the two power levels"
  text: "Every weld in the design, split at the largest main effect. The gap between the two clouds is the 80.7 N power effect; the spread within each is what the confidence interval on that effect is built from."
  statistics: "Box shows median and hinges with Tukey whiskers; all 24 welds are drawn. Effect intervals use t(16 df) x 2s / sqrt(24), s = 14.6 N."
  n_statement: "n = 24 welds, 8 corners x 3 replicates."
  style: journal
}