yapCAD Validation Test Schema
Version: validation-schema-v1.0
Status: Implemented – yapCAD 1.0
Code implementation: yapcad.package.analysis.schema
This document defines the schema for validation tests that can be stored in
yapCAD packages (.ycpkg). Validation tests allow automated verification
of design requirements against geometry, simulation results, or computed
properties.
Overview
Validation tests are stored as YAML files under validation/plans/ in a
package. Each test file defines:
Identity: Unique ID, kind, and human-readable description
Inputs: What geometry/data the test operates on
Acceptance Criteria: Pass/fail conditions
Execution: How to run the test (local/remote, tool configuration)
Results: Captured outputs stored under
validation/results/
Test Kinds
Validation tests are categorized by kind:
Geometric Tests (geometric)
Tests that verify geometric properties of shapes without simulation.
volume: Check solid volume against limits
area: Check surface area or 2D region area
bbox: Check bounding box dimensions
distance: Check distances between features
clearance: Check minimum clearance between parts
Measurement Tests (measurement)
Tests that verify computed measurements or derived values.
dimension: Check a specific dimension (length, width, height)
mass: Check mass given density
centroid: Check center of mass location
moment: Check moment of inertia
Simulation Tests (structural, thermal, cfd, multiphysics)
Tests that invoke external solvers for physical simulation.
structural: FEA stress/deflection analysis (backends: fenics, calculix, abaqus)
thermal: Heat transfer analysis
cfd: Computational fluid dynamics
multiphysics: Coupled physics (backend: comsol)
Assembly Tests (assembly)
Tests that verify assembly constraints and relationships.
interference: Check for part overlaps
fit: Check clearance fit requirements
alignment: Check alignment constraints
Schema Definition
Common Fields
All validation tests share these fields:
# Required
id: string # Unique identifier (e.g., "volume-check-001")
kind: string # Test category (see above)
backend: string # Tool/method for evaluation
# Optional but recommended
name: string # Human-readable name
description: string # Detailed description
# Input specification
geometry:
source: path # Path to geometry file (relative to package)
entities: list<str> # Entity IDs to test (empty = all)
# Pass/fail criteria
acceptance:
<metric_name>:
limit: number # Threshold value
comparison: string # "<=", ">=", "<", ">", "==", "~=" (approximate)
tolerance: number # For "~=" comparison (optional)
units: string # Units for documentation
description: string # Human-readable explanation
# Execution context
execution:
mode: string # "local" or "remote"
command: string # Solver command (optional)
env: map<str,str> # Environment variables
timeout_s: number # Maximum execution time
# Metadata
metadata:
author: string
created: string # ISO 8601 date
revision: number
tags: list<str>
Geometric Test Schema
For kind: geometric:
id: volume-check
kind: geometric
backend: yapcad # Native yapCAD computation
geometry:
source: geometry/primary.json
entities: ["solid-main"]
check:
property: volume # volume, area, bbox, centroid
units: mm3
acceptance:
volume:
limit: 50000.0
comparison: ">="
description: "Minimum material volume for strength"
# For bounding box checks
# check:
# property: bbox
# axis: x # x, y, z, or "all"
#
# acceptance:
# bbox.x:
# limit: 100.0
# comparison: "<="
Measurement Test Schema
For kind: measurement:
id: mass-check
kind: measurement
backend: yapcad
geometry:
source: geometry/primary.json
entities: ["solid-main"]
check:
property: mass
density_kgm3: 2700 # Material density
acceptance:
mass_kg:
limit: 0.5
comparison: "<="
description: "Maximum mass for weight budget"
Structural Analysis Schema
For kind: structural (FEA):
id: thrust-fea
kind: structural
backend: fenics # or calculix, abaqus
name: "Thrust Plate Static Analysis"
description: |
Linear elastic analysis under max thrust.
geometry:
source: geometry/primary.json
entities: ["solid-main"]
materials:
default:
name: "6061-T6 Aluminum"
youngs_modulus_pa: 68.9e9
poisson_ratio: 0.33
density_kgm3: 2700
loads:
- id: thrust_pressure
type: pressure # pressure, force, moment
surfaces: ["motor_mount"]
magnitude_pa: 2.61e6
boundaryConditions:
- id: fixed_base
type: fixed # fixed, pinned, roller, spring
surfaces: ["bottom_face"]
acceptance:
displacement.max_mm:
limit: 10.0
comparison: "<="
stress.von_mises.max_pa:
limit: 180e6
comparison: "<="
backendOptions:
mesh:
element_size: 5.0
element_order: 1
solver:
type: linear
faceNaming:
strategy: geometric
rules:
- name: motor_mount
selector:
type: cylindrical
radius: 50.8
execution:
mode: local
timeout_s: 600
Assembly Test Schema
For kind: assembly:
id: clearance-check
kind: assembly
backend: yapcad
geometry:
source: geometry/primary.json
entities: ["part_a", "part_b"]
check:
property: clearance
between:
- entity: part_a
surface: outer
- entity: part_b
surface: inner
acceptance:
min_clearance_mm:
limit: 0.5
comparison: ">="
description: "Sliding fit clearance"
Surface Selection Strategies
For FEA boundary conditions and loads, surfaces can be selected by name or
by geometric strategy. The strategy field invokes backend-specific
surface selectors:
Built-in Strategies
Position-based (all backends):
z_min- Bottom surface (minimum Z coordinate)z_max- Top surface (maximum Z coordinate)x_min,x_max,y_min,y_max- Axis-aligned selections
Shape-based (fenics backend):
z_max_ring- Top surface excluding central region (for ring/annular loads)motor_mount- Central cylindrical regionstringer_notches- Edge notch regions at specified angles
Face Naming Rules
The faceNaming section can define custom surface selection rules:
faceNaming:
strategy: geometric
rules:
- name: motor_mount_inner
selector:
type: cylindrical
axis: [0, 0, 1]
radius: 50.8
tolerance: 1.0
- name: stringer_notch_1
selector:
type: planar
normal: [1, 0, 0]
position_constraint:
axis: x
at_max: true
Result Schema
After execution, results are stored in validation/results/<plan_id>/:
{
"plan_id": "thrust-fea",
"status": "passed",
"timestamp": "2025-12-30T15:30:00Z",
"backend": "fenics",
"backend_version": "0.8.0",
"execution_time_s": 45.2,
"metrics": {
"displacement.max_mm": 7.3,
"stress.von_mises.max_pa": 145e6,
"nodes": 12500,
"elements": 8200
},
"acceptance_results": {
"displacement.max_mm": {
"value": 7.3,
"limit": 10.0,
"comparison": "<=",
"passed": true,
"margin": 2.7,
"margin_pct": 27.0
},
"stress.von_mises.max_pa": {
"value": 145e6,
"limit": 180e6,
"comparison": "<=",
"passed": true,
"margin": 35e6,
"margin_pct": 19.4
}
},
"artifacts": [
{"kind": "mesh", "path": "mesh.msh"},
{"kind": "solution", "path": "displacement.pvd"},
{"kind": "log", "path": "solver.log"}
],
"errors": [],
"warnings": [],
"notes": "Analysis completed successfully."
}
Status Values
passed- All acceptance criteria metfailed- One or more criteria not meterror- Execution error (solver crash, missing files, etc.)skipped- Plan skipped (missing backend, disabled, etc.)pending- Queued for remote execution
Backend Registration
Backends are registered in yapCAD via the adapter framework:
from yapcad.package.analysis.base import (
AnalysisAdapter, AnalysisPlan, AnalysisResult,
register_backend
)
class MyAdapter(AnalysisAdapter):
name = "my-solver"
def run(self, manifest, plan: AnalysisPlan,
workspace: Path, **kwargs) -> AnalysisResult:
# Implement solver invocation
...
return AnalysisResult(
plan_id=plan.plan_id,
status="passed",
metrics={...}
)
register_backend("my-solver", MyAdapter)
Built-in Backends
yapcad: Native geometric/measurement checks (always available)
fenics: FEniCSx-based FEA (requires dolfinx)
calculix: CalculiX solver (requires ccx binary)
Example: Complete Package
my_design.ycpkg/
├── manifest.yaml
├── geometry/
│ └── primary.json
├── validation/
│ ├── plans/
│ │ ├── volume-check.yaml # Geometric test
│ │ ├── mass-budget.yaml # Measurement test
│ │ └── structural-fea.yaml # Simulation test
│ └── results/
│ ├── volume-check/
│ │ └── summary.json
│ ├── mass-budget/
│ │ └── summary.json
│ └── structural-fea/
│ ├── summary.json
│ ├── mesh.msh
│ └── displacement.pvd
└── exports/
└── model.step
CLI Usage
# Run a specific validation plan
python tools/ycpkg_analyze.py my_design.ycpkg/ --plan validation/plans/volume-check.yaml
# Run all validation plans in a package
python tools/ycpkg_analyze.py my_design.ycpkg/ --all
# Generate validation report
python tools/ycpkg_analyze.py my_design.ycpkg/ --report validation_report.html
Future Extensions
JSON Schema files: Formal JSON Schema documents for automated validation
DSL-based tests: Define tests directly in DSL files
Parametric sweeps: Run tests across parameter ranges
CI/CD integration: GitHub Actions workflow templates
Result visualization: Interactive result viewers