FEMM/ROADMAP.md

26 KiB

FEMM port roadmap

status snapshot

The four C++ solvers (fkn, belasolv, csolv, hsolv) are linked into Rust via per-engine static archives, wrapped behind C ABI under ffi/, surfaced through crates/femm-sys. Document model is mirrored in Rust across four discipline crates (femm-doc for magnetostatic, femm-doc-elec, femm-doc-curr, femm-doc-heat); parsers and writers round-trip the on-disk text formats. An iced 0.14 canvas in crates/femm-app opens .fem, pans, zooms, and supports Select / AddNode / AddBlockLabel as click-tools against femm-doc::edit. Mag editing primitives exist (add_node, add_segment, add_arc_segment, add_block_label, delete_selected_*, closest-entity queries) but PSLG enforcement (intersection splitting, duplicate collapse, on-line break) is not yet implemented. There is no preprocessor for the three non-mag disciplines wired into the GUI, no post-processor at all, no property editing, no problem-definition dialog, no mesh launch, and no .ans loader.

pre-processor

The original draws a planar straight-line graph (PSLG) of nodes, segments, arc segments, and block labels. Each discipline has its own doc class (CFemmeDoc, CbeladrawDoc, CcdrawDoc, ChdrawDoc) sharing identical geometry storage but differing in MaterialProp, BoundaryProp, PointProp, Circuit fields. The View class for each discipline (CFemmeView, CbeladrawView, CcdrawView, ChdrawView) is structurally identical — the discipline-specific behavior is confined to which property dialogs open from OnOpenSelected.

edit modes and mouse gestures

EditAction in the View is an int: 0=Node, 1=Segment, 2=BlockLabel, 3=ArcSegment, 4=Group. Each mode rebinds the meaning of left-click, right-click, right-double-click, and TAB. Source: FemmeView.cpp (mag), beladrawView.cpp (elec), cdrawView.cpp (current), hdrawView.cpp (heat).

  • node mode (EditAction==0) — left-click places a node at the snapped mouse position; right-click toggles selection of the closest node; right-double-click pops an info message-box for that node; TAB opens the CEnterPt dialog for typed coordinates. Tier S.
  • segment mode (EditAction==1) — left-click picks the closest node as first endpoint; a second left-click picks the second endpoint and emits an AddSegment; right-click toggles selection of the closest segment; right-double-click reports length, BC, mesh size; ESC clears the half-built segment. Tier S.
  • arc segment mode (EditAction==3) — same two-click flow as segment, but between the two clicks a CArcDlg opens for arc angle, max segment length, and boundary marker. Tier M.
  • block-label mode (EditAction==2) — left-click places a label; right-click toggles selection; right-double-click reports material, circuit, mesh size, group, magnetization direction. Tier S.
  • group mode (EditAction==4) — right-click toggles every entity sharing the closest entity's group number; TAB pops a CGroupNumber dialog to type a group number and toggle that whole group. Tier S.
  • box select (SelectWndFlag) — drag a rectangle; on release selects all entities of the current mode (or all four kinds when in group mode) wholly inside. XOR-pixel rubber-band drawn in OnMouseMove. Tier M.
  • circle select (SelectCircFlag, mag only via OnFDSelectCirc) — drag from center to edge; selects entities inside the resulting disc. Tier M.
  • zoom-window (ZoomWndFlag) — drag a rectangle that becomes the new view extents. Tier S.
  • pan via arrow keys; PgUp/PgDn zoom by step; Home resets zoom; Ctrl+Z undoes; DEL cuts selection; SPACE opens the property dialog for current selection; F3 halves mesh density on selected blocks; F4 doubles. Tier S.
  • create-radius (CreateRadiusFlag) — next click chooses a node; a prompt asks for radius; if CanCreateRadius succeeds the corner is filleted in. Tier M.

The XOR-pixel rubber-band approach in the original is a Win32 trick (read pixels, XOR-write, remember to restore). In iced this becomes a transient overlay shape on the canvas — simpler and tier-S to implement.

dialogs

Every dialog below corresponds to one Xxx.h/Xxx.cpp pair under femm/. Discipline-prefixed variants share a layout but differ in fields. The .rc resource definitions are gone, so layout is redesigned; field set, validation, and ok-button effect come from the .h and the OnInitDialog/OnOK in the .cpp.

operation dialogs opened by SPACE / Edit > Properties

  • COpNodeDlg / bd_OpNodeDlg / cd_OpNodeDlg / hd_OpNodeDlgOpNodeDlg.h and prefixed variants. Fields: nodal-property name (dropdown over nodeproplist), in-group. Tier S.
  • COpSegDlg / bd_OpSegDlg / cd_OpSegDlg / hd_OpSegDlgOpSegDlg.h. Fields: boundary-property name, line mesh size (with auto-mesh toggle), hide-in-postprocessor, in-group. Tier S.
  • COpArcSegDlg / bd_OpArcSegDlg / cd_OpArcSegDlg / hd_OpArcSegDlgOpArcSegDlg.h. Fields: boundary marker, max segment length (degrees), hide, in-group. Tier S.
  • COpBlkDlg / bd_OpBlkDlg / cd_OpBlkDlg / hd_OpBlkDlgOpBlkDlg.h. Fields: block material, circuit (mag only), is-external (axisymmetric only), is-default, side length / area limit with auto-mesh toggle, mag direction (and a Lua "magdirfctn" textbox for functional MagDir), turns, in-group. Tier M.
  • COpGrpOpGrp.h. Bulk-edit the group number across a heterogeneous selection. Tier S.

property-list dialogs opened from menu Properties > Materials / Boundaries / Points / Circuits

  • CPtPropPtProp.h. List with Add / Modify / Delete. Generic shell parameterized by which underlying property list it is editing. Tier S.

property-editor dialogs reached from the Add/Modify buttons of CPtProp (one per discipline per property kind)

  • CMatDlgMatDlg.h. Magnetostatic material: name, mu_x, mu_y, H_c, J_re+J_im, conductivity, lam direction, lam thickness, lam fill, hysteresis lag angles Theta_h*, BH-curve edit button (opens CBHData), wire diameter, num strands, and a nonlinearity-mode combo. Tier L.
  • bdCMatDlgbd_MatDlg.h. Electrostatic material: name, eps_x, eps_y, volume charge density qv. Tier S.
  • cdCMatDlgcd_MatDlg.h. Current-flow material: name, conductivity ox/oy (real+imag), and three-curve nonlinearity arrays. Tier M.
  • hdCMatDlghd_MatDlg.h. Heat material: name, Kx, Ky, Kt (volumetric heat capacity), qv, and a nonlinear KH-curve combo with edit button. Tier M.
  • CBdryDlgBdryDlg.h. Magnetostatic boundary: BdryFormat combo (Prescribed-A, small-skin-depth, mixed, strategic dual, periodic, antiperiodic, periodic-air-gap, antiperiodic-air-gap), A0/A1/A2 + phi, c0/c1, mu, sigma, inner/outer angle. Tier M.
  • bdCBdryDlgbd_BdryDlg.h. Electrostatic boundary: format combo, v (potential), qs (surface charge), c0/c1. Tier S.
  • cdCBdryDlgcd_BdryDlg.h. Current-flow boundary: format combo, vs (complex voltage), qs (complex surface current), c0/c1. Tier S.
  • hdCBdryDlghd_BdryDlg.h. Heat boundary: format combo, Tset (fixed T), q (heat flux), beta (radiation), htc (convection), To1/To2 (ambient temps). Tier S.
  • CNodePropNodeProp.h. Mag point property: A (potential, complex), J (point current, complex). Tier S.
  • equivalent for elec/curr/heat (bd_NodeProp.h, cd_NodeProp.h, hd_NodeProp.h) — small variants. Tier S.
  • CCircPropCircProp.h. Mag circuit: name, total current (complex), series/parallel radio. Tier S.
  • bdCCircProp, cdCCircProp, hdCCircPropbd_CircProp.h, cd_CircProp.h, hd_CircProp.h. V/Q name plus voltage/charge or voltage/heat-source radio. Tier S.

geometry-input and modal helpers (shared)

  • CEnterPtEnterPt.h. TAB-coordinate entry (rectangular or polar). Tier S.
  • CArcDlgArcDlg.h. Arc creation: angle, max-side-length, boundary. Tier S.
  • CGroupNumberGroupNumber.h. Single int. Tier S.
  • CCopyDlgCopyDlg.h. Rotate or translate, with about-point or delta, n-copies, IsMove flag. Tier S.
  • CMirrorDlgMirrorDlg.h. Two-point axis pa/pb. Tier S.
  • CScaleDlgScaleDlg.h. Base point, scale factor. Tier S.
  • CGridMod / GRIDDLGGridMod.h, GRIDDLG.H. Grid size and coords (cartesian/polar). Tier S.
  • CPromptBox — typed-radius prompt used by OnCreateRadius. Tier S.
  • CMakeABCDlgMakeABCDlg.h. Open-boundary construction: number of layers, radius, center x/y, edge-type combo. Tier M.
  • CExteriorPropsExteriorProps.h. Axisymmetric exterior region: Ri, Ro, Zo. Tier S.
  • CDXFImportDXFImport.h. DXF import tolerance. Tier S.

problem-definition dialog (one per discipline)

  • probdlgprobdlg.h. Magnetostatic: problem type (planar / axisymmetric), length units, smart-mesh, frequency, precision, min-angle, depth, problem note, solver type (succ/newton), previous-solution path and prev-type. Tier M.
  • bdCProbDlgbd_probdlg.h. Electrostatic. Same shape minus frequency/solver/prev. Tier S.
  • cdCProbDlgcd_probdlg.h. Current flow: adds frequency. Tier S.
  • hdCProbDlghd_probdlg.h. Heat: adds dt (time step) and previous-solution path. Tier S.

material-library editor

  • fe_CLibDlgfe_libdlg.h and bd_libdlg.h / cd_libdlg.h / hd_libdlg.h. Drag-and-drop tree (library on left, model on right). Backed by LibFolderInfo. Tier L. The .lib file format is read-line-by-line in fe_libdlg.cpp::ParseLine. The drag/drop behavior depends on Win32 CTreeCtrl, so the iced version becomes two side-by-side scrollable lists with arrow buttons or drag handles.

preferences

  • CPref / bdCPref / cdCPref / hdCPrefPref.h and prefixed variants. Per-discipline-preprocessor defaults: edit action, coords (cart/polar), problem type, length units, solver, default freq, default grid size, default pixels-per-unit, depth, precision, min-angle, show-grid, snap-grid, show-origin, show-names, and a per-color picker driven by a combo. Tier M.
  • CGeneralPrefsGeneralPrefs.h. App-wide: default-doc type, default-Lua-console (drop), default-XY-plot, default-output-window, default-smartmesh. Tier S.
  • the post-processor variant: CViewPref, bvCPref, etc. — see post-processor section.

BH curve editor (mag-only material substructure)

  • CBHDataBHData.h. Two text columns (B, H) plus name, with linear/log plot preview. Reads BH datafiles via BHDatafile.cpp. Tier M.

geometry processing

  • PSLG enforcement (MOVECOPY.CPP::EnforcePSLG, FancyEnforcePSLG, and per-discipline bd_movecopy.cpp / cd_movecopy.cpp / hd_movecopy.cpp) — the rebuild-list approach: empty the four lists, re-AddNode / AddSegment / AddArcSegment / AddBlockLabel everything, and the Add* functions check tolerance, split crossings, and reject overlaps. The fancy version takes an explicit tolerance for DXF import. Tier L.
  • intersection math — CFemmeDoc::GetIntersection (line-line), GetLineArcIntersection, GetArcArcIntersection, ShortestDistanceFromArc, GetCircle (recover center/radius from two endpoints + arc angle). Pure geometry; port directly. Tier M.
  • CanCreateRadius / CreateRadius — fillet two adjacent segments at a node with a given radius. Tier M.
  • mirror, rotate, translate, scale — RotateMove, TranslateMove, ScaleMove, MirrorSelected, RotateCopy, TranslateCopy. The move variants act on the selection; copy variants accept n-copies and emit fresh entities. Each ends with a call to EnforcePSLG. Tier M.
  • DXF import — DXFImport.cpp plus per-discipline overrides. Reads ASCII DXF r12: LINE, ARC, CIRCLE, LWPOLYLINE entities translate into segments and arcs, then FancyEnforcePSLG(tol) runs. Tier L.
  • DXF export — WriteDXF. Walks lists and writes LINE/ARC entities. Tier M.
  • mesh launch — OnWritePoly in writepoly.cpp (mag) + discipline variants. Writes a .poly file: nodes (with index, x, y, marker), segments (with marker referencing boundary id), holes (block labels marked <No Mesh>), region attributes (each non-hole block label gets a region id and area target). Then CreateProcess invokes triangle.exe -p -P -q<minangle> -e -A -a -z -Q -I <root>. FunnyOnWritePoly handles periodic-BC enforcement (nodes on the periodic boundary must come in matched pairs). After Triangle returns, LoadMesh reads back .node / .ele / .edge to populate meshnode / meshline / greymeshline. Tier L. We exec the Triangle binary the same way the original does — only difference is posix_spawn instead of CreateProcess.

post-processor

The post-processor opens an .ans file (for elec .res, current .res, heat .anh) produced by the solver. Each discipline has its own pair of files. The view classes are again structurally identical; the differences are in plot quantities and integral kinds.

loading

  • CFemmviewDoc::OnOpenDocumentFemmviewDoc.cpp:226. Reopens the matching .fem (to get nodes/lines/labels/properties), then reads the .ans body: solver settings header, mesh nodes (each with A, NumList), mesh elements (each with 3 node indices, lab, b1, b2, mu1, mu2), point/segment/block/arc property arrays, optional air-gap-element block. Allocates the NumList/ConList neighbor-list adjacency. Tier L.
  • belaviewDoc.cpp, cviewDoc.cpp/CVIEWDOC.CPP, hviewDoc.cpp — same shape, different per-element quantities (V/D, V/J, T/F respectively). Tier M each once mag is done.

plot modes

The view stores DensityPlot (an int code), NumContours, ShowAr, ShowAi, ShowMask, plus LegendFlag, GreyContours, Smooth, PtsFlag, MeshFlag, VectorPlot, VectorScaleFactor, PlotBounds[9][2]. OnDraw (FemmviewView.cpp:777) renders, in order: density fill, mesh wireframe (if MeshFlag), contour lines (if ShowAr/ShowAi), the PSLG geometry, vectors (if VectorPlot), the user-defined contour, the mask, names, mesh points, and the legend.

mag density-plot options (cvCDPlotDlg2 — yes, the mag view borrows the current-flow dialog class; see "notes and surprises") cover, depending on DC vs AC, the quantities |B|, Bx/Br, By/Bz, |H|, Hx/Hr, Hy/Hz, |J|, J_re, J_im. Sources: FemmviewView.cpp::OnDplot, cv_DPlotDlg2.h.

  • mesh wireframe — OnShowMesh. Tier S.
  • input geometry overlay (always on). Tier S.
  • equipotential / flux-line contours (mag) — uses real-A and optionally imag-A; banded by NumContours; DoContours is the line walker in elements. Tier M.
  • density plot (mag) — fills each element with a color-mapped shade of B/H/J magnitude or component, optionally smoothed using nodal values. PlotFluxDensity per-element fill. Tier L.
  • vector plot (mag) — OnVplot -> CVPlotDlg. Choices: none, B, H (DC) or B_re, H_re, B_im, H_im, B_re&B_im, H_re&H_im (AC). Tier M.
  • point-info readout — OnRButtonDblClk in EditAction==0 mode shows mesh node (x,y,A,B,H,mu) at the click. DisplayPointProperties formats. Tier S.
  • mesh-point markers — PtsFlag. Tier S.
  • legend overlay — LegendFlag plus the 20-bin colormap (Color00..Color19, Grey00..Grey19). Tier S.
  • mask display — show the Henrotte weighting-function mask used by the "Henrotte" force/torque integrals. Built by MakeMask / bv_makemask.cpp / cv_makemask.cpp / hv_makemask.cpp. Tier M.

post-processor selection modes (EditAction again, but different meanings)

  • 0 Point — click reports values; right-double-click shows closest input node. Tier S.
  • 1 Contour — left-click extends a user-defined contour (pDoc->contour) by snapping to closest node or to the closest segment/arc; SHIFT pops CBendContourDlg to bend the last contour leg into an arc; DEL removes the last point; ESC clears. Tier M.
  • 2 Block — left-click toggles selection of the block under the cursor (uses InTriangle to find which mesh element, then floods to the connected region via ConList). Tier M.

integrations and contour ops

The line integral dialog CLIntDlg exposes (mag): normal flux (B.n), MMF along H.t, contour length / surface area, force-via-stress-tensor, torque-via-stress-tensor, and (B.n)^2. The block integral dialog CBlockInt exposes 17 entries enumerated in FemmviewView.cpp::OnMenuIntegrate cases 0..16: A.J (coil energy), integral of A, energy in B.H/2, hysteresis losses, total losses, area, ohmic losses, total current, integral of B, volume, Lorentz force (DC + 2X), Lorentz torque, energy density, Maxwell-stress (Henrotte) force, Maxwell-stress torque, integral of R^2, R/g (specific reluctance). Air-gap integrals (GapIntegral) compute force/torque/energy across an Air Gap Element boundary using harmonics. Sources: FemmviewView.cpp:2952-3515, FemmviewDoc.cpp::BlockIntegral, FemmviewDoc.cpp::LineIntegral, FemmviewDoc.cpp::lua_gapintegral. Tier XL — these are the algorithmically heaviest part of the post-processor.

elec / current / heat integrals are smaller subsets (force and torque only, for cv_BlockInt.cpp and cv_LIntDlg.cpp).

plot dialogs

  • CCPlotDlg / CCplotDlg2CPlotDlg.h, CplotDlg2.h. Mag contour-plot setup: num contours, A-bounds (lower/upper), show real, show imag, show mask. Two variants because AC has imag part. Tier S.
  • cvCDPlotDlg2cv_DPlotDlg2.h. Density-plot setup: which scalar to plot (combo), show-it toggle, show legend, grayscale toggle, lower/upper bound. Tier S.
  • CVPlotDlg / bv_VPlotDlg / cv_VPlotDlg / hv_VPlotDlg — vector-plot kind combo and scale factor. Tier S.
  • CXYPlotDlg / bv_XYPlotDlg / cv_XYPlotDlg / hv_XYPlotDlg — XY plot setup for the user-contour: quantity combo (potential, |B|, B.n, B.t, |H|, H.n, H.t, plus J_eddy, Js+J_eddy in AC; for materials also Mu_x/Mu_y per block), N points, to-file plus file-format combo (text / matlab / mathematica / gnuplot / csv). The plot itself renders to a metafile via Xyplot.cpp. Tier M.
  • CGapPlotDlgGapPlotDlg.h. Air-gap plot: pick AGE, quantity, N points, file. Tier S.
  • CLIntDlg, cv_LIntDlg, hv_LIntDlg — line integral type combo. Tier S.
  • CBlockInt, cv_BlockInt, hv_BlockInt — block integral type combo. Tier S.
  • bv_CircDlg, cv_CircDlg, hv_CircDlg — circuit-results readout. Tier S.

post-processor preferences

  • CViewPref / bvCPref / cvCPref / hvCPrefviewpref.h and prefixed variants. Edit-action default, default density-plot kind, default vector-plot kind, weighting scheme (Henrotte / uniform / extended), num contours default, grey-contours, legend, grid, show-Ar, show-Ai, show-mask, snap, smooth, shift-H, line-integral N points, plot N points, show-mesh, show-points, show-names, color overrides. Tier M.

shared infrastructure

  • grid (size, snap, show, polar vs cartesian) — same code path on the canvas in both pre and post. Tier S.
  • screen↔world transforms — ScreenToDwg / DwgToScreen, currently implemented in doc_canvas.rs. Tier already done.
  • zoom-to-fit (OnZoomNatural) — bounding-box over all nodes/labels/arcs with margin. Tier S.
  • keyboard zoom (CKbdZoom) — typed window extents. Tier S.
  • preferences file IO — femme.cfg, belasolv.cfg, csolv.cfg, hsolv.cfg are text key/value pairs (<SelColor>, <BkgndColor>, <EditAction>, ...). ScanPreferences / WritePreferences per view+doc pair. Tier S.
  • undo stack — UpdateUndo snapshots all four lists into undonodelist / undolinelist / undoarclist / undoblocklist before any mutation; Undo swaps. One level deep. Tier S.
  • group numbering — every entity carries an InGroup int; group-mode selection and modal group editing are the only consumers. Tier S.
  • material library on-disk — text in a custom block-keyed format; one library file per discipline, with vendor URL/name metadata. Tier M.
  • BH curve evaluation — BHData and BHDatafile.cpp implement cubic-spline interpolation for nonlinear materials; the result is consumed by the solver, not the GUI, so the GUI side is just edit + serialize. Tier M.

suggested order

each milestone names the smallest visible end-to-end result, not just an internal step.

  1. finish mag PSLG enforcement and segment / arc click-tools. Port EnforcePSLG, GetIntersection, GetLineArcIntersection, GetArcArcIntersection, CanCreateRadius/CreateRadius. Add AddSegment/AddArc canvas tools that pick the first node on click 1 and finalize on click 2. Demo: draw two crossing segments and watch them get split at the intersection.

  2. selection model + DEL/move/copy. Add per-entity selected flag, right-click toggle, box-select drag, group right-click, and the CCopyDlg/CMirrorDlg/CScaleDlg modals. Demo: build a quarter geometry, mirror-copy it to full.

  3. mag problem-definition dialog + property list dialogs. Implement probdlg and CPtProp (the four-discipline shell), plus CMatDlg, CBdryDlg, CNodeProp, CCircProp. Demo: open the bundled demo.fem, edit a material, save, reopen, see the change.

  4. per-selection property dialogs. COpNodeDlg, COpSegDlg, COpArcSegDlg, COpBlkDlg. Demo: click a label, hit space, change its block material from the dropdown, see the canvas redraw with the new label text.

  5. mesh launch end-to-end (mag). Port OnWritePoly (skip periodic for now), call out to the existing triangle binary, parse .node/.ele back into a mesh layer, draw it. Demo: hit F2 (or a "Mesh" button), see triangles overlay.

  6. mag solver launch. Wire the existing FFI to call fkn on the in-memory doc (or via the saved .fem/.poly path), then move on to step 7. Demo: hit "Analyze", solver runs, .ans appears on disk.

  7. mag post-processor loading + mesh display + density plot. Port CFemmviewDoc::OnOpenDocument, the neighbor-list builder, PlotFluxDensity for |B| only, plus the colormap. Demo: open a solved .ans, see a colored flux density plot.

  8. mag post-processor contour plot + point-info readout. DoContours for real-A, the equipotential drawing, plus mouse-click point query. Demo: click anywhere, get A/B/H/mu at that point.

  9. mag line integrals. Contour edit mode (EditAction=1 in the postprocessor), CLIntDlg, LineIntegral for cases 0 (flux), 1 (MMF), 2 (length/area). Demo: draw a contour across an airgap, read off normal flux.

  10. mag block integrals. Block selection mode, CBlockInt, all 17 BlockIntegral cases. Demo: select coil, read coil energy and current; select rotor, read Lorentz torque.

  11. port the other three disciplines. Reuse the now-proven shell. The doc parsers exist already; the work is dialog families and (smaller) integral sets per discipline.

  12. DXF, material library, BH editor, open-boundary builder. Power-user features. Defer until the four disciplines work end-to-end.

notes and surprises

  • mag's density-plot dialog class is named cvCDPlotDlg2 and lives in cv_DPlotDlg2.h (the current-flow viewer's file). The mag viewer doesn't have its own — FemmviewView.cpp::OnDplot instantiates the current-flow class directly. Not a bug, just an MFC class-rename that didn't get propagated. New iced port should have one DensityPlotDialog parameterized by an enum of plot kinds, not four near-copies.
  • EditAction has different meanings in pre and post processor. In pre: 0=node, 1=segment, 2=label, 3=arc, 4=group. In post: 0=point, 1=contour, 2=block. The two views share the field name but not the semantics.
  • the post-processor opens a separate document (CFemmviewDoc) rather than augmenting the pre-processor doc. The .ans loader rereads the .fem first to grab the original geometry and property lists, then reads the solved-element block on top. In the Rust port this should be the same: one PostDoc that holds a FemmDoc plus the solved mesh and per-element fields, not a giant union.
  • OnMenuAnalyze shells out to fkn.exe via CreateProcess with the document path. In the port, the same model is fine — we already build per-engine archives, and the analyze(path) Rust call replaces the process spawn. Air-gap-element support (the agelist array) is a recent addition driving the gap-integral and gap-plot dialogs; many demo .fem files won't have any AGEs, so the GUI must handle agelist.size==0 everywhere.
  • the BH-curve dialog stores B and H as multi-line text strings (CString m_Bdata; CString m_Hdata;) and parses them on OK via StripBHData. Idiomatic Rust replacement: two synchronized Vec.
  • bd_nosebl.cpp / cd_nosebl.cpp / hd_nosebl.cpp plus NOSEBL.CPP carry per-discipline copies of the geometry parser, even though the geometry sections are identical across disciplines. The Rust parser crates have already collapsed these into shared types where appropriate — keep doing that for any new shared code.
  • the original references a "Lua Console" prominently in menus and the lnu_* view functions, and many doc methods are split into a non-Lua and a Lua entry point (AddNode and lua_addnode). Per project rules, the Lua console is out of scope; the lua_* static methods can be ignored entirely. The Lua interpreter linked through the FFI is used by the solver for material formulas (functional MagDir, BH expressions) only.
  • the triangle/triangle.c mesher is left as a separate executable invocation. Don't try to inline it.
  • cFemmeView::OnMakeABC produces an open-boundary "asymptotic boundary condition" approximation by laying down N concentric circular shells, each with a calculated mu and sigma — it builds geometry and material/boundary properties together. The dialog has a combo for the edge type (Dirichlet / Neumann), defaults sourced from MakeABCDlg.cpp. Useful but not on the critical path.
  • two grid dialogs exist: CGridMod (GridMod.h) and GRIDDLG (GRIDDLG.H). They differ only in the coord-system combo wiring. Pick one for the port.
  • KbdZoom, MyMsgBox, PromptBox, OutBox, MaskProgress, LuaEdit, MyTabCtrl, MDITabs, MyRecentFileList, MyCommandLineInfo are MFC convenience widgets that have no analogue and no port. The native iced widgets cover their roles.
  • ActiveFEMM.cpp / mathlink.h are the ActiveX/Mathematica IPC shim — explicitly out of scope per the brief.
  • femmplotDoc.cpp + femmplotView.cpp are a tiny separate document type that pops up to display XY-plot metafiles from the post-processor. It is not a "post processor" itself, just a viewer. The Rust port can render the same plot inside the same iced window — no separate doc class needed.