Resources Numerical accuracy Calculation policy

Capital and operating cost

Estimates the purchased and installed cost of process equipment and the yearly cost of its energy.

How the precision is kept

The arithmetic is a handful of 64-bit expressions. The numbers are textbook correlations whose constants, the file says, were typed from memory and must be compared with the book; the result is a base-year (2001) cost unless the person supplies a cost index. The calculator states an accuracy of ±30 to ±50 % with every result.

Calculations under this policy

5 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.

process/cost.js CadCraft 0.8.2 64-bit 5 calculations Reviewed

Tests tools/process-test/test.mjs

Purchased cost of one item

64-bit

The purchased cost of an equipment item of a given size, in base-year dollars or scaled by a cost index.

C₀ = 10^(K₁ + K₂ log₁₀ A + K₃ (log₁₀ A)²); C = C₀ × I_now ÷ I_base

One logarithm and one power. The K constants are typed to four or five digits and marked as not yet checked against the book; the notes returned with the cost say so.

  • process/cost.js
  • lines 25 to 34
  • CadCraft 0.8.2
/** Base-year purchased cost (US$) of equipment `kind` at size A, with the problems (outside the correlation's range, constants unchecked). */
export function purchased(kind, A, index = null) {
  const e = EQUIPMENT[kind]; if (!e) throw new Error('unknown equipment ' + kind);
  const l = Math.log10(A), c0 = Math.pow(10, e.K[0] + e.K[1] * l + e.K[2] * l * l), notes = [];
  if (A < e.min || A > e.max) notes.push(`size ${A} ${e.unit} is outside the correlation's range ${e.min}–${e.max} ${e.unit}`);
  if (e.check) notes.push('the correlation constants have not been checked against the book yet');
  const ratio = index && index.now ? index.now / (index.base || TURTON_BASE.cepci) : null;
  if (ratio == null) notes.push('no cost index given: this is a ' + TURTON_BASE.year + ' base-year cost');
  return { base: c0, cost: ratio == null ? c0 : c0 * ratio, indexRatio: ratio, year: ratio == null ? TURTON_BASE.year : null, notes, unit: e.unit };
}

Six-tenths scaling

64-bit

A known cost scaled to another size.

C₂ = C₁ (A₂ ÷ A₁)^n, n = 0.6 unless given

One division and one power. The exponent is a rule of thumb.

  • process/cost.js
  • line 35
  • CadCraft 0.8.2
export const scale = (c1, a1, a2, n = 0.6) => c1 * Math.pow(a2 / a1, n);

Installed cost

64-bit

The installed plant cost from the purchased equipment total.

installed = purchased × Lang factor (3.10 solid, 3.63 solid–fluid, 4.74 fluid)

One multiplication by a factor of three significant digits.

  • process/cost.js
  • line 36
  • CadCraft 0.8.2
export const installed = (purchasedTotal, kind = 'fluid') => purchasedTotal * LANG[kind];

Energy cost

64-bit

The cost of energy per hour and per year for a list of powers and prices.

per hour = Σ |P| ÷ 1000 × price; per year = per hour × hours (8000 unless given)

Items are added in list order. An item with no price is named in the result and not added.

  • process/cost.js
  • lines 37 to 42
  • CadCraft 0.8.2
/** Operating cost per second and per year: items [{ name, power (W), price ($/kWh) }], hours per year. Items without a price are listed, not guessed. */
export function operating(items, hours = 8000) {
  let perHour = 0; const rows = [], missing = [];
  for (const it of items) { if (it.price == null) { missing.push(it.name); continue; } const c = Math.abs(it.power) / 1000 * it.price; perHour += c; rows.push({ name: it.name, perHour: c }); }
  return { perHour, perYear: perHour * hours, rows, missing };
}

Equipment cost table

64-bit

The cost of every item, the purchased total and the installed total.

purchased = Σ cost of the rows; installed = purchased × Lang factor

The total is a plain sum in row order, kept unrounded.

  • process/cost.js
  • lines 43 to 48
  • CadCraft 0.8.2
/** Equipment list → cost table: rows [{ name, kind, A }] ; returns purchased, installed (Lang), totals and the notes. */
export function capital(rows, { index = null, plant = 'fluid' } = {}) {
  const out = []; let total = 0; const notes = new Set();
  for (const r of rows) { const p = purchased(r.kind, r.A, index); out.push({ ...r, cost: p.cost, base: p.base }); total += p.cost; p.notes.forEach((n) => notes.add(n)); }
  return { rows: out, purchased: total, installed: installed(total, plant), lang: LANG[plant], notes: [...notes], sources: COST_SOURCES };
}

In detail

Method
log₁₀ C = K₁ + K₂ log₁₀ A + K₃ (log₁₀ A)² (Turton et al., App. A, as cited); six-tenths scaling; Lang factors; index ratio.
Number types
64-bit numbers. Constants of four or five significant digits, each equipment entry flagged check: true.
Checked by
tools/process-test/test.mjs checks that the library copy of purchased reproduces its own formula for a pump; the copy is byte-identical.
Limits
A size outside the correlation's range is computed anyway and noted. An energy item without a price is listed and left out of the total.

Approach: 64-bit, stated limit

The arithmetic is 64-bit, but the method or the data sets the accuracy: a solver tolerance, a mesh, a step size, a datum shift, a table. The limit is stated where the result is shown.

Every policy that takes this approach