8.0.1 Windows / current-source Studio review
Package applicability is under review; follow the stated version and platform limits.
Generate the mesh before importing it
Generate an ASCII, first-order MSH 2.2 volume mesh in Gmsh, give the conductor a named Physical Volume and each port end a named Physical Surface, then reference that MSH from the saved IXI. Use a nested $PHYSICAL assignment to connect the volume name to an explicit $MATERIAL. The checked Windows 8.0.1 route uses $IMPORTMESH; the manual’s shorter $IMPORT spelling currently fails in this runtime.
The complete download supplies bar.geo, bar.ixi, bar.cir, process.ldf and run_import.py. It describes a uniform 100 × 10 × 10 µm conductor with conductivity 5 × 10⁷ S/m, no London penetration depth and relative permeability one. It is a teaching model with a simple resistance reference, not calibrated package technology.
Use Gmsh separately to evaluate the supplied OpenCASCADE GEO and create bar.msh. This workflow imports that mesh into InductEx®; direct GEO parsing, arbitrary CAD healing and automatic material/terminal assignment are not established by these checks. A normal compatible issued InductEx® licence is required.
Generate and extract the complete bar from PowerShell
Extract all five inputs into a new writable folder. Select your actual Python, Gmsh and InductEx® executables and issued licence path in this complete PowerShell command, then run it from that folder. Both result names must be unused. The client references the existing licence through an isolated configuration; it never copies licence contents.
Each run copies the four model inputs, executes Gmsh with -3 -format msh2, checks the supplied physical/coordinate contract, runs InductEx® and compares the current positive R1 with the stated bar reference. Raw output and settings can contain local paths or licence metadata; keep them private until reviewed. The public client is specific to this supplied bar.
$ErrorActionPreference = 'Stop'
$python = 'python'
$gmsh = 'C:\InductEx\bin\gmsh.exe'
$inductex = 'C:\Program Files\SUN Magnetics\InductEx\bin\inductex.exe'
$licence = 'C:\Program Files\SUN Magnetics\Licenses\sm_license.txt'
& $python .\run_import.py --gmsh $gmsh --inductex $inductex --licence $licence --results .\bar-results-001
if ($LASTEXITCODE -ne 0) { throw 'The bar check failed. Review its current private log and receipt.' }
& $python .\run_import.py --gmsh $gmsh --inductex $inductex --licence $licence --results .\bar-results-002 --mesh-factor 0.5
if ($LASTEXITCODE -ne 0) { throw 'The refined bar check failed. Review its current private log and receipt.' }Inspect and run the project in Studio
The native scenario checks the production controls, default licensed Core runner, current results and correction. File selections enter at the production dialog boundary; physical picker operation, all editing branches, restart and final distributed-package qualification remain pending. The clipped settings image and earlier private-path provenance image are withheld.
- After successful mesh generation, open bar.ixi in the first result directory. Keep bar.msh, bar.cir and process.ldf beside it. The process file is still loaded by this import-only route; its layout layers are unused here, but its global settings remain relevant.
- On Basic > Review, expand Advanced setup and choose Layout/imports. Expand Imported geometry and physical assignments and select bar.msh. Review Name, Unit, Scale, Rotate and Translate. Terminal rows are read-only in Basic; edit those pairs deliberately in Raw IXI. Nested $PHYSICAL Name and Material must match the intended mesh volume and explicit material record.
- In Raw IXI, use the mesh-import banner’s Open preview action. On the mesh document’s Groups tab, check metal, left and right, including their dimensions and element counts. Preview applies numeric Unit/Scale/Rotate/Translate; it does not establish material validity, port connection or a completed solve.
- Return to the saved IXI, choose Check and run and Run extraction, then read current Results and Raw output. The checked baseline completes with R1 = 0.02 Ω. Changing Scale to 2 through its visible Apply control, saving and rerunning gives 0.01 Ω; restoring Scale 1 recovers 0.02 Ω.
- For the missing-input recovery exercise, change the import Name to absent.msh, save and run. The native task reports Failed with an external-mesh loading error. Restore bar.msh, save and run again; the checked current result returns to Completed and 0.02 Ω. Preserve any result generation you need before rerunning.

Keep units, transforms and physical assignments explicit
A checked 90° Z rotation followed by translation (0.001, 0.002, 0.003) places the bar at x = 0.00099–0.001 m, y = 0.002–0.0021 m, z = 0.003–0.00301 m and preserves its resistance. Scaling by two changes the physical model, while a rigid transform preserves this isolated uniform-bar reference.
Do not repair a unit mistake by changing only a plot label. The disposable Unit 1e-3 variant creates a bar a thousand times larger and produces a zero fitted resistance with about 99.7% fit error despite exit zero. That run is rejected. Changing dimensions at fixed frequency also changes the electromagnetic regime; inverse-size resistance is not a general AC scaling rule.
| Input | Meaning and checked value |
|---|---|
| Unit 1e-6 | Metres per mesh-coordinate unit. Raw bounds 0–100, 0–10, 0–10 become 100 × 10 × 10 µm. Exported combined-mesh coordinates in this run are metres. |
| Scale 1; Rotate; Translate | Coordinates are multiplied by Unit and Scale, rotated about the origin in XYZ degrees, then translated in metres. The triple follows Rotate or Translate on its next line. |
| Terminal "P1+" "left" / "P1-" "right" | The port name and polarity connect the netlist port to named physical surfaces. Both ends must exist; a visually plausible body alone does not establish a port. |
| $PHYSICAL Name "metal"; Material "metal_material" | Map the mesh volume name to the intended explicit $MATERIAL. Material names in the Basic controls are raw text and are not validated against the material records. |
| Sigma / Lambda / MuR | Conductivity is S/m, London penetration depth is metres and relative permeability is dimensionless. This normal-metal example uses 5e7, 0 and 1 respectively. |
Check the reference and the actual refinement
For a uniform low-frequency bar, R = length / (conductivity × cross-sectional area) = 0.02 Ω. The checked baseline has 190 nodes and 434 tetrahedra and gives 0.0200000 Ω. A separate mesh-factor 0.5 run has 1,073 nodes and 3,586 tetrahedra and gives 0.0200132 Ω, approximately 0.066% above that reference and above the baseline.
The client uses a declared 1% reference comparison for this simple teaching bar. These two meshes and their observed difference are a bounded refinement check; they do not establish a universal convergence tolerance or package accuracy. For a real structure, refine the relevant current-carrying geometry, inspect solver and model-fit errors, compare the quantities of interest and retain an appropriate independent reference.
The example uses 1 kHz. A preliminary zero-frequency attempt was rejected because this InductEx® route enabled AC analysis. The independent R formula supplies a low-frequency reference; the example does not claim to qualify a general DC import route. Its lack of an extracted inductance is intentional: bar.cir asks for R1.
Recognise the checked format and mapping limits
For this exercised legacy import path, retain ASCII MSH 2.2, first-order triangles and tetrahedra, globally distinct contiguous physical tags in declaration order, sequential node IDs in file order and the checked two-tag element layout. The supplied GEO generates those conditions. Do not assume that a mesh which opens in a viewer is accepted by Core.
Disposable MSH 4.1 and quadratic-tetrahedron files fail at the solver with Physical contains no elements. Valid meshes rewritten with sparse physical tags or nonsequential node IDs also fail in this runtime. Re-export a compatible mesh from the geometry source and inspect the actual header, groups and connectivity. Editing only the header or stripping element nodes is not a conversion.
| Observed failure | Recovery and unresolved finding |
|---|---|
| Record or command $import not recognised | KB-IMPORT-001: the manual/editor catalog and exercised Core reader disagree. The supplied checked 8.0.1 IXI uses $IMPORTMESH and preserves that spelling during native Scale Apply. Reconcile the supported contract before broader release claims. |
| External object metal has no material assigned. Default to first defined material. | KB-IMPORT-002: an unknown mapped material returns exit zero and R1 = 0 with 100% fit error in the disposable test. Reject that result, correct the exact material mapping and rerun. A warning or fallback is not an approved material choice. |
| No negative terminal found, or an unknown material from an unmatched volume | KB-IMPORT-003: missing terminal or volume-name mappings produce errors followed by an abnormal Windows process exit in the checked cases. Correct the exact mesh/port/volume names from the intact files; retain the actual diagnostic. Product crash handling remains open. |
| Error while loading external mesh | Check the exact saved Name, working copy and file existence. Restore the complete generated MSH beside this IXI and rerun; CLI and native correction recover the reference result. |
Save bar.geo
// Public teaching bar. Coordinate numbers represent micrometres.
SetFactory("OpenCASCADE");
Box(1) = {0, 0, 0, 100, 10, 10};
epsilon = 1e-6;
left() = Surface In BoundingBox {-epsilon, -epsilon, -epsilon,
epsilon, 10+epsilon, 10+epsilon};
right() = Surface In BoundingBox {100-epsilon, -epsilon, -epsilon,
100+epsilon, 10+epsilon, 10+epsilon};
// Distinct physical tags are intentional across both dimensions.
Physical Surface("left", 1) = {left()};
Physical Surface("right", 2) = {right()};
Physical Volume("metal", 3) = {1};
Mesh.MeshSizeMin = 4;
Mesh.MeshSizeMax = 5;
Mesh.ElementOrder = 1;
Mesh.MshFileVersion = 2.2;
Mesh.Binary = 0;
Mesh.SaveAll = 0;Save bar.ixi
* Public external tetrahedral mesh teaching example
$COMMAND
MeshFile "imported-bar.msh"
MeshType TETRA
Mode MQS
Frequency 1e3
Process "process.ldf"
Netlist "bar.cir"
$END
$MATERIAL
Name "metal_material"
Sigma 5e7
Lambda 0
MuR 1
$END
$IMPORTMESH
Name "bar.msh"
Unit 1e-6
Scale 1
Rotate
(0, 0, 0)
Translate
(0, 0, 0)
Terminal "P1+" "left"
Terminal "P1-" "right"
$PHYSICAL
Name "metal"
Material "metal_material"
$END
$ENDSave bar.cir
* One port across a uniform resistive bar; R = L/(sigma * area)
P1 1 0
R1 1 0 0.02Save process.ldf
* Public microstrip teaching stack; dimensions use Units below
$Parameters
Units = 1e-6
SegmentSize = 2.0
AbsMin = 0.025
GPOverhang = 5.0
ProcessHasGroundPlane = TRUE
GPLayer = 17
TermLayer = 19
TextLayer = 18
HFilaments = 1
TerminalInRange = 1.0
UnitL = 1
$End
$Layer
Number = 17
Name = M0
Thickness = 0.2
Lambda = 0.09
Order = 0
Mask = -1
Filmtype = S
HFilaments = 2
$End
$Layer
Number = 2
Name = I0
Thickness = 0.15
Order = 1
Mask = -1
Filmtype = I
$End
$Layer
Number = 5
Name = M1
Thickness = 0.25
Lambda = 0.09
Order = 2
Mask = 1
Filmtype = S
HFilaments = 3
$EndSave run_import.py
"""Run the complete public Gmsh bar teaching example in a new result directory.
This client is deliberately specific to the supplied bar. It is not a general
mesh validator or a way to assign unknown materials/terminals automatically.
Raw solver logs and settings may contain private local information.
"""
import argparse
import hashlib
import json
import math
import os
from pathlib import Path
import re
import shutil
import subprocess
import sys
INPUTS = ('bar.geo', 'bar.ixi', 'bar.cir', 'process.ldf')
def sha(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def read_msh2(path):
lines = path.read_text(encoding='ascii').splitlines()
def section(name):
start = lines.index('$' + name) + 1
end = lines.index('$End' + name, start)
return lines[start:end]
if section('MeshFormat') != ['2.2 0 8']:
raise ValueError('This checked reader requires ASCII MSH 2.2 (2.2 0 8).')
groups = section('PhysicalNames')
if int(groups[0]) != len(groups)-1:
raise ValueError('Physical-name count does not match the complete file.')
physicals = {}
for row in groups[1:]:
match = re.fullmatch(r'(\d+)\s+(\d+)\s+"([^"]+)"', row)
if not match:
raise ValueError('Unsupported physical-name record.')
dimension, tag = int(match[1]), int(match[2])
if tag in physicals:
raise ValueError('Use distinct physical tags across dimensions for this checked import path.')
physicals[tag] = {'dimension': dimension, 'name': match[3]}
rows = section('Nodes')
if int(rows[0]) != len(rows)-1:
raise ValueError('Node count does not match the complete file.')
nodes = []
for index, row in enumerate(rows[1:], 1):
values = row.split()
if len(values) != 4 or int(values[0]) != index:
raise ValueError('This import path requires sequential node IDs in physical row order.')
point = tuple(float(v) for v in values[1:])
if not all(math.isfinite(v) for v in point):
raise ValueError('Nonfinite mesh coordinate.')
nodes.append(point)
rows = section('Elements')
if int(rows[0]) != len(rows)-1:
raise ValueError('Element count does not match the complete file.')
elements = []
for row in rows[1:]:
values = [int(v) for v in row.split()]
kind, tags = values[1:3]
if kind not in (1, 2, 4) or tags != 2:
raise ValueError('Use first-order lines/triangles/tetrahedra and the checked two-tag MSH layout.')
node_ids = values[5:]
if len(node_ids) != {1:2, 2:3, 4:4}[kind] or not all(1 <= n <= len(nodes) for n in node_ids):
raise ValueError('Invalid element-node reference.')
if values[3] not in physicals:
raise ValueError('Element references an undeclared physical group.')
elements.append({'kind':kind,'physical':values[3],'nodes':node_ids})
return {'physicals':physicals,'nodes':nodes,'elements':elements}
def bounds(mesh):
return [[min(p[i] for p in mesh['nodes']), max(p[i] for p in mesh['nodes'])] for i in range(3)]
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--gmsh', type=Path, required=True)
parser.add_argument('--inductex', type=Path, required=True)
parser.add_argument('--licence', type=Path, required=True)
parser.add_argument('--results', type=Path, required=True)
parser.add_argument('--mesh-factor', type=float, default=1.0)
args = parser.parse_args()
source = Path(__file__).resolve().parent
work = args.results.absolute()
try:
gmsh, inductex, licence = [p.resolve(strict=True) for p in (args.gmsh, args.inductex, args.licence)]
if not all(p.is_file() for p in (gmsh, inductex, licence)):
raise ValueError('Select existing Gmsh, InductEx and issued-licence files.')
if work.exists() or not work.parent.is_dir():
raise ValueError('Select a new result directory under an existing writable parent.')
if not math.isfinite(args.mesh_factor) or not .25 <= args.mesh_factor <= 2:
raise ValueError('Use a mesh factor from 0.25 to 2 for this teaching study.')
originals = {n:sha(source/n) for n in INPUTS}
work.mkdir()
for n in INPUTS:
shutil.copyfile(source/n, work/n)
home = work/'private-home/.sunmagnetics'
home.mkdir(parents=True)
(home/'ixcfg.ini').write_text('[General]\nLicenseFileName='+licence.as_posix()+'\n',encoding='utf-8')
env = os.environ.copy()
env['USERPROFILE'] = str(home.parent)
env['PATH'] = str(inductex.parent)+';'+str(gmsh.parent)+';'+env.get('PATH','')
flags = {'creationflags':subprocess.CREATE_NO_WINDOW} if os.name=='nt' else {}
receipt = {'status':'running','inputs':originals,'mesh_factor':args.mesh_factor,
'scope':'Supplied uniform public bar at 1 kHz; independent low-frequency resistance reference, not general convergence or physical calibration.'}
def save():
(work/'receipt.json').write_text(json.dumps(receipt,indent=2)+'\n',encoding='utf-8')
save()
command = [str(gmsh),'bar.geo','-3','-format','msh2','-clscale',str(args.mesh_factor),'-o','bar.msh','-v','2']
generated = subprocess.run(command,cwd=work,env=env,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,timeout=90,**flags)
(work/'gmsh-private.log').write_bytes(generated.stdout)
receipt['gmsh_exit_code'] = generated.returncode
if generated.returncode != 0:
raise RuntimeError('Gmsh failed; retain its private log.')
mesh = read_msh2(work/'bar.msh')
expected = {1:{'dimension':2,'name':'left'},2:{'dimension':2,'name':'right'},3:{'dimension':3,'name':'metal'}}
if mesh['physicals'] != expected or bounds(mesh) != [[0,100],[0,10],[0,10]]:
raise ValueError('Generated mesh does not match the supplied bar/terminal physical contract.')
if not any(e['kind']==4 and e['physical']==3 for e in mesh['elements']):
raise ValueError('The imported body has no tetrahedral volume elements.')
receipt['raw_mesh'] = {'sha256':sha(work/'bar.msh'),'nodes':len(mesh['nodes']),
'triangles':sum(e['kind']==2 for e in mesh['elements']),
'tetrahedra':sum(e['kind']==4 for e in mesh['elements']),'bounds_in_mesh_units':bounds(mesh)}
run = subprocess.run([str(inductex),'bar.ixi'],cwd=work,env=env,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,timeout=150,**flags)
(work/'inductex-private.log').write_bytes(run.stdout)
receipt['inductex_exit_code'] = run.returncode
text = run.stdout.decode('utf-8',errors='replace')
if run.returncode != 0 or re.search(r'(?im)^\s*(ToolEngine error|Unexpected exception|Warnings?\b)|CONVERGENCE FAILED|Not successful',text):
raise RuntimeError('Extraction failed or requires warning review; retain the current private log.')
match = re.fullmatch(r'R1\s+([-+0-9.eE]+)\s*',(work/'output/elements.txt').read_text(encoding='ascii'))
if not match:
raise ValueError('No current single R1 result was found.')
resistance = float(match[1])
reference = 100e-6 / (5e7 * 10e-6 * 10e-6)
difference = abs(resistance/reference-1)
if not math.isfinite(resistance) or resistance <= 0 or difference > .01:
raise ValueError('The teaching bar failed its stated 1% low-frequency reference comparison.')
settings = json.loads((work/'output/settings_imported-bar.json').read_text(encoding='utf-8'))
if settings['MATERIALS']['metal_material']['SIGMA'] != 5e7:
raise ValueError('Current solver settings do not retain the requested conductivity.')
if not all(sha(source/n)==h==sha(work/n) for n,h in originals.items()):
raise ValueError('A source input changed during the run.')
receipt.update(status='passed',resistance_ohm=resistance,reference_ohm=reference,relative_reference_difference=difference,
gmsh_sha256=sha(gmsh),inductex_sha256=sha(inductex),inputs_preserved=True)
save()
print(json.dumps({'status':'passed','R1_ohm':resistance,'reference_ohm':reference,
'tetrahedra':receipt['raw_mesh']['tetrahedra']}))
return 0
except (OSError,ValueError,RuntimeError,subprocess.TimeoutExpired) as error:
if 'receipt' in locals():
receipt.update(status='failed',reason=str(error));save()
print(str(error),file=sys.stderr)
return 2
if __name__=='__main__':
raise SystemExit(main())Extend the model deliberately
For your structure, start from its complete geometry, intended materials, terminal surfaces, coordinate system and frequency regime. Record the Gmsh and InductEx®/TetraHenry® versions, mesh density, port mapping, raw numerical units and acceptance checks with each result. The supplied bar client should not be relabelled as a general validator for a different design.
Package dies, substrate-to-package connections, wedge or ball-and-stitch wires, bump bonds and coupled extraction need their own complete examples and continuity/refinement checks. This imported bar provides a checked foundation; those package workflows remain a separate coverage gap. Capacitance numerical acceptance remains held under the existing EQS finding.
Sources and verification details
Recorded inputs/builds only. Complete walkthrough and final-package acceptance remain separate.
VAL-045 · Windows InductEx® 8.0.1 / TTH 1.1.50; Gmsh 4.13.1 and frozen current-source Studio
Windows Gmsh 4.13.1 and catalog InductEx® 8.0.1/TTH 1.1.50; complete public first-order uniform bar at 1 kHz, two mesh densities, transforms, actual bad-input cases and recovery. One-percent resistance reference belongs only to this teaching bar; invalid zero/poor-fit runs are rejected. No arbitrary CAD import, bond geometry, capacitance, physical calibration or final-package qualification. Actual browser-downloaded five-input bar ZIP, complete PowerShell 7 article/README command with only Python and InductEx® executable selections changed, existing issued InductEx® licence and new results under a folder with spaces. Both generation/extraction/reference/refinement runs pass; no GUI, general CAD, material fallback or final-release acceptance.
Public first-order bar only; no arbitrary CAD/bond connection, full physical GUI route, product issue repair, device accuracy or final-package/platform qualification.
VAL-046 · Windows InductEx® 8.0.1 / TTH 1.1.50; Gmsh 4.13.1 and frozen current-source Studio
Frozen current-source licensed Windows Studio/Core 8.0.1. Actual baseline/Scale Apply/save/run/recovery, referenced-mesh preview and missing-mesh correction. Exact native Groups image only; path-bearing provenance and clipped settings captures withheld. No physical picker, crash repair, arbitrary material validation, other platform or final-package acceptance.
Public first-order bar only; no arbitrary CAD/bond connection, full physical GUI route, product issue repair, device accuracy or final-package/platform qualification.
studio-imported-bar-groups
Windows current-source Studio/Core 8.0.1 native scenario, reviewed 4 November 2026
Referenced numeric-transform mesh preview; material/terminal correctness and extraction are checked separately. No physical picker or final-package acceptance.
- inductex:docs/manual/ix_offchip.tex · Arbitrary structures from Gmsh; Physical structures
- inductex:docs/manual/ix_layoutinput.tex · IXI import and material records; explicit spelling discrepancy
- inductex:docs/manual/studio_projects.tex · Basic/Raw IXI, retained Advanced setup and current Results
- validation:gmsh-import-windows-20261104 · VAL-045 and VAL-046; complete bar, transforms, bad inputs and native recovery
- No arbitrary CAD, package/wirebond connection, product crash repair, complete physical GUI or final-release acceptance.
