Resources Numerical accuracy Calculation policy

Solar one-line currents, devices and wires

Works out the current on each run of a solar one-line diagram and picks the overcurrent device and wire size from the tables the person gives.

How the precision is kept

Currents are 64-bit products of the module and inverter values and the typed factors. Each run's device and wire are the smallest table entries that carry the required current. The currents kept on the diagram are rounded to 0.1 A, and one run takes its required current from the rounded value of the run before it.

Open item. Size the run from the DC disconnect to the inverter from the unrounded required current, not from the 0.1 A value stored on the previous run.

Calculations under this policy

6 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.

pv-oneline.js BimCraft 0.8.1 64-bit 6 calculations Reviewed

Tests tools/bimcraft-test/eg-pv-test.mjs

Overcurrent device size

64-bit

The smallest standard device that is at least the required current.

smallest x in the list with x ≥ amps − 1e-9

The list is sorted and searched; the 1e-9 A allowance keeps a requirement that equals a standard size, but for rounding, from moving up a size. Returns nothing when no device is large enough.

  • pv-oneline.js
  • line 27
  • BimCraft 0.8.1
export function nextOcpd(amps, list = CODE_DEFAULTS.ocpd) { const l = [...list].sort((a, b) => a - b); return l.find((x) => x >= amps - 1e-9) ?? null; }

Wire size

64-bit

The smallest wire whose ampacity, after derating, is at least the required current.

smallest wire with ampacity × derate ≥ amps − 1e-9

Ampacities come from the table the person gives; the derate factor multiplies the ampacity rather than dividing the current.

  • pv-oneline.js
  • line 28
  • BimCraft 0.8.1
export function pickWire(amps, table = CODE_DEFAULTS.wire, derate = 1) { const t = [...table].sort((a, b) => a.amps - b.amps); return t.find((w) => w.amps * derate >= amps - 1e-9) ?? null; }

A run on the diagram

64-bit

Records one run with its current, required current, device and wire.

device and wire from the required current; stored current and required current rounded to 0.1 A

The device and wire are picked from the required current as passed in, before rounding. The current and required current kept on the run are rounded to 0.1 A with Math.round(x × 10) ÷ 10.

  • pv-oneline.js
  • line 36
  • BimCraft 0.8.1
const edge = (a, b, circuit, current, extra = {}) => { const required = extra.required ?? current; const o = nextOcpd(required, C.ocpd), w = pickWire(required, C.wire, C.derate); edges.push({ id: 'e' + (edges.length + 1), from: a.id, to: b.id, circuit, current: r1(current), required: r1(required), ocpd: extra.noOcpd ? null : o, wire: w?.size ?? null, ...(extra.label ? { label: extra.label } : {}), ...(o === null || w === null ? { over: true } : {}) }); };

DC currents of an array

64-bit

The current of one string circuit and of the array's combined output, with the required values.

per circuit = I_sc factor × continuous factor × I_sc; output = strings × I_sc; required = factor × output

Products of the module's short-circuit current, the string count and the two typed factors (1.25 each in the example set). Nothing is rounded before the device and wire are picked for these runs.

  • pv-oneline.js
  • lines 47 to 57
  • BimCraft 0.8.1
const Iscs = M.isc, perCircuit = factor * Iscs;
const combine = S.count >= C.fuseFromStrings;
let last = arr;
if (combine) {
  const cb = node('combiner', 'DC combiner', 1, row, { inputs: S.count, fuse: nextOcpd(perCircuit, C.ocpd) });
  edge(arr, cb, 'dc', Iscs, { required: perCircuit, label: S.count + ' strings of ' + S.n });
  last = cb;
}
const out = S.count * Iscs, req = factor * out;
totals.dcCurrentMax = Math.max(totals.dcCurrentMax, out);
const dd = node('disconnect', 'DC disconnect', 2, row, { rated: nextOcpd(req, C.ocpd) });

Run from the DC disconnect to the inverter

64-bit

The current, device and wire of the run into each inverter.

This run reads the current and required current back from the previous run, where both were already rounded to 0.1 A, and picks its device and wire from that rounded requirement. A requirement of 20.03 A, for example, gives a 25 A device on the previous run and a 20 A device here.

  • pv-oneline.js
  • line 68
  • BimCraft 0.8.1
for (const d of dcDisc.filter((x) => x.ii === i)) edge(d.node, n, 'dc', edges.find((e) => e.to === d.node.id)?.current ?? 0, { required: edges.find((e) => e.to === d.node.id)?.required, label: 'to inverter input' });

AC current of an inverter

64-bit

The output current of one inverter at the service voltage.

I = P_ac × 1000 ÷ (V × √3) for three-phase; I = P_ac × 1000 ÷ V for single-phase

One expression with Math.sqrt(3) at full precision. The voltage is not guarded against 0. No power factor is applied.

  • pv-oneline.js
  • line 63
  • BimCraft 0.8.1
const perInvAc = inv.pacKw * 1000 / (ac.voltage * (ac.phases === 3 ? Math.sqrt(3) : 1));

In detail

Method
DC: current = strings × I_sc, required = I_sc factor × continuous factor × current. AC: I = P ÷ (V × √3) for three-phase, P ÷ V for single-phase. Device = smallest standard size ≥ required; wire = smallest whose ampacity × derate ≥ required.
Number types
64-bit numbers; table lookups; currents on the diagram rounded to 0.1 A, power to 0.01 kW.
Tolerances
Table lookups allow 1e-9 A under the required current.
Limits
The file states that the factors and wire table are examples for the person to replace and that nothing here says a design complies with a code. The run from the DC disconnect to the inverter is sized from the previous run's current after it was rounded to 0.1 A, so a requirement just above a standard size can round down to that size.

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