{"sections":[{"heading":"What this model represents","paragraphs":["For positive voltage V(p)-V(n), positive device current flows from p to n. The terminal current is I(v) + dQ(v)/dt; its small-signal admittance about a selected bias is dI/dv + j*omega*dQ/dv. Keep static current, total transient current and an AC phasor distinct.","Use Yname p n model with .MODEL name POLY(...). B remains the Josephson-junction designator. I(v)=I0+I1*v+I2*v^2+I3*v^3 and Q(v)=Q0+Q1*v+Q2*v^2+Q3*v^3; coefficient units are A/V^r and C/V^r respectively. A constant Q0 has zero derivative and is not a capacitance."]},{"heading":"Prepare the complete teaching inputs","paragraphs":["Use a compatible licensed JoSIM-Pro 2.9.0 Windows runtime and a writable copy of the complete download. Keep the chosen model include with all four matching .cir inputs. The standalone Python 3 checker needs no third-party packages; set $Python, $JoSIM and $Licence to full paths. $Licence must be the issued JoSIM-Pro file, distinct from an InductEx licence.","These are synthetic model checks. Agreement does not calibrate a measured semiconductor, establish cryogenic validity or prove stability or uniqueness for another topology."]},{"figures":[{"asset_id":"josim-poly-dc-response","caption":"The DC horizontal coordinate is swept source voltage, not time. OP.iterations and OP.normalized_residual are dimensionless diagnostics, not device signals."}],"heading":"Run and inspect the model in the GUI","paragraphs":[],"steps":["Open poly-op.cir from the writable copy, confirm its saved source and include, then use Run simulation. Read the scalar values and units; an operating point is not a waveform.","Open and run poly-dc.cir. Its seven independently solved points sweep V1 from -0.1 V to 0.5 V in 0.1 V steps. The horizontal coordinate is source voltage, not elapsed time.","Open and run poly-ac.cir. The selected bias is 0.2 V; frequencies are 1, 2 and 3 GHz. The one-volt, 30-degree peak reference phasor multiplies the local admittance; it does not simulate a physically qualified one-volt nonlinear excursion.","Open and run poly-tran.cir with the explicit fixed-step VOLTAGE/BDF options. The voltage ramps from -0.1 V to 0.5 V over 2 ns, using 5 ps steps and output cadence. Read voltage and total current with their separate display units.","Before rerunning an edit, choose Yes to save and run the intended source. Cancel creates no new task. No uses the saved file; it does not simulate the unsaved text. The checked path can nevertheless label that document Results current, so verify saved input and current output identity."]},{"figures":[{"asset_id":"josim-poly-transient-response","caption":"The first sample is the initial static current. The later current includes charge response to the ramp; the independently checked interior excludes startup and the final ramp corner."}],"heading":"Interpret current and charge separately","paragraphs":["At 0.2 V this polynomial gives 300 microamps, differential conductance 1.08 mS and differential capacitance 2.52 pF. At DC, dQ/dt is zero. During the ramp, add (Q1+2*Q2*v+3*Q3*v^2) times 3e8 V/s. The Q0=7p constant does not change transient current; changing it to zero reproduced the same arrays.","The initial sample contains the static initial current. Startup charge history and the final ramp corner are excluded from the differentiable-interior reference check; a plotted initial current jump is not itself proof of an error."]},{"heading":"Compare time refinement with the independent reference","paragraphs":["The checker also runs 20 ps and 2.5 ps copies without changing the canonical inputs. Coarse solver completion is distinct from the current-error criterion. For this fixture, 20 ps misses the criterion, while 5 ps and 2.5 ps meet it and the latter reduces the maximum interior error.","The polynomial interior bound is 10 nA. Maximum errors are approximately 64.8, 4.05 and 1.0125 nA at 20, 5 and 2.5 ps. The cubic-charge BDF2 truncation predicts 2*Q3*(3e8)^3*h^2, independently explaining this refinement pattern. The bound belongs to this supplied fixture, not arbitrary POLY models."]},{"heading":"Recognise limits and recover a rejected run","paragraphs":["D/Y transients require fixed-step VOLTAGE/BDF in the checked runtime. PHASE and TRAP reject these transients; adaptive stepping also fails the shared runtime contract. Mixed Josephson transients and checkpoint pause/resume remain outside the documented model support.","Unknown model fields and unsupported instance attributes are errors. The checked controls reject AREA=0, FC=1 and a mismatched diode .TEMP; Y accepts the model name, not a diode AREA attribute. POLY negative finite coefficients are permitted, without a passivity guarantee.","A deliberately insufficient Newton iteration limit fails without a new static report and preserves a pre-existing authoritative report. Restoring the ordinary limit and rerunning at the same bias gives a fresh checked result. Correct the first diagnostic and use a new output generation; an iteration limit alone does not tighten an already accepted residual gate."]},{"figures":[{"asset_id":"josim-nonlinear-save-before-run","caption":"Choose Yes to run the visible edit. No can retain a stale task while the document incorrectly says Results current; verify source identity and the new numerical data."}],"heading":"Save the refinement edit deliberately","paragraphs":["The native scenario checked Cancel, No and both explicit Yes/save choices. No retained the original 401-sample saved run while preserving the edited 20 ps buffer. Yes saved and ran that buffer, producing 101 samples. Normal Undo followed by another Yes/save and Run restored the original source and 401-sample arrays. A separately launched app explicitly reopening the saved input reproduced them.","KB-RESULT-001 retains the No-path document-label contradiction. Compare saved source, task receipt and output data; do not use Results current alone as proof that the visible unsaved text was executed."]},{"code":"& $Python -B .\\run_models.py --device poly --josim $JoSIM --licence $Licence --expected-version 2.9.0 --output-root .\\poly-review\nif ($LASTEXITCODE -ne 0) { throw 'The polynomial teaching reference did not pass; inspect the new receipt and first diagnostic.' }","heading":"Check the polynomial teaching model","paragraphs":["Run in the extracted input directory. The output root must be new. The helper records the actual version, source and output hashes, isolates its own configuration and leaves the issued licence unchanged. Raw logs and receipts can contain local paths and licence-holder details; keep them private.","A zero polynomial-client exit and passed receipt require all stated checks. The diode command instead checks the exact retained failure and its separate transient criteria; it is not a successful reverse-current validation."]},{"code":".MODEL PM POLY(I0=.1m I1=1m I2=-.4m I3=2m Q0=7p Q1=2p Q2=.4p Q3=3p)","heading":"Save poly.inc"},{"code":"* Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 DC .2\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.OP\n.END","heading":"Save poly-op.cir"},{"code":"* Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 DC .1\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.DC V1 -.1 .5 .1\n.END","heading":"Save poly-dc.cir"},{"code":"* Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 DC .2 AC 1 30\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.AC LIN 3 1G 3G\n.PRINT AC V(N) I(Y1)\n.END","heading":"Save poly-ac.cir"},{"code":"* Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 PWL(0 -.1 2n .5)\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.TRAN 5p 2n 0 5p\n.PRINT V(N) I(Y1)\n.END","heading":"Save poly-tran.cir"},{"code":"\"\"\"Check the supplied Windows diode or POLY teaching inputs with JoSIM-Pro.\"\"\"\nimport argparse\nimport cmath\nimport csv\nimport hashlib\nimport io\nimport json\nimport math\nimport os\nfrom pathlib import Path\nimport re\nimport subprocess\nimport sys\n\nSTOP = 2e-9\nSLOPE = .6 / STOP\nRUNTIME_BOLTZMANN = 1.38064852e-23\nSI_BOLTZMANN = 1.380649e-23\n\n\ndef sha(path):\n    return hashlib.sha256(path.read_bytes()).hexdigest()\n\n\ndef equation(kind, voltage, boltzmann=RUNTIME_BOLTZMANN):\n    \"\"\"Independent conduction current and differential charge for these inputs.\"\"\"\n    v = voltage\n    if kind == 'poly':\n        current = .0001 + .001 * v - .0004 * v**2 + .002 * v**3\n        capacitance = 2e-12 + .8e-12 * v + 9e-12 * v**2\n        conductance = .001 - .0008 * v + .006 * v**2\n    else:\n        # The checked runtime retains an older k_B. Report the exact-SI\n        # comparison separately; this is not an accuracy or calibration waiver.\n        vt = boltzmann * 300.15 / 1.602176634e-19\n        current = 2e-12 * math.expm1(v / vt)\n        conductance = 2e-12 * math.exp(v / vt) / vt\n        # AREA=2 scales both conduction and charge. At FC*VJ, continue\n        # depletion capacitance linearly with its boundary slope.\n        if v < .35:\n            depletion = 4e-12 / math.sqrt(1 - v / .7)\n        else:\n            at_boundary = 4e-12 / math.sqrt(.5)\n            depletion = at_boundary * (1 + .5 * (v - .35) / (.7 * .5))\n        capacitance = depletion + 1e-9 * conductance\n    return current, conductance, capacitance\n\n\ndef table(path):\n    text = path.read_text(encoding='utf-8-sig')\n    metadata = None\n    if text.startswith('# josim-ac-csv/1 '):\n        first, text = text.split('\\n', 1)\n        metadata = json.loads(first[len('# josim-ac-csv/1 '):])\n    rows = list(csv.reader(io.StringIO(text)))\n    names = rows[0]\n    data = [[float(value) for value in row] for row in rows[1:] if row]\n    if not data or len(names) != len(set(names)) or any(\n            len(row) != len(names) or not all(math.isfinite(x) for x in row) for row in data):\n        raise ValueError('Missing, duplicate, ragged or nonfinite numerical data')\n    return metadata, names, data\n\n\ndef close(actual, expected):\n    return math.isclose(actual, expected, rel_tol=1e-9, abs_tol=1e-15)\n\n\ndef static_check(kind, path, swept):\n    _, names, rows = table(path)\n    device = 'D1' if kind == 'diode' else 'Y1'\n    axes = [-.1 + .1 * i for i in range(7)] if swept else [.2]\n    if len(rows) != len(axes):\n        raise ValueError('Unexpected static sample count')\n    errors, si_differences, comparisons = [], [], []\n    for axis, row in zip(axes, rows):\n        values = dict(zip(names, row))\n        expected = equation(kind, axis)[0]\n        ok = (close(values['V(N) (V)'], axis)\n              and 0 <= values['OP.normalized_residual (1)'] <= 1)\n        if swept:\n            ok = ok and close(values['Sweep(V1) (V)'], axis)\n        if not ok:\n            raise ValueError('Static voltage, sweep coordinate or solver residual gate failed')\n        errors.append(abs(values['I(' + device + ') (A)'] - expected))\n        si_current = equation(kind, axis, SI_BOLTZMANN)[0]\n        si_differences.append(abs(values['I(' + device + ') (A)'] - si_current))\n        comparisons.append({'bias_V': axis, 'actual_current_A': values['I(' + device + ') (A)'],\n                            'runtime_equation_A': expected, 'exact_SI_equation_A': si_current,\n                            'normalized_residual': values['OP.normalized_residual (1)'],\n                            'current_match': close(values['I(' + device + ') (A)'], expected),\n                            'source_current_match': close(values['I(V1) (A)'], -expected)})\n    return {'samples': len(rows), 'max_current_error_A': max(errors),\n            'max_current_difference_from_exact_SI_A': max(si_differences),\n            'comparisons': comparisons,\n            'strict_current_reference_passed': all(row['current_match'] and row['source_current_match'] for row in comparisons),\n            'reference': 'Explicit runtime k_B; exact-SI difference is separate' if kind == 'diode' else 'Polynomial coefficients'}\n\n\ndef ac_check(kind, path):\n    metadata, names, rows = table(path)\n    device = 'D1' if kind == 'diode' else 'Y1'\n    expected_names = ['frequency (Hz)', 'Re(V(N)) (V)', 'Im(V(N)) (V)',\n                      'Re(I(' + device + ')) (A)', 'Im(I(' + device + ')) (A)']\n    if names != expected_names or len(rows) != 3 or metadata is None:\n        raise ValueError('Unexpected AC schema or sample count')\n    if (metadata.get('phasor_convention') != 'peak_exp_positive_j'\n            or str(metadata.get('effective_seed')) != '321'):\n        raise ValueError('Unexpected AC convention or seed')\n    _, conductance, capacitance = equation(kind, .2)\n    source = cmath.rect(1, math.pi / 6)\n    errors = []\n    for frequency, rv, iv, ri, ii in rows:\n        expected = source * complex(conductance, 2 * math.pi * frequency * capacitance)\n        errors.append(abs(complex(ri, ii) - expected))\n        if abs(complex(rv, iv) - source) > 1e-12 or errors[-1] > 1e-11:\n            raise ValueError('AC phasor differs from the bias derivative reference')\n    if [row[0] for row in rows] != [1e9, 2e9, 3e9]:\n        raise ValueError('AC frequency axis differs from the requested grid')\n    return {'samples': 3, 'conductance_S': conductance, 'capacitance_F': capacitance,\n            'max_current_phasor_error_A': max(errors)}\n\n\ndef transient_check(kind, path, step):\n    _, names, rows = table(path)\n    device = 'D1' if kind == 'diode' else 'Y1'\n    if names != ['time', 'V(N)', 'I(' + device + ')'] or len(rows) != round(STOP / step) + 1:\n        raise ValueError('Unexpected transient columns or sample count')\n    if not close(rows[0][2], equation(kind, -.1)[0]):\n        raise ValueError('The initial sample must contain the static initial current')\n    errors, ratios = [], []\n    for index, (time, voltage, current) in enumerate(rows):\n        if abs(time - index * step) > 1e-20 or abs(voltage - (-.1 + SLOPE * time)) > 1e-12:\n            raise ValueError('Unexpected transient time or imposed-voltage coordinate')\n        # Initial charge history and the final ramp corner are distinct from\n        # the differentiable interior used for the time-discretisation check.\n        if index < 3 or index == len(rows) - 1:\n            continue\n        conduction, _, capacitance = equation(kind, voltage)\n        expected = conduction + capacitance * SLOPE\n        error = abs(current - expected)\n        bound = 1e-8 if kind == 'poly' else 1e-8 + .001 * abs(expected)\n        errors.append(error)\n        ratios.append(error / bound)\n    return {'samples': len(rows), 'interior_samples': len(errors), 'step_s': step,\n            'max_current_error_A': max(errors), 'max_bound_ratio': max(ratios),\n            'reference_bound_passed': max(ratios) <= 1}\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=__doc__)\n    parser.add_argument('--device', choices=['diode', 'poly'], required=True)\n    parser.add_argument('--josim', type=Path, required=True)\n    parser.add_argument('--licence', type=Path, required=True)\n    parser.add_argument('--expected-version', required=True)\n    parser.add_argument('--output-root', type=Path, required=True)\n    args = parser.parse_args()\n    source = Path(__file__).resolve().parent\n    names = [args.device + '.inc'] + [args.device + '-' + mode + '.cir' for mode in ('op', 'dc', 'ac', 'tran')]\n    try:\n        if os.name != 'nt':\n            raise ValueError('This checked launcher is Windows-specific')\n        binary, licence = args.josim.resolve(strict=True), args.licence.resolve(strict=True)\n        root = args.output_root.resolve()\n        if not binary.is_file() or not licence.is_file() or root.exists():\n            raise ValueError('Use existing executable/licence files and a new output root')\n        if any(c in str(licence) for c in '\\r\\n'):\n            raise ValueError('The licence path cannot contain a line break')\n        licence_hash = sha(licence)\n        inputs = {name: sha(source / name) for name in names}\n        root.mkdir(parents=True, exist_ok=False)\n    except (OSError, ValueError) as error:\n        print('Preflight refused: ' + str(error), file=sys.stderr)\n        return 2\n    receipt = {'status': 'failed', 'device': args.device, 'inputs': inputs,\n               'scope': 'Supplied synthetic Windows teaching inputs only; no measured-device calibration'}\n    try:\n        home = root / 'home'\n        (home / '.josimpro').mkdir(parents=True)\n        (home / '.josimpro/config.ini').write_text('[General]\\nLicenseLocation=' + str(licence) + '\\n', encoding='utf-8')\n        environment = os.environ.copy()\n        environment['USERPROFILE'] = str(home)\n        environment['PATH'] = str(binary.parent) + os.pathsep + environment.get('PATH', '')\n        for key, suffix in [('APPDATA', 'AppData/Roaming'), ('LOCALAPPDATA', 'AppData/Local')]:\n            (home / suffix).mkdir(parents=True)\n            environment[key] = str(home / suffix)\n        version = subprocess.run([str(binary), '--version'], env=environment, capture_output=True, timeout=15)\n        (root / 'private-version.log').write_bytes(version.stdout + version.stderr)\n        found = re.search(r'(?m)^v(\\d+\\.\\d+\\.\\d+)\\s*$', (version.stdout + version.stderr).decode('utf-8', errors='replace'))\n        if version.returncode or not found or found[1] != args.expected_version:\n            raise ValueError('The resolved executable does not report the requested version')\n        receipt['runtime'] = {'version': found[1], 'binary_sha256': sha(binary)}\n        results = {}\n        for mode in ('op', 'dc', 'ac', 'tran', 'coarse', 'refined'):\n            directory = root / mode\n            directory.mkdir()\n            main_name = args.device + '-' + ('tran' if mode in {'coarse', 'refined'} else mode) + '.cir'\n            text = (source / main_name).read_text(encoding='utf-8')\n            if mode in {'coarse', 'refined'}:\n                replacement = '.TRAN 20p 2n 0 20p' if mode == 'coarse' else '.TRAN 2.5p 2n 0 2.5p'\n                if text.count('.TRAN 5p 2n 0 5p') != 1:\n                    raise ValueError('The supplied teaching transient was changed')\n                text = text.replace('.TRAN 5p 2n 0 5p', replacement)\n            deck = directory / main_name\n            deck.write_text(text, encoding='utf-8', newline='\\n')\n            (directory / (args.device + '.inc')).write_bytes((source / (args.device + '.inc')).read_bytes())\n            output = directory / 'result.csv'\n            run = subprocess.run([str(binary), '-P', '17', '-o', str(output), str(deck)],\n                                 cwd=directory, env=environment, capture_output=True, timeout=60)\n            (directory / 'private-process.log').write_bytes(run.stdout + run.stderr)\n            if run.returncode != 0 or not output.is_file():\n                raise ValueError(mode + ' did not produce a current successful analysis file')\n            if mode in {'op', 'dc'}:\n                result = static_check(args.device, output, mode == 'dc')\n            elif mode == 'ac':\n                result = ac_check(args.device, output)\n            else:\n                step = {'tran': 5e-12, 'coarse': 20e-12, 'refined': 2.5e-12}[mode]\n                result = transient_check(args.device, output, step)\n            result['output_sha256'] = sha(output)\n            results[mode] = result\n        receipt['results'] = results\n        if not all(results[mode]['strict_current_reference_passed'] for mode in ('op', 'dc')):\n            raise ValueError('Strict static current reference failed; inspect per-row deltas. Solver acceptance is separate from numerical accuracy')\n        if (results['coarse']['reference_bound_passed'] or not results['tran']['reference_bound_passed']\n                or not results['refined']['reference_bound_passed']\n                or results['refined']['max_current_error_A'] >= .5 * results['tran']['max_current_error_A']):\n            raise ValueError('The declared teaching time-refinement checks failed')\n        if any(sha(source / name) != value for name, value in inputs.items()) or sha(licence) != licence_hash:\n            raise ValueError('A source or issued licence changed during execution')\n        receipt['status'] = 'passed'\n        print(json.dumps({'status': 'passed', 'device': args.device,\n                          'transient_current_error_A': results['tran']['max_current_error_A']}))\n    except (OSError, ValueError, KeyError, subprocess.SubprocessError) as error:\n        receipt['reason'] = str(error)\n        print('Check failed: ' + str(error), file=sys.stderr)\n    finally:\n        (root / 'run.json').write_text(json.dumps(receipt, indent=2) + '\\n', encoding='utf-8')\n    return 0 if receipt['status'] == 'passed' else 1\n\n\nif __name__ == '__main__':\n    raise SystemExit(main())","heading":"Save run_models.py"},{"heading":"Check the result","paragraphs":["Require the intended saved inputs, actual compatible runtime, new artifacts, correct axes/units and the independent per-analysis verdict. Solver success, GUI freshness and numerical/physical acceptance remain separate. Retain both diode limitations as failed or qualified references."]},{"heading":"If the problem remains","paragraphs":["Preserve the complete synthetic inputs, exact runtime and first diagnostic privately. Check units, temperature, supported mode and saved source before changing the model. Do not infer measured-device accuracy or a supported model feature from a finite plot alone."]}],"canonical_url":"https://www.sun-magnetics.com/knowledge-base/josim-polynomial-current-charge","url":"/knowledge-base/josim-polynomial-current-charge","known_issues":[{"disposition":"verified_workaround","id":"KB-RESULT-001","title":"Running the last saved file can label an edited tab current","public_notice":"Save the intended edited source before Run and verify current arrays. Choosing No runs the saved source; the document current label may then disagree with the still-edited buffer.","claim_scope":"Only the affected claim and recorded build/input; not whole-guide or final-release acceptance"}],"search_record":{"execution":true,"relatedProducts":[],"version_tags":["JoSIM-Pro 2.9 target"],"text":"Define and validate polynomial current and charge Use the Y designator and a POLY model, keep current and charge coefficient units explicit, and compare static, complex and transient outputs with independent equations. JoSIM-Pro Fresh current-source Windows 2.9.0 review candidate; final-package/platform checks pending How to poly nonlinear current charge VOLTAGE BDF fixed step OP DC AC Y POLY I0 I1 I2 I3 Q0 Q1 Q2 Q3 coefficient units What this model represents For positive voltage V(p)-V(n), positive device current flows from p to n. The terminal current is I(v) + dQ(v)/dt; its small-signal admittance about a selected bias is dI/dv + j*omega*dQ/dv. Keep static current, total transient current and an AC phasor distinct. Use Yname p n model with .MODEL name POLY(...). B remains the Josephson-junction designator. I(v)=I0+I1*v+I2*v^2+I3*v^3 and Q(v)=Q0+Q1*v+Q2*v^2+Q3*v^3; coefficient units are A/V^r and C/V^r respectively. A constant Q0 has zero derivative and is not a capacitance.  Prepare the complete teaching inputs Use a compatible licensed JoSIM-Pro 2.9.0 Windows runtime and a writable copy of the complete download. Keep the chosen model include with all four matching .cir inputs. The standalone Python 3 checker needs no third-party packages; set $Python, $JoSIM and $Licence to full paths. $Licence must be the issued JoSIM-Pro file, distinct from an InductEx licence. These are synthetic model checks. Agreement does not calibrate a measured semiconductor, establish cryogenic validity or prove stability or uniqueness for another topology.  Run and inspect the model in the GUI Open poly-op.cir from the writable copy, confirm its saved source and include, then use Run simulation. Read the scalar values and units; an operating point is not a waveform. Open and run poly-dc.cir. Its seven independently solved points sweep V1 from -0.1 V to 0.5 V in 0.1 V steps. The horizontal coordinate is source voltage, not elapsed time. Open and run poly-ac.cir. The selected bias is 0.2 V; frequencies are 1, 2 and 3 GHz. The one-volt, 30-degree peak reference phasor multiplies the local admittance; it does not simulate a physically qualified one-volt nonlinear excursion. Open and run poly-tran.cir with the explicit fixed-step VOLTAGE/BDF options. The voltage ramps from -0.1 V to 0.5 V over 2 ns, using 5 ps steps and output cadence. Read voltage and total current with their separate display units. Before rerunning an edit, choose Yes to save and run the intended source. Cancel creates no new task. No uses the saved file; it does not simulate the unsaved text. The checked path can nevertheless label that document Results current, so verify saved input and current output identity.  The DC horizontal coordinate is swept source voltage, not time. OP.iterations and OP.normalized_residual are dimensionless diagnostics, not device signals. Actual seven-point polynomial DC plots include voltage, device/source currents and dimensionless operating-point diagnostics against the swept source voltage. Interpret current and charge separately At 0.2 V this polynomial gives 300 microamps, differential conductance 1.08 mS and differential capacitance 2.52 pF. At DC, dQ/dt is zero. During the ramp, add (Q1+2*Q2*v+3*Q3*v^2) times 3e8 V/s. The Q0=7p constant does not change transient current; changing it to zero reproduced the same arrays. The initial sample contains the static initial current. Startup charge history and the final ramp corner are excluded from the differentiable-interior reference check; a plotted initial current jump is not itself proof of an error.  The first sample is the initial static current. The later current includes charge response to the ramp; the independently checked interior excludes startup and the final ramp corner. Actual polynomial transient plots show a voltage ramp and total current including the derivative of charge; time is in nanoseconds and current in milliamperes. Compare time refinement with the independent reference The checker also runs 20 ps and 2.5 ps copies without changing the canonical inputs. Coarse solver completion is distinct from the current-error criterion. For this fixture, 20 ps misses the criterion, while 5 ps and 2.5 ps meet it and the latter reduces the maximum interior error. The polynomial interior bound is 10 nA. Maximum errors are approximately 64.8, 4.05 and 1.0125 nA at 20, 5 and 2.5 ps. The cubic-charge BDF2 truncation predicts 2*Q3*(3e8)^3*h^2, independently explaining this refinement pattern. The bound belongs to this supplied fixture, not arbitrary POLY models.  Recognise limits and recover a rejected run D/Y transients require fixed-step VOLTAGE/BDF in the checked runtime. PHASE and TRAP reject these transients; adaptive stepping also fails the shared runtime contract. Mixed Josephson transients and checkpoint pause/resume remain outside the documented model support. Unknown model fields and unsupported instance attributes are errors. The checked controls reject AREA=0, FC=1 and a mismatched diode .TEMP; Y accepts the model name, not a diode AREA attribute. POLY negative finite coefficients are permitted, without a passivity guarantee. A deliberately insufficient Newton iteration limit fails without a new static report and preserves a pre-existing authoritative report. Restoring the ordinary limit and rerunning at the same bias gives a fresh checked result. Correct the first diagnostic and use a new output generation; an iteration limit alone does not tighten an already accepted residual gate.  Save the refinement edit deliberately The native scenario checked Cancel, No and both explicit Yes/save choices. No retained the original 401-sample saved run while preserving the edited 20 ps buffer. Yes saved and ran that buffer, producing 101 samples. Normal Undo followed by another Yes/save and Run restored the original source and 401-sample arrays. A separately launched app explicitly reopening the saved input reproduced them. KB-RESULT-001 retains the No-path document-label contradiction. Compare saved source, task receipt and output data; do not use Results current alone as proof that the visible unsaved text was executed.  Choose Yes to run the visible edit. No can retain a stale task while the document incorrectly says Results current; verify source identity and the new numerical data. The actual unsaved-source dialog offers Yes to save and run, No to run the saved file, and Cancel to stop. Check the polynomial teaching model Run in the extracted input directory. The output root must be new. The helper records the actual version, source and output hashes, isolates its own configuration and leaves the issued licence unchanged. Raw logs and receipts can contain local paths and licence-holder details; keep them private. A zero polynomial-client exit and passed receipt require all stated checks. The diode command instead checks the exact retained failure and its separate transient criteria; it is not a successful reverse-current validation. & $Python -B .\\run_models.py --device poly --josim $JoSIM --licence $Licence --expected-version 2.9.0 --output-root .\\poly-review\nif ($LASTEXITCODE -ne 0) { throw 'The polynomial teaching reference did not pass; inspect the new receipt and first diagnostic.' } Save poly.inc .MODEL PM POLY(I0=.1m I1=1m I2=-.4m I3=2m Q0=7p Q1=2p Q2=.4p Q3=3p) Save poly-op.cir * Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 DC .2\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.OP\n.END Save poly-dc.cir * Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 DC .1\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.DC V1 -.1 .5 .1\n.END Save poly-ac.cir * Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 DC .2 AC 1 30\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.AC LIN 3 1G 3G\n.PRINT AC V(N) I(Y1)\n.END Save poly-tran.cir * Synthetic poly current and charge teaching model\n.include \"poly.inc\"\nY1 N 0 PM\nV1 N 0 PWL(0 -.1 2n .5)\n.OPTION SEED=321 ANALYSIS=VOLTAGE INTEGRATION=BDF\n.TRAN 5p 2n 0 5p\n.PRINT V(N) I(Y1)\n.END Save run_models.py \"\"\"Check the supplied Windows diode or POLY teaching inputs with JoSIM-Pro.\"\"\"\nimport argparse\nimport cmath\nimport csv\nimport hashlib\nimport io\nimport json\nimport math\nimport os\nfrom pathlib import Path\nimport re\nimport subprocess\nimport sys\n\nSTOP = 2e-9\nSLOPE = .6 / STOP\nRUNTIME_BOLTZMANN = 1.38064852e-23\nSI_BOLTZMANN = 1.380649e-23\n\n\ndef sha(path):\n    return hashlib.sha256(path.read_bytes()).hexdigest()\n\n\ndef equation(kind, voltage, boltzmann=RUNTIME_BOLTZMANN):\n    \"\"\"Independent conduction current and differential charge for these inputs.\"\"\"\n    v = voltage\n    if kind == 'poly':\n        current = .0001 + .001 * v - .0004 * v**2 + .002 * v**3\n        capacitance = 2e-12 + .8e-12 * v + 9e-12 * v**2\n        conductance = .001 - .0008 * v + .006 * v**2\n    else:\n        # The checked runtime retains an older k_B. Report the exact-SI\n        # comparison separately; this is not an accuracy or calibration waiver.\n        vt = boltzmann * 300.15 / 1.602176634e-19\n        current = 2e-12 * math.expm1(v / vt)\n        conductance = 2e-12 * math.exp(v / vt) / vt\n        # AREA=2 scales both conduction and charge. At FC*VJ, continue\n        # depletion capacitance linearly with its boundary slope.\n        if v < .35:\n            depletion = 4e-12 / math.sqrt(1 - v / .7)\n        else:\n            at_boundary = 4e-12 / math.sqrt(.5)\n            depletion = at_boundary * (1 + .5 * (v - .35) / (.7 * .5))\n        capacitance = depletion + 1e-9 * conductance\n    return current, conductance, capacitance\n\n\ndef table(path):\n    text = path.read_text(encoding='utf-8-sig')\n    metadata = None\n    if text.startswith('# josim-ac-csv/1 '):\n        first, text = text.split('\\n', 1)\n        metadata = json.loads(first[len('# josim-ac-csv/1 '):])\n    rows = list(csv.reader(io.StringIO(text)))\n    names = rows[0]\n    data = [[float(value) for value in row] for row in rows[1:] if row]\n    if not data or len(names) != len(set(names)) or any(\n            len(row) != len(names) or not all(math.isfinite(x) for x in row) for row in data):\n        raise ValueError('Missing, duplicate, ragged or nonfinite numerical data')\n    return metadata, names, data\n\n\ndef close(actual, expected):\n    return math.isclose(actual, expected, rel_tol=1e-9, abs_tol=1e-15)\n\n\ndef static_check(kind, path, swept):\n    _, names, rows = table(path)\n    device = 'D1' if kind == 'diode' else 'Y1'\n    axes = [-.1 + .1 * i for i in range(7)] if swept else [.2]\n    if len(rows) != len(axes):\n        raise ValueError('Unexpected static sample count')\n    errors, si_differences, comparisons = [], [], []\n    for axis, row in zip(axes, rows):\n        values = dict(zip(names, row))\n        expected = equation(kind, axis)[0]\n        ok = (close(values['V(N) (V)'], axis)\n              and 0 <= values['OP.normalized_residual (1)'] <= 1)\n        if swept:\n            ok = ok and close(values['Sweep(V1) (V)'], axis)\n        if not ok:\n            raise ValueError('Static voltage, sweep coordinate or solver residual gate failed')\n        errors.append(abs(values['I(' + device + ') (A)'] - expected))\n        si_current = equation(kind, axis, SI_BOLTZMANN)[0]\n        si_differences.append(abs(values['I(' + device + ') (A)'] - si_current))\n        comparisons.append({'bias_V': axis, 'actual_current_A': values['I(' + device + ') (A)'],\n                            'runtime_equation_A': expected, 'exact_SI_equation_A': si_current,\n                            'normalized_residual': values['OP.normalized_residual (1)'],\n                            'current_match': close(values['I(' + device + ') (A)'], expected),\n                            'source_current_match': close(values['I(V1) (A)'], -expected)})\n    return {'samples': len(rows), 'max_current_error_A': max(errors),\n            'max_current_difference_from_exact_SI_A': max(si_differences),\n            'comparisons': comparisons,\n            'strict_current_reference_passed': all(row['current_match'] and row['source_current_match'] for row in comparisons),\n            'reference': 'Explicit runtime k_B; exact-SI difference is separate' if kind == 'diode' else 'Polynomial coefficients'}\n\n\ndef ac_check(kind, path):\n    metadata, names, rows = table(path)\n    device = 'D1' if kind == 'diode' else 'Y1'\n    expected_names = ['frequency (Hz)', 'Re(V(N)) (V)', 'Im(V(N)) (V)',\n                      'Re(I(' + device + ')) (A)', 'Im(I(' + device + ')) (A)']\n    if names != expected_names or len(rows) != 3 or metadata is None:\n        raise ValueError('Unexpected AC schema or sample count')\n    if (metadata.get('phasor_convention') != 'peak_exp_positive_j'\n            or str(metadata.get('effective_seed')) != '321'):\n        raise ValueError('Unexpected AC convention or seed')\n    _, conductance, capacitance = equation(kind, .2)\n    source = cmath.rect(1, math.pi / 6)\n    errors = []\n    for frequency, rv, iv, ri, ii in rows:\n        expected = source * complex(conductance, 2 * math.pi * frequency * capacitance)\n        errors.append(abs(complex(ri, ii) - expected))\n        if abs(complex(rv, iv) - source) > 1e-12 or errors[-1] > 1e-11:\n            raise ValueError('AC phasor differs from the bias derivative reference')\n    if [row[0] for row in rows] != [1e9, 2e9, 3e9]:\n        raise ValueError('AC frequency axis differs from the requested grid')\n    return {'samples': 3, 'conductance_S': conductance, 'capacitance_F': capacitance,\n            'max_current_phasor_error_A': max(errors)}\n\n\ndef transient_check(kind, path, step):\n    _, names, rows = table(path)\n    device = 'D1' if kind == 'diode' else 'Y1'\n    if names != ['time', 'V(N)', 'I(' + device + ')'] or len(rows) != round(STOP / step) + 1:\n        raise ValueError('Unexpected transient columns or sample count')\n    if not close(rows[0][2], equation(kind, -.1)[0]):\n        raise ValueError('The initial sample must contain the static initial current')\n    errors, ratios = [], []\n    for index, (time, voltage, current) in enumerate(rows):\n        if abs(time - index * step) > 1e-20 or abs(voltage - (-.1 + SLOPE * time)) > 1e-12:\n            raise ValueError('Unexpected transient time or imposed-voltage coordinate')\n        # Initial charge history and the final ramp corner are distinct from\n        # the differentiable interior used for the time-discretisation check.\n        if index < 3 or index == len(rows) - 1:\n            continue\n        conduction, _, capacitance = equation(kind, voltage)\n        expected = conduction + capacitance * SLOPE\n        error = abs(current - expected)\n        bound = 1e-8 if kind == 'poly' else 1e-8 + .001 * abs(expected)\n        errors.append(error)\n        ratios.append(error / bound)\n    return {'samples': len(rows), 'interior_samples': len(errors), 'step_s': step,\n            'max_current_error_A': max(errors), 'max_bound_ratio': max(ratios),\n            'reference_bound_passed': max(ratios) <= 1}\n\n\ndef main():\n    parser = argparse.ArgumentParser(description=__doc__)\n    parser.add_argument('--device', choices=['diode', 'poly'], required=True)\n    parser.add_argument('--josim', type=Path, required=True)\n    parser.add_argument('--licence', type=Path, required=True)\n    parser.add_argument('--expected-version', required=True)\n    parser.add_argument('--output-root', type=Path, required=True)\n    args = parser.parse_args()\n    source = Path(__file__).resolve().parent\n    names = [args.device + '.inc'] + [args.device + '-' + mode + '.cir' for mode in ('op', 'dc', 'ac', 'tran')]\n    try:\n        if os.name != 'nt':\n            raise ValueError('This checked launcher is Windows-specific')\n        binary, licence = args.josim.resolve(strict=True), args.licence.resolve(strict=True)\n        root = args.output_root.resolve()\n        if not binary.is_file() or not licence.is_file() or root.exists():\n            raise ValueError('Use existing executable/licence files and a new output root')\n        if any(c in str(licence) for c in '\\r\\n'):\n            raise ValueError('The licence path cannot contain a line break')\n        licence_hash = sha(licence)\n        inputs = {name: sha(source / name) for name in names}\n        root.mkdir(parents=True, exist_ok=False)\n    except (OSError, ValueError) as error:\n        print('Preflight refused: ' + str(error), file=sys.stderr)\n        return 2\n    receipt = {'status': 'failed', 'device': args.device, 'inputs': inputs,\n               'scope': 'Supplied synthetic Windows teaching inputs only; no measured-device calibration'}\n    try:\n        home = root / 'home'\n        (home / '.josimpro').mkdir(parents=True)\n        (home / '.josimpro/config.ini').write_text('[General]\\nLicenseLocation=' + str(licence) + '\\n', encoding='utf-8')\n        environment = os.environ.copy()\n        environment['USERPROFILE'] = str(home)\n        environment['PATH'] = str(binary.parent) + os.pathsep + environment.get('PATH', '')\n        for key, suffix in [('APPDATA', 'AppData/Roaming'), ('LOCALAPPDATA', 'AppData/Local')]:\n            (home / suffix).mkdir(parents=True)\n            environment[key] = str(home / suffix)\n        version = subprocess.run([str(binary), '--version'], env=environment, capture_output=True, timeout=15)\n        (root / 'private-version.log').write_bytes(version.stdout + version.stderr)\n        found = re.search(r'(?m)^v(\\d+\\.\\d+\\.\\d+)\\s*$', (version.stdout + version.stderr).decode('utf-8', errors='replace'))\n        if version.returncode or not found or found[1] != args.expected_version:\n            raise ValueError('The resolved executable does not report the requested version')\n        receipt['runtime'] = {'version': found[1], 'binary_sha256': sha(binary)}\n        results = {}\n        for mode in ('op', 'dc', 'ac', 'tran', 'coarse', 'refined'):\n            directory = root / mode\n            directory.mkdir()\n            main_name = args.device + '-' + ('tran' if mode in {'coarse', 'refined'} else mode) + '.cir'\n            text = (source / main_name).read_text(encoding='utf-8')\n            if mode in {'coarse', 'refined'}:\n                replacement = '.TRAN 20p 2n 0 20p' if mode == 'coarse' else '.TRAN 2.5p 2n 0 2.5p'\n                if text.count('.TRAN 5p 2n 0 5p') != 1:\n                    raise ValueError('The supplied teaching transient was changed')\n                text = text.replace('.TRAN 5p 2n 0 5p', replacement)\n            deck = directory / main_name\n            deck.write_text(text, encoding='utf-8', newline='\\n')\n            (directory / (args.device + '.inc')).write_bytes((source / (args.device + '.inc')).read_bytes())\n            output = directory / 'result.csv'\n            run = subprocess.run([str(binary), '-P', '17', '-o', str(output), str(deck)],\n                                 cwd=directory, env=environment, capture_output=True, timeout=60)\n            (directory / 'private-process.log').write_bytes(run.stdout + run.stderr)\n            if run.returncode != 0 or not output.is_file():\n                raise ValueError(mode + ' did not produce a current successful analysis file')\n            if mode in {'op', 'dc'}:\n                result = static_check(args.device, output, mode == 'dc')\n            elif mode == 'ac':\n                result = ac_check(args.device, output)\n            else:\n                step = {'tran': 5e-12, 'coarse': 20e-12, 'refined': 2.5e-12}[mode]\n                result = transient_check(args.device, output, step)\n            result['output_sha256'] = sha(output)\n            results[mode] = result\n        receipt['results'] = results\n        if not all(results[mode]['strict_current_reference_passed'] for mode in ('op', 'dc')):\n            raise ValueError('Strict static current reference failed; inspect per-row deltas. Solver acceptance is separate from numerical accuracy')\n        if (results['coarse']['reference_bound_passed'] or not results['tran']['reference_bound_passed']\n                or not results['refined']['reference_bound_passed']\n                or results['refined']['max_current_error_A'] >= .5 * results['tran']['max_current_error_A']):\n            raise ValueError('The declared teaching time-refinement checks failed')\n        if any(sha(source / name) != value for name, value in inputs.items()) or sha(licence) != licence_hash:\n            raise ValueError('A source or issued licence changed during execution')\n        receipt['status'] = 'passed'\n        print(json.dumps({'status': 'passed', 'device': args.device,\n                          'transient_current_error_A': results['tran']['max_current_error_A']}))\n    except (OSError, ValueError, KeyError, subprocess.SubprocessError) as error:\n        receipt['reason'] = str(error)\n        print('Check failed: ' + str(error), file=sys.stderr)\n    finally:\n        (root / 'run.json').write_text(json.dumps(receipt, indent=2) + '\\n', encoding='utf-8')\n    return 0 if receipt['status'] == 'passed' else 1\n\n\nif __name__ == '__main__':\n    raise SystemExit(main()) Check the result Require the intended saved inputs, actual compatible runtime, new artifacts, correct axes/units and the independent per-analysis verdict. Solver success, GUI freshness and numerical/physical acceptance remain separate. Retain both diode limitations as failed or qualified references.  If the problem remains Preserve the complete synthetic inputs, exact runtime and first diagnostic privately. Check units, temperature, supported mode and saved source before changing the model. Do not infer measured-device accuracy or a supported model feature from a finite plot alone. ","id":"josim-polynomial-current-charge","keywords":"poly nonlinear current charge VOLTAGE BDF fixed step OP DC AC Y POLY I0 I1 I2 I3 Q0 Q1 Q2 Q3 coefficient units","kind":"How to","title":"Define and validate polynomial current and charge","product":"JoSIM-Pro"},"version":"Fresh current-source Windows 2.9.0 review candidate; final-package/platform checks pending","id":"josim-polynomial-current-charge","related":["/knowledge-base/josim-run-current-source","/knowledge-base/josim-dc-op","/knowledge-base/josim-ac-analysis","/knowledge-base/josim-diode-current-charge"],"downloads":[{"url":"/_functions/kbExample?name=josim-nonlinear-models.zip","scope":"Exact checked input files plus instructions; final-release/platform applicability remains pending.","files":["diode-ac.cir","diode-dc.cir","diode-op.cir","diode-tran.cir","diode.inc","poly-ac.cir","poly-dc.cir","poly-op.cir","poly-tran.cir","poly.inc","run_models.py","README.txt"],"id":"josim-nonlinear-models","requires":["Compatible licensed Windows JoSIM-Pro 2.9.0 runtime and issued JoSIM-Pro licence","Python 3 standard library and new writable output roots"],"title":"Complete diode and polynomial current/charge teaching models"}],"publication_status":"published","numerical_output":null,"provenance":{"execution_checks":[{"routes":["cli","python"],"scope":"39 real CLI/client/reference checks, complete D/POLY inputs, OP/DC/complex AC, time refinement, unsupported-mode and model-domain rejection, actual nonlinear failure, protected prior files and new recovery. The diode strict reverse-current and exact-SI comparisons remain distinct failed/limited references. The actual browser-downloaded bytes repeat all 39 contract checks and pass ten exact-command/archive/verdict comparisons.","result":"passed","articles":["josim-diode-current-charge","josim-polynomial-current-charge"],"purpose":"nonlinear-model-reference-rejection-and-failure-recovery","version":"Fresh frozen Windows JoSIM-Pro 2.9.0 nonlinear review candidate","id":"VAL-068","records":["39 CLI/client/reference checks; exact PowerShell command replay"],"limit":"This passed review records bounded successes and expected failures; it does not accept the failed diode current reference, arbitrary-model physical accuracy, stability/uniqueness, GUI, other platforms or final packages.","observed":{"poly_dc_samples":7,"diode_reverse":{"actual_current_A":-2.0802895390318088e-12,"current_match":false,"bias_V":-0.1,"source_current_match":false,"runtime_equation_A":-1.9581261499613277e-12,"exact_SI_equation_A":-1.9581260936766667e-12,"normalized_residual":0.1221633885771345},"diode_op_exact_SI_difference_A":1.226536512697422e-14,"diode_strict_current_reference":"failed; retained in the complete sweep","poly_current_error_A":{"coarse":6.480000005635797e-8,"refined":1.012500543042666e-9,"tran":4.050000230581413e-9},"poly_ac_capacitance_F":2.52e-12,"poly_operating_current_A":0.0003,"issues":["KB-DIODE-001","KB-DIODE-002","KB-RESULT-001"],"poly_ac_conductance_S":0.00108,"ac_frequency_samples":3}},{"routes":["gui-native-scenario"],"scope":"25 independent native/source/artifact checks, two normal app processes, fourteen successful runs and one failed run. Actual editor key/text commit, Cancel/No/Yes, source/disk separation, coarser-step/Undo/save recovery, typed AC opening and explicit saved-source reruns. No can run the saved model while the document incorrectly says Results current.","result":"passed","articles":["josim-diode-current-charge","josim-polynomial-current-charge","josim-run-current-source"],"purpose":"native-nonlinear-save-choices-current-data-and-recovery","version":"Fresh frozen Windows JoSIM-Pro 2.9.0 nonlinear review candidate","id":"VAL-069","records":["25 native/source/artifact checks; five unedited native captures"],"limit":"No product repair, complete GUI article, physical OS picker/pointer, automatic session restoration, final package/platform or general measured-device accuracy acceptance. The task, document label and numerical reference retain separate scopes.","observed":{"failed_native_runs":1,"owned_processes":2,"diode_numerical_reference":"Strict reverse-current and exact-SI distinctions remain open","no_task_stale":true,"no_saved_samples":401,"restored_samples":401,"save_prompt_choices":["Cancel","No","Yes","Yes"],"successful_native_runs":14,"no_document_label":"Results current","yes_coarse_samples":101}}],"figure_evidence":[{"evidence_limit":"Bounded illustration with independent raw-data checks. Known reference/freshness limits, physical OS picker/pointer, arbitrary physical model and final-package/platform qualification remain separate.","id":"josim-poly-dc-response","reference_label":"Fresh frozen Windows JoSIM-Pro 2.9.0 nonlinear candidate, reviewed 4 November 2026"},{"evidence_limit":"Bounded illustration with independent raw-data checks. Known reference/freshness limits, physical OS picker/pointer, arbitrary physical model and final-package/platform qualification remain separate.","id":"josim-poly-transient-response","reference_label":"Fresh frozen Windows JoSIM-Pro 2.9.0 nonlinear candidate, reviewed 4 November 2026"},{"evidence_limit":"Bounded illustration with independent raw-data checks. Known reference/freshness limits, physical OS picker/pointer, arbitrary physical model and final-package/platform qualification remain separate.","id":"josim-nonlinear-save-before-run","reference_label":"Fresh frozen Windows JoSIM-Pro 2.9.0 nonlinear candidate, reviewed 4 November 2026"}],"review_notes":["39 CLI/client/reference and 25 native/source/artifact checks on a freshly frozen Windows 2.9.0 candidate; installed products, settings and issued licences are preserved.","The complete diode sweep retains its strict reverse-current failure; the exact-SI constant comparison is separate. Known issues are documented, not repaired.","Complete GUI article, physical operator input, all nonlinear topologies, other platforms, final packages and measured-device calibration remain unqualified."],"scope":"Recorded inputs/builds only. Complete walkthrough and final-package acceptance remain separate.","verification_requirements":{"gui_method":"product-native-scenario","status":"review-incomplete","illustrations":"required","required":["technical-review","release-applicability","execution","gui-workflow","recovery","illustrations"],"legacy_walkthrough_field":"pending retained; not full GUI/release acceptance"},"sources":[{"id":"josim-pro:docs/manual_source/sections/syntax.tex","section":"Diode and polynomial current/charge models"},{"id":"validation:nonlinear-models-20261104","section":"VAL-068/069 complete synthetic cases, strict failed references, actual save choices and current artifacts"}]},"title":"Define and validate polynomial current and charge","type":"How to","markdown_url":"/_functions/kbResource?path=markdown%2Fjosim-polynomial-current-charge.md","summary":"Use the Y designator and a POLY model, keep current and charge coefficient units explicit, and compare static, complex and transient outputs with independent equations.","product":"JoSIM-Pro"}