yapcad.package.analysis package

Submodules

yapcad.package.analysis.base module

Shared data structures for analysis/validation plans.

class yapcad.package.analysis.base.AnalysisAdapter[source]

Bases: ABC

Base class for solver adapters.

name: str = 'analysis-adapter'
abstractmethod run(manifest, plan: AnalysisPlan, workspace: Path, **kwargs: Any) AnalysisResult[source]

Execute the plan and return an AnalysisResult.

class yapcad.package.analysis.base.AnalysisPlan(plan_id: str, kind: str, backend: str, name: str | None = None, description: str | None = None, geometry: Dict[str, ~typing.Any]=<factory>, materials: Dict[str, ~typing.Any]=<factory>, loads: Dict[str, ~typing.Any]]=<factory>, boundary_conditions: Dict[str, ~typing.Any]]=<factory>, acceptance: Dict[str, ~typing.Any]=<factory>, backend_options: Dict[str, ~typing.Any]=<factory>, execution: ExecutionConfig = <factory>, attachments: Dict[str, ~typing.Any]]=<factory>, metadata: Dict[str, ~typing.Any]=<factory>, raw: Dict[str, ~typing.Any]=<factory>)[source]

Bases: object

Representation of a validation/analysis plan loaded from YAML.

acceptance: Dict[str, Any]
attachments: List[Dict[str, Any]]
backend: str
backend_options: Dict[str, Any]
boundary_conditions: List[Dict[str, Any]]
description: str | None = None
execution: ExecutionConfig
geometry: Dict[str, Any]
kind: str
loads: List[Dict[str, Any]]
materials: Dict[str, Any]
metadata: Dict[str, Any]
name: str | None = None
property normalized_backend: str
plan_id: str
raw: Dict[str, Any]
class yapcad.package.analysis.base.AnalysisResult(plan_id: str, status: str, metrics: Dict[str, ~typing.Any]=<factory>, summary: Dict[str, ~typing.Any]=<factory>, artifacts: Dict[str, ~typing.Any]]=<factory>, summary_path: Path | None = None, backend: str | None = None, timestamp: str | None = None, notes: str | None = None)[source]

Bases: object

Container for results emitted by analysis adapters.

artifacts: List[Dict[str, Any]]
backend: str | None = None
metrics: Dict[str, Any]
notes: str | None = None
plan_id: str
status: str
summary: Dict[str, Any]
summary_path: Path | None = None
timestamp: str | None = None
to_manifest_entry(package_root: Path) Dict[str, Any][source]
class yapcad.package.analysis.base.ExecutionConfig(mode: str = 'local', command: str | None = None, transport: str | None = None, host: str | None = None, workdir: str | None = None, env: Dict[str, str]=<factory>, options: Dict[str, ~typing.Any]=<factory>, license: Dict[str, ~typing.Any]=<factory>)[source]

Bases: object

Execution context for an analysis plan.

command: str | None = None
env: Dict[str, str]
host: str | None = None
property is_remote: bool
license: Dict[str, Any]
mode: str = 'local'
options: Dict[str, Any]
transport: str | None = None
workdir: str | None = None
yapcad.package.analysis.base.available_backends() Sequence[str][source]
yapcad.package.analysis.base.get_backend(name: str) Type[AnalysisAdapter] | None[source]
yapcad.package.analysis.base.load_plan(path: Path | str) AnalysisPlan[source]

Load a YAML analysis plan and return the normalised AnalysisPlan.

yapcad.package.analysis.base.register_backend(name: str, adapter_cls: Type[AnalysisAdapter]) None[source]

yapcad.package.analysis.calculix module

CalculiX backend for yapCAD analysis plans.

class yapcad.package.analysis.calculix.CalculixAdapter[source]

Bases: AnalysisAdapter

Create a simplified axisymmetric disk model and execute CalculiX when available.

name: str = 'calculix'
run(manifest: PackageManifest, plan: AnalysisPlan, workspace: Path, **_: Any) AnalysisResult[source]

Execute the plan and return an AnalysisResult.

yapcad.package.analysis.cli module

Command-line helpers for running analysis plans.

yapcad.package.analysis.cli.analyze_package(package_path: Path | str, plan_path: Path | str, *, status: str = 'pending') Path[source]

Record analysis metadata for plan_path inside package_path.

This helper prepares the results directory, writes a summary.json placeholder, and updates the manifest validation.results block.

yapcad.package.analysis.cli.main(argv: Sequence[str] | None = None) int[source]

yapcad.package.analysis.face_naming module

Face naming system for boundary condition assignment.

This module provides utilities for naming faces of yapCAD solids, which can then be used to assign boundary conditions in analysis plans.

Face names can be assigned: 1. At creation time via DSL with { face_names: {…} } syntax 2. Post-hoc via selectors (by normal, by area, by position) 3. Interactively in the viewer (future)

The face names are stored in solid metadata and propagate through to Gmsh physical groups when meshing.

Copyright (c) 2025 yapCAD contributors MIT License

class yapcad.package.analysis.face_naming.ByAreaSelector(min_area: float | None = None, max_area: float | None = None, largest: bool = False, smallest: bool = False)[source]

Bases: FaceSelector

Select faces by area criteria.

matches(face: FaceInfo) bool[source]

Return True if face matches this selector.

set_context(faces: List[FaceInfo]) None[source]

Set all faces for largest/smallest comparison.

class yapcad.package.analysis.face_naming.ByNormalSelector(direction: Tuple[float, float, float], tolerance_deg: float = 5.0, allow_reversed: bool = False)[source]

Bases: FaceSelector

Select faces by normal direction.

matches(face: FaceInfo) bool[source]

Return True if face matches this selector.

class yapcad.package.analysis.face_naming.ByPositionSelector(axis: str = 'z', at_min: bool = False, at_max: bool = False, above: float | None = None, below: float | None = None, tolerance: float = 1e-06)[source]

Bases: FaceSelector

Select faces by centroid position.

matches(face: FaceInfo) bool[source]

Return True if face matches this selector.

set_context(faces: List[FaceInfo]) None[source]

Set all faces for min/max comparison.

class yapcad.package.analysis.face_naming.CombinedSelector(selectors: List[FaceSelector], mode: str = 'and')[source]

Bases: FaceSelector

Combine multiple selectors with AND/OR logic.

matches(face: FaceInfo) bool[source]

Return True if face matches this selector.

set_context(faces: List[FaceInfo]) None[source]

Propagate context to child selectors.

class yapcad.package.analysis.face_naming.FaceInfo(index: int, centroid: ~typing.Tuple[float, float, float], normal: ~typing.Tuple[float, float, float], area: float, name: str | None = None, tags: ~typing.List[str] = <factory>)[source]

Bases: object

Information about a face for selection/naming.

Variables:
  • index (int) – Face index in the solid

  • centroid (Tuple[float, float, float]) – Face centroid point

  • normal (Tuple[float, float, float]) – Face normal vector (average for curved faces)

  • area (float) – Face area

  • name (str | None) – Optional assigned name

  • tags (List[str]) – Optional list of tags

area: float
centroid: Tuple[float, float, float]
index: int
name: str | None = None
normal: Tuple[float, float, float]
tags: List[str]
class yapcad.package.analysis.face_naming.FaceNamer(solid: Any)[source]

Bases: object

Utility for naming faces of yapCAD solids.

This class extracts face information from solids and applies names based on selectors or explicit assignments.

property faces: List[FaceInfo]

Get list of face information.

get_named_faces() Dict[str, List[int]][source]

Get all named faces.

Returns:

Mapping of names to face indices

name_faces(assignments: Dict[str, FaceSelector | List[int]]) Dict[str, List[int]][source]

Apply face name assignments.

Parameters:

assignments – Mapping of names to selectors or explicit face indices

Returns:

Mapping of names to matched face indices

to_metadata() Dict[str, Any][source]

Convert face naming to metadata format.

Returns:

Dictionary suitable for solid metadata

class yapcad.package.analysis.face_naming.FaceSelector[source]

Bases: object

Base class for face selection predicates.

matches(face: FaceInfo) bool[source]

Return True if face matches this selector.

yapcad.package.analysis.face_naming.back_faces(tolerance_deg: float = 5.0) ByNormalSelector[source]

Select faces with -Y normal (back faces).

yapcad.package.analysis.face_naming.bottom_faces(tolerance_deg: float = 5.0) ByNormalSelector[source]

Select faces with -Z normal (bottom faces).

yapcad.package.analysis.face_naming.faces_at_z_max(tolerance: float = 1e-06) ByPositionSelector[source]

Select faces at maximum Z coordinate.

yapcad.package.analysis.face_naming.faces_at_z_min(tolerance: float = 1e-06) ByPositionSelector[source]

Select faces at minimum Z coordinate.

yapcad.package.analysis.face_naming.front_faces(tolerance_deg: float = 5.0) ByNormalSelector[source]

Select faces with +Y normal (front faces).

yapcad.package.analysis.face_naming.largest_face() ByAreaSelector[source]

Select the largest face by area.

yapcad.package.analysis.face_naming.left_faces(tolerance_deg: float = 5.0) ByNormalSelector[source]

Select faces with -X normal (left faces).

yapcad.package.analysis.face_naming.right_faces(tolerance_deg: float = 5.0) ByNormalSelector[source]

Select faces with +X normal (right faces).

yapcad.package.analysis.face_naming.smallest_face() ByAreaSelector[source]

Select the smallest face by area.

yapcad.package.analysis.face_naming.top_faces(tolerance_deg: float = 5.0) ByNormalSelector[source]

Select faces with +Z normal (top faces).

yapcad.package.analysis.fenics module

FEniCSx (DOLFINx) backend for yapCAD structural analysis.

This module provides FEA capabilities using FEniCSx/DOLFINx with Gmsh meshing. The key advantage is OCC kernel alignment: yapCAD, Gmsh, and FEniCSx all use OpenCASCADE, enabling direct geometry passing without lossy conversions.

Supported analysis types: - Linear elastic static analysis - Thermal analysis (future) - Modal analysis (future)

Usage:

from yapcad.package.analysis.fenics import FenicsxAdapter

adapter = FenicsxAdapter() result = adapter.run(manifest, plan, workspace)

Installation:

conda create -n yapcad-fenics -c conda-forge fenics-dolfinx gmsh pythonocc-core

Copyright (c) 2025 yapCAD contributors MIT License

class yapcad.package.analysis.fenics.FenicsxAdapter[source]

Bases: AnalysisAdapter

FEniCSx (DOLFINx) FEA backend for structural analysis.

This adapter performs linear elastic static analysis using FEniCSx with Gmsh for mesh generation. It supports:

  • Fixed boundary conditions (displacement = 0)

  • Pressure loads on faces

  • Point loads (concentrated forces)

  • Traction (distributed force) on faces

Results include: - Maximum displacement - Maximum von Mises stress - Displacement and stress fields (VTU export)

name: str = 'fenics'
run(manifest: Any, plan: AnalysisPlan, workspace: Path, **kwargs: Any) AnalysisResult[source]

Execute the FEA analysis.

Parameters:
  • manifest – Package manifest

  • plan – Analysis plan specification

  • workspace – Working directory for intermediate files

Returns:

AnalysisResult with metrics and artifacts

class yapcad.package.analysis.fenics.MaterialProperties(youngs_modulus: float, poisson_ratio: float, density: float = 0.0)[source]

Bases: object

Linear elastic material properties.

density: float = 0.0
property lame_lambda: float

First Lamé parameter.

property lame_mu: float

Second Lamé parameter (shear modulus).

poisson_ratio: float
youngs_modulus: float
yapcad.package.analysis.fenics.fenics_available() bool[source]

Return True if FEniCSx (DOLFINx) is available.

yapcad.package.analysis.fenics.require_fenics() None[source]

Raise error if FEniCSx is not available.

yapcad.package.analysis.gmsh_mesher module

Gmsh meshing integration for yapCAD analysis.

This module provides meshing capabilities using Gmsh’s OCC integration, enabling direct geometry transfer from yapCAD’s OCC-based BREP representation.

The key advantage is that both yapCAD and Gmsh use the OpenCASCADE kernel, so geometry can be passed directly without lossy STEP/IGES conversions.

Usage:

from yapcad.package.analysis.gmsh_mesher import GmshMesher, MeshHints

mesher = GmshMesher() mesh = mesher.mesh_from_solid(solid, hints=MeshHints(element_size=2.0)) mesher.export_mesh(workspace / “model.msh”)

Copyright (c) 2025 yapCAD contributors MIT License

class yapcad.package.analysis.gmsh_mesher.GmshMesher(model_name: str = 'yapCAD_model')[source]

Bases: object

Primary meshing interface using Gmsh’s OCC integration.

This class provides meshing capabilities for yapCAD solids using Gmsh. It leverages the shared OCC kernel between yapCAD and Gmsh for direct geometry transfer without intermediate file formats.

Example

mesher = GmshMesher() mesher.initialize() mesher.import_solid(solid) mesher.set_physical_groups({“fixed_face”: [1, 2], “load_face”: [3]}) mesher.generate_mesh(hints) mesher.export_mesh(Path(“output.msh”)) mesher.finalize()

export_mesh(path: Path, format: str | None = None) Path[source]

Export the mesh to a file.

Parameters:
  • path – Output path

  • format – Optional format override (msh, vtk, xdmf, su2)

Returns:

Path to the exported file

finalize() None[source]

Finalize Gmsh and release resources.

generate_mesh(hints: MeshHints | None = None, dim: int = 3) None[source]

Generate the mesh.

Parameters:
  • hints – Mesh generation hints

  • dim – Mesh dimension (2 for surface, 3 for volume)

get_mesh_stats() Dict[str, Any][source]

Get mesh statistics.

Returns:

Dictionary with node count, element counts by type, quality metrics

import_solid(solid: Any, face_names: Dict[str, List[int]] | None = None, use_stl: bool = False) List[Tuple[int, int]][source]

Import a yapCAD solid into Gmsh.

This uses Gmsh’s OCC integration to import the geometry directly from the OCC representation, avoiding STEP/IGES conversion losses.

Parameters:
  • solid – yapCAD solid (must have OCC BREP representation)

  • face_names – Optional mapping of face names to face indices

  • use_stl – If True, use STL (tessellated) representation which may be more robust for complex geometries with topology issues

Returns:

List of (dim, tag) tuples for imported entities

import_step(step_path: Path) List[Tuple[int, int]][source]

Import geometry from a STEP file.

Parameters:

step_path – Path to the STEP file

Returns:

List of (dim, tag) tuples for imported entities

initialize(verbose: bool = True, geometry_tolerance: float = 0.1) None[source]

Initialize Gmsh (must be called before other operations).

Parameters:
  • verbose – If True, enable terminal output for progress monitoring

  • geometry_tolerance – Tolerance for geometry repair operations

set_physical_groups(groups: Dict[str, List[int]], dim: int = 2) None[source]

Define physical groups for boundary conditions.

Physical groups associate mesh entities with names that can be used to apply boundary conditions in the solver.

Parameters:
  • groups – Mapping of group names to entity tags

  • dim – Dimension of entities (2 for faces, 3 for volumes)

set_physical_groups_by_normal(groups: Dict[str, Tuple[float, float, float]], tolerance_deg: float = 5.0) None[source]

Define physical groups by face normal direction.

This is useful for automatically identifying faces like “top”, “bottom”, “front”, etc. based on their orientation.

Parameters:
  • groups – Mapping of group names to normal vectors (x, y, z)

  • tolerance_deg – Angular tolerance in degrees

class yapcad.package.analysis.gmsh_mesher.MeshHints(element_size: float = 5.0, min_element_size: float | None = None, max_element_size: float | None = None, algorithm_2d: int = 6, algorithm_3d: int = 1, element_order: int = 1, optimize: bool = True, optimize_netgen: bool = False, refinement_fields: Dict[str, ~typing.Any]]=<factory>, geometry_tolerance: float = 0.0001, recover_3d: bool = True, use_stl: bool = False, scale_factor: float = 1.0)[source]

Bases: object

Mesh generation hints for Gmsh.

Variables:
  • element_size (float) – Target element size (mesh density)

  • min_element_size (float | None) – Minimum element size

  • max_element_size (float | None) – Maximum element size

  • algorithm_2d (int) – 2D meshing algorithm (1=MeshAdapt, 2=Auto, 5=Delaunay, 6=Frontal-Delaunay)

  • algorithm_3d (int) – 3D meshing algorithm (1=Delaunay, 4=Frontal, 10=HXT)

  • element_order (int) – Element polynomial order (1=linear, 2=quadratic)

  • optimize (bool) – Whether to optimize mesh quality

  • optimize_netgen (bool) – Use Netgen optimizer for 3D meshes

  • refinement_fields (List[Dict[str, Any]]) – List of refinement field specifications

  • geometry_tolerance (float) – Tolerance for geometry healing (default 1e-4)

  • recover_3d (bool) – If False, skip 3D mesh generation and do 2D only

  • stl_fallback – If True, use STL intermediate format when BREP fails

algorithm_2d: int = 6
algorithm_3d: int = 1
element_order: int = 1
element_size: float = 5.0
geometry_tolerance: float = 0.0001
max_element_size: float | None = None
min_element_size: float | None = None
optimize: bool = True
optimize_netgen: bool = False
recover_3d: bool = True
refinement_fields: List[Dict[str, Any]]
scale_factor: float = 1.0
use_stl: bool = False
class yapcad.package.analysis.gmsh_mesher.PhysicalGroup(name: str, dim: int, tags: List[int])[source]

Bases: object

A named group of mesh entities (for boundary conditions).

Variables:
  • name (str) – Human-readable name for the group

  • dim (int) – Dimension (0=point, 1=edge, 2=face, 3=volume)

  • tags (List[int]) – Gmsh entity tags in this group

dim: int
name: str
tags: List[int]
yapcad.package.analysis.gmsh_mesher.gmsh_available() bool[source]

Return True if Gmsh Python API is available.

yapcad.package.analysis.gmsh_mesher.mesh_solid(solid: Any, output_path: Path, hints: MeshHints | None = None, physical_groups: Dict[str, List[int]] | None = None, dim: int = 3) Dict[str, Any][source]

Convenience function to mesh a solid and export.

Parameters:
  • solid – yapCAD solid to mesh

  • output_path – Path for output mesh file

  • hints – Mesh generation hints

  • physical_groups – Optional face groups for BCs

  • dim – Mesh dimension

Returns:

Mesh statistics dictionary

yapcad.package.analysis.gmsh_mesher.require_gmsh() None[source]

Raise error if Gmsh is not available.

yapcad.package.analysis.mechatron_fea_setup module

Mechatron-canonical FEA setup helper.

Reads bolt_patterns and load_cases from a Mechatron graph.json (the canonical source-of-truth) and produces structured inputs the FEA solver needs: per-bolt world coordinates, spring stiffness lookup, load case attach resolution.

Replaces the v4-v7 pattern of hand-rolled bolt_inventory.json + canonical.json side files. After this lands, a FEA script does:

from yapcad.package.analysis.mechatron_fea_setup import prepare
setup = prepare(graph_path="path/to/assembly/graph.json",
                load_case_id="LC-004a")
# setup.bolts:        list of Bolt entries (world coords + axis + spec)
# setup.spring_k:     {(bolt_idx): (k_axial_N_per_m, k_shear_N_per_m)}
# setup.load_attach:  resolved attach info (part, position_mm, direction_unit)
# setup.load_case:    raw LoadCase dict for reference

History: created 2026-05-20 as Phase 3+4 of the FEA → Mechatron integration plan.

class yapcad.package.analysis.mechatron_fea_setup.Bolt(interface_id: str, bolt_index: int, parent_part: str, child_part: str, parent_world_mm: Tuple[float, float, float], child_world_mm: Tuple[float, float, float], axis_unit: Tuple[float, float, float], bolt_spec: str, pcd_mm: float, clock_deg: float, k_axial_N_per_m: float, k_shear_N_per_m: float)[source]

Bases: object

One bolt in the assembly, world coordinates.

parent_world / child_world give the head- and nut-side positions; the bolt axis is the unit vector from parent to child (or access_direction if available).

axis_unit: Tuple[float, float, float]
bolt_index: int
bolt_spec: str
child_part: str
child_world_mm: Tuple[float, float, float]
clock_deg: float
interface_id: str
k_axial_N_per_m: float
k_shear_N_per_m: float
parent_part: str
parent_world_mm: Tuple[float, float, float]
pcd_mm: float
class yapcad.package.analysis.mechatron_fea_setup.FeaSetup(graph_path: str, bolts: List[Bolt] = <factory>, load_case_id: str | None = None, load_attach: LoadAttachResolved | None = None, raw_load_case: Dict[str, ~typing.Any] | None=None, raw_interfaces: Dict[str, ~typing.Any]]=<factory>)[source]

Bases: object

Everything an FEA script needs, sourced from mechatron graph.json.

bolts: List[Bolt]
graph_path: str
load_attach: LoadAttachResolved | None = None
load_case_id: str | None = None
raw_interfaces: List[Dict[str, Any]]
raw_load_case: Dict[str, Any] | None = None
class yapcad.package.analysis.mechatron_fea_setup.LoadAttachResolved(load_case_id: str, part: str, interface_id: str | None, position_mm: Tuple[float, float, float], direction_unit: Tuple[float, float, float], magnitude_n: float, coordinate_frame: str, bolt_index: int | None, clock_deg: float | None, raw: Dict[str, Any])[source]

Bases: object

A LoadCase resolved against the assembly: where the force is applied, in the FEA mesh frame, on which part(s).

bolt_index: int | None
clock_deg: float | None
coordinate_frame: str
direction_unit: Tuple[float, float, float]
interface_id: str | None
load_case_id: str
magnitude_n: float
part: str
position_mm: Tuple[float, float, float]
raw: Dict[str, Any]
yapcad.package.analysis.mechatron_fea_setup.generate_bolts_for_interface(iface: Dict[str, Any], parent_world_origin_mm: Tuple[float, float, float] | None = None, child_world_origin_mm: Tuple[float, float, float] | None = None, *, parts_by_id: Dict[str, Dict[str, Any]] | None = None, world_transforms: Dict[str, Tuple[List[float], List[float]]] | None = None, bolts_per_part_spec: Dict[str, Any] | None = None) List[Bolt][source]

Generate per-bolt entries for an interface’s bolt_pattern.

Two code paths:

  1. Preferred (post-2026-05-27): when parts_by_id + world_transforms are supplied, derive each bolt’s axis from the parent part’s per-hole datums (top_bolt_hole_N / bot_bolt_hole_N) transformed through the kinematic chain. The per-hole direction field in graph.json carries the true radial-or-axial bolt axis per hole, so this path produces correct orientations for both joint types.

    When bolts_per_part_spec is also supplied AND a matching group exists, additionally use the YAML’s orientation, head_axial_offset_mm / head_radial_offset_mm, and shank_length_mm to derive the head-anchor and shank-tip endpoints. parent_world_mm becomes the head anchor (where the bolt enters the joint), child_world_mm becomes the shank tip (where it exits), and the connector line spans the physical bolt length.

  2. Legacy fallback (used when parts_by_id is absent): evenly distribute bolts around PCD using bolt_pattern.access_direction and world_z_mm. Same behavior as the pre-2026-05-27 code. Note that this path emits all axes as ±Z, since it distributes bolts purely by PCD + access_direction and has no per-hole radial datum data. Use the preferred per-hole-datum path (supply parts_by_id + world_transforms) when correct radial-joint axes are needed.

Parameters:
  • iface – the Interface dict from graph.json (must have bolt_pattern)

  • parent_world_origin_mm – legacy override (used only in fallback path)

  • child_world_origin_mm – legacy override (used only in fallback path)

  • parts_by_id – optional {part_id: part_dict} index from graph.json

  • world_transforms – optional {part_id: ([tx,ty,tz], [qx,qy,qz,qw])} from solve_world_transforms(graph)

  • bolts_per_part_spec – optional bolts_per_part.yaml inner dict from _load_bolts_per_part_spec(graph_path)

Returns:

list of Bolt entries with world coords, axis, spec, stiffness.

yapcad.package.analysis.mechatron_fea_setup.get_interface(graph: Dict[str, Any], iface_id: str) Dict[str, Any][source]

Return one Interface by id, or raise KeyError.

yapcad.package.analysis.mechatron_fea_setup.get_load_case(graph: Dict[str, Any], lc_id: str) Dict[str, Any][source]

Return one LoadCase by id, or raise KeyError.

yapcad.package.analysis.mechatron_fea_setup.list_interfaces_with_bolt_patterns(graph: Dict[str, Any]) List[Dict[str, Any]][source]

Return only interfaces that have a bolt_pattern attached.

Skips bolt_patterns with PLACEHOLDER bolt_spec — those are flagged as needing engineering input before being usable.

yapcad.package.analysis.mechatron_fea_setup.list_load_cases(graph: Dict[str, Any]) List[Dict[str, Any]][source]

Return all LoadCase dicts from the graph.

yapcad.package.analysis.mechatron_fea_setup.load_graph(graph_path: str | Path) Dict[str, Any][source]

Load and validate a mechatron graph.json.

yapcad.package.analysis.mechatron_fea_setup.prepare(graph_path: str | Path, load_case_id: str | None = None, *, interface_origins_mm: Dict[str, Tuple[float, float, float]] | None = None) FeaSetup[source]

One-shot FEA setup from a mechatron graph.json.

Reads the graph, resolves the load case (if given), enumerates all structural bolts with stiffness, and returns a FeaSetup struct.

Parameters:
  • graph_path – path to graph.json (mechatron canonical)

  • load_case_id – e.g. “LC-004a” — if None, no load attach is resolved

  • interface_origins_mm – optional override map {iface_id: (x,y,z) world}. If not given, bolts are returned in interface-local coords with origin (0,0,0); the FEA setup is responsible for combining with the assembly transforms from the graph’s interface solve.

Returns:

FeaSetup with bolts, load_attach (if requested), and raw refs.

yapcad.package.analysis.mechatron_fea_setup.resolve_load_attach(load_case: Dict[str, Any]) LoadAttachResolved[source]

Convert a LoadCase dict to a resolved attach descriptor.

Does NOT compute world coordinates of bolt-targeted loads (those need interface origins from graph.json). Just packages the LoadCase fields into a struct the FEA solver can consume directly.

yapcad.package.analysis.mechatron_fea_setup.solve_world_transforms(graph: Dict[str, Any]) Dict[str, Tuple[List[float], List[float]]][source]

Walk the kinematic chain from world and compute world (T, Q) for every part.

Returns: dict mapping part_id -> ([tx,ty,tz], [qx,qy,qz,qw]).

Mirrors the algorithm in the dashboard’s _load_graph(). Interfaces carry origin: [x,y,z] (child position in PARENT-LOCAL frame) and optional orientation: [x,y,z,w] (child rotation in parent frame). Root is the synthetic world part at identity.

yapcad.package.analysis.mechatron_fea_setup.stiffness_for_bolt_spec(bolt_spec: str) Tuple[float, float][source]

Return (k_axial_N_per_m, k_shear_N_per_m) for a bolt spec.

Uses the canonical _BOLT_SPEC_GEOMETRY table. Unknown specs fall back to M5 stiffness with a warning.

yapcad.package.analysis.mechatron_fea_setup.vehicle_to_mesh_direction(direction: Sequence[float]) Tuple[float, float, float][source]

Same swap for direction vectors.

yapcad.package.analysis.mechatron_fea_setup.vehicle_to_mesh_position(pos: Sequence[float]) Tuple[float, float, float][source]

Vehicle frame (X=axial) → FEA mesh frame (Z=axial).

yapcad.package.analysis.schema module

Validation test schema implementation.

This module provides schema validation for yapCAD validation plans and results as specified in docs/validation_schema.rst.

Schema Version: validation-schema-v0.1

class yapcad.package.analysis.schema.ComparisonOp(*values)[source]

Bases: Enum

Acceptance criteria comparison operators.

APPROX = '~='
EQ = '=='
GE = '>='
GT = '>'
LE = '<='
LT = '<'
class yapcad.package.analysis.schema.ResultStatus(*values)[source]

Bases: Enum

Result status values.

ERROR = 'error'
FAILED = 'failed'
PASSED = 'passed'
PENDING = 'pending'
SKIPPED = 'skipped'
class yapcad.package.analysis.schema.SchemaError(path: str, message: str, severity: str = 'error')[source]

Bases: object

Represents a schema validation error.

message: str
path: str
severity: str = 'error'
class yapcad.package.analysis.schema.ValidationKind(*values)[source]

Bases: Enum

Supported validation test kinds.

ASSEMBLY = 'assembly'
CFD = 'cfd'
GEOMETRIC = 'geometric'
MEASUREMENT = 'measurement'
MULTIPHYSICS = 'multiphysics'
STRUCTURAL = 'structural'
THERMAL = 'thermal'
class yapcad.package.analysis.schema.ValidationReport(valid: bool, errors: List[SchemaError] = <factory>, warnings: List[SchemaError] = <factory>, schema_version: str = 'validation-schema-v0.1')[source]

Bases: object

Result of schema validation.

errors: List[SchemaError]
schema_version: str = 'validation-schema-v0.1'
valid: bool
warnings: List[SchemaError]
yapcad.package.analysis.schema.validate_plan(data: Dict[str, Any]) ValidationReport[source]

Validate a validation plan against the schema.

Parameters:

data – The plan data as a dictionary (loaded from YAML)

Returns:

ValidationReport with validation results

yapcad.package.analysis.schema.validate_plan_file(path: str | Path) ValidationReport[source]

Validate a validation plan YAML file.

Parameters:

path – Path to the YAML file

Returns:

ValidationReport with validation results

yapcad.package.analysis.schema.validate_result(data: Dict[str, Any]) ValidationReport[source]

Validate a validation result against the schema.

Parameters:

data – The result data as a dictionary (loaded from JSON)

Returns:

ValidationReport with validation results

yapcad.package.analysis.schema.validate_result_file(path: str | Path) ValidationReport[source]

Validate a validation result JSON file.

Parameters:

path – Path to the JSON file

Returns:

ValidationReport with validation results

yapcad.package.analysis.yapcad_native module

Native yapCAD backend for geometric and measurement validation tests.

This module provides validation capabilities using yapCAD’s built-in geometry functions. No external solvers are required.

Supported test kinds: - geometric: volume, area, bbox checks - measurement: mass, centroid calculations

Usage:

from yapcad.package.analysis.yapcad_native import YapCADNativeAdapter

adapter = YapCADNativeAdapter() result = adapter.run(manifest, plan, workspace)

Copyright (c) 2025 yapCAD contributors MIT License

class yapcad.package.analysis.yapcad_native.YapCADNativeAdapter[source]

Bases: AnalysisAdapter

Native yapCAD backend for geometric validation tests.

This adapter performs geometric and measurement checks using yapCAD’s built-in functions. It supports:

  • Volume checks (solid volume against limits)

  • Area checks (surface area or 2D region area)

  • Bounding box checks (dimensions, diagonal)

  • Mass checks (volume * density)

  • Centroid checks (center of mass location)

Results include computed metrics and pass/fail status based on acceptance criteria.

name: str = 'yapcad'
run(manifest: Any, plan: AnalysisPlan, workspace: Path, **kwargs: Any) AnalysisResult[source]

Execute the validation check.

Parameters:
  • manifest – Package manifest

  • plan – Analysis plan specification

  • workspace – Working directory for intermediate files

Returns:

AnalysisResult with metrics and pass/fail status

Module contents

Analysis helper exports.