303 lines
9.1 KiB
JSON
303 lines
9.1 KiB
JSON
{
|
||
"meta": {
|
||
"version": "2.0",
|
||
"created": "2026-02-09T12:00:00Z",
|
||
"modified": "2026-02-09T12:00:00Z",
|
||
"created_by": "optimizer-agent",
|
||
"modified_by": "optimizer-agent",
|
||
"study_name": "01_doe_landscape",
|
||
"description": "Hydrotech Beam — DoE landscape mapping + TPE optimization. Minimize mass subject to displacement and stress constraints.",
|
||
"tags": ["hydrotech-beam", "doe", "landscape", "tpe", "single-objective"]
|
||
},
|
||
"model": {
|
||
"sim": {
|
||
"path": "models/Beam_sim1.sim",
|
||
"solver": "nastran"
|
||
},
|
||
"part": "models/Beam.prt",
|
||
"fem": "models/Beam_fem1.fem",
|
||
"idealized": "models/Beam_fem1_i.prt"
|
||
},
|
||
"design_variables": [
|
||
{
|
||
"id": "dv_001",
|
||
"name": "beam_half_core_thickness",
|
||
"expression_name": "beam_half_core_thickness",
|
||
"type": "continuous",
|
||
"bounds": {
|
||
"min": 10,
|
||
"max": 40
|
||
},
|
||
"baseline": 20,
|
||
"units": "mm",
|
||
"enabled": true,
|
||
"description": "Core half-thickness. Stiffness scales ~quadratically via sandwich effect (lever arm). Also adds core mass linearly."
|
||
},
|
||
{
|
||
"id": "dv_002",
|
||
"name": "beam_face_thickness",
|
||
"expression_name": "beam_face_thickness",
|
||
"type": "continuous",
|
||
"bounds": {
|
||
"min": 10,
|
||
"max": 40
|
||
},
|
||
"baseline": 20,
|
||
"units": "mm",
|
||
"enabled": true,
|
||
"description": "Face sheet thickness. Primary bending stiffness contributor AND primary mass contributor. Key trade-off variable."
|
||
},
|
||
{
|
||
"id": "dv_003",
|
||
"name": "holes_diameter",
|
||
"expression_name": "holes_diameter",
|
||
"type": "continuous",
|
||
"bounds": {
|
||
"min": 150,
|
||
"max": 450
|
||
},
|
||
"baseline": 300,
|
||
"units": "mm",
|
||
"enabled": true,
|
||
"description": "Lightening hole diameter. Mass reduction scales with d². Stress concentration scales with hole size. Geometric feasibility depends on beam web length."
|
||
},
|
||
{
|
||
"id": "dv_004",
|
||
"name": "hole_count",
|
||
"expression_name": "hole_count",
|
||
"type": "integer",
|
||
"bounds": {
|
||
"min": 5,
|
||
"max": 15
|
||
},
|
||
"baseline": 10,
|
||
"units": "",
|
||
"enabled": true,
|
||
"description": "Number of lightening holes in the web. Integer variable (11 levels). Interacts strongly with holes_diameter for geometric feasibility."
|
||
}
|
||
],
|
||
"extractors": [
|
||
{
|
||
"id": "ext_001",
|
||
"name": "Mass Extractor",
|
||
"type": "expression",
|
||
"config": {
|
||
"expression_name": "p173",
|
||
"description": "Total beam mass from NX expression"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "mass",
|
||
"metric": "total",
|
||
"units": "kg"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": "ext_002",
|
||
"name": "Displacement Extractor",
|
||
"type": "displacement",
|
||
"config": {
|
||
"method": "result_sensor_or_op2",
|
||
"component": "magnitude",
|
||
"location": "beam_tip",
|
||
"description": "Tip displacement magnitude from SOL 101. Preferred: NX result sensor. Fallback: parse .op2 at tip node ID.",
|
||
"TODO": "Confirm displacement sensor exists in Beam_sim1.sim OR identify tip node ID"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "tip_displacement",
|
||
"metric": "max_magnitude",
|
||
"units": "mm"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": "ext_003",
|
||
"name": "Stress Extractor",
|
||
"type": "stress",
|
||
"config": {
|
||
"method": "op2_elemental_nodal",
|
||
"stress_type": "von_mises",
|
||
"scope": "all_elements",
|
||
"unit_conversion": "kPa_to_MPa",
|
||
"description": "Max von Mises stress (elemental nodal) from SOL 101. pyNastran returns kPa for NX kg-mm-s units — divide by 1000 for MPa.",
|
||
"TODO": "Verify element types in model (CQUAD4? CTETRA? CHEXA?) and confirm stress scope"
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "max_von_mises",
|
||
"metric": "max",
|
||
"units": "MPa"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"objectives": [
|
||
{
|
||
"id": "obj_001",
|
||
"name": "Minimize beam mass",
|
||
"direction": "minimize",
|
||
"weight": 1.0,
|
||
"source": {
|
||
"extractor_id": "ext_001",
|
||
"output_name": "mass"
|
||
},
|
||
"units": "kg"
|
||
}
|
||
],
|
||
"constraints": [
|
||
{
|
||
"id": "con_001",
|
||
"name": "Tip displacement limit",
|
||
"type": "hard",
|
||
"operator": "<=",
|
||
"threshold": 10.0,
|
||
"source": {
|
||
"extractor_id": "ext_002",
|
||
"output_name": "tip_displacement"
|
||
},
|
||
"penalty_config": {
|
||
"method": "deb_rules",
|
||
"description": "Deb's feasibility rules: feasible always beats infeasible; among infeasible, lower violation wins"
|
||
},
|
||
"margin_buffer": {
|
||
"optimizer_target": 9.5,
|
||
"hard_limit": 10.0,
|
||
"description": "5% inner margin during optimization to account for numerical noise"
|
||
}
|
||
},
|
||
{
|
||
"id": "con_002",
|
||
"name": "Von Mises stress limit",
|
||
"type": "hard",
|
||
"operator": "<=",
|
||
"threshold": 130.0,
|
||
"source": {
|
||
"extractor_id": "ext_003",
|
||
"output_name": "max_von_mises"
|
||
},
|
||
"penalty_config": {
|
||
"method": "deb_rules",
|
||
"description": "Deb's feasibility rules: feasible always beats infeasible; among infeasible, lower violation wins"
|
||
},
|
||
"margin_buffer": {
|
||
"optimizer_target": 123.5,
|
||
"hard_limit": 130.0,
|
||
"description": "5% inner margin during optimization to account for mesh sensitivity"
|
||
}
|
||
}
|
||
],
|
||
"optimization": {
|
||
"phases": [
|
||
{
|
||
"id": "phase_1",
|
||
"name": "DoE Landscape Mapping",
|
||
"algorithm": {
|
||
"type": "LHS",
|
||
"config": {
|
||
"criterion": "maximin",
|
||
"integer_handling": "round_nearest_stratified",
|
||
"seed": 42
|
||
}
|
||
},
|
||
"budget": {
|
||
"max_trials": 50,
|
||
"baseline_enqueued": true,
|
||
"total_with_baseline": 51
|
||
},
|
||
"purpose": "Map design space, identify feasible region, assess sensitivities and interactions"
|
||
},
|
||
{
|
||
"id": "phase_2",
|
||
"name": "TPE Optimization",
|
||
"algorithm": {
|
||
"type": "TPE",
|
||
"config": {
|
||
"sampler": "TPESampler",
|
||
"n_startup_trials": 0,
|
||
"warm_start_from": "phase_1_best_feasible",
|
||
"seed": 42,
|
||
"constraint_handling": "deb_feasibility_rules"
|
||
}
|
||
},
|
||
"budget": {
|
||
"min_trials": 60,
|
||
"max_trials": 100,
|
||
"adaptive": true
|
||
},
|
||
"convergence": {
|
||
"stall_window": 20,
|
||
"stall_threshold_pct": 1.0,
|
||
"min_trials_before_check": 60
|
||
},
|
||
"purpose": "Directed optimization to converge on minimum-mass feasible design"
|
||
}
|
||
],
|
||
"total_budget": {
|
||
"min": 114,
|
||
"max": 156,
|
||
"estimated_hours": "4-5"
|
||
},
|
||
"baseline_trial": {
|
||
"enqueue": true,
|
||
"values": {
|
||
"beam_half_core_thickness": 20,
|
||
"beam_face_thickness": 20,
|
||
"holes_diameter": 300,
|
||
"hole_count": 10
|
||
},
|
||
"expected_results": {
|
||
"mass_kg": 974,
|
||
"tip_displacement_mm": 22,
|
||
"max_von_mises_mpa": "UNKNOWN — must measure"
|
||
}
|
||
}
|
||
},
|
||
"error_handling": {
|
||
"trial_timeout_seconds": 600,
|
||
"on_nx_rebuild_failure": "record_infeasible_max_violation",
|
||
"on_solver_failure": "record_infeasible_max_violation",
|
||
"on_extraction_failure": "record_infeasible_max_violation",
|
||
"max_consecutive_failures": 5,
|
||
"max_failure_rate_pct": 30,
|
||
"nx_process_management": "NEVER kill NX directly. Use NXSessionManager.close_nx_if_allowed() only."
|
||
},
|
||
"pre_flight_checks": [
|
||
{
|
||
"id": "pf_001",
|
||
"name": "Baseline validation",
|
||
"description": "Run Trial 0 with baseline parameters, verify mass ≈ 974 kg and displacement ≈ 22 mm"
|
||
},
|
||
{
|
||
"id": "pf_002",
|
||
"name": "Corner tests",
|
||
"description": "Test 16 corner combinations (min/max for each DV). Verify NX rebuilds and solves at all corners."
|
||
},
|
||
{
|
||
"id": "pf_003",
|
||
"name": "Mesh convergence",
|
||
"description": "Run baseline at 3 mesh densities. Verify stress convergence within 10%."
|
||
},
|
||
{
|
||
"id": "pf_004",
|
||
"name": "Extractor validation",
|
||
"description": "Confirm mass, displacement, and stress extractors return correct values at baseline."
|
||
},
|
||
{
|
||
"id": "pf_005",
|
||
"name": "Geometric feasibility",
|
||
"description": "Determine beam web length. Verify max(hole_count) × max(holes_diameter) fits. Add ligament constraint if needed."
|
||
}
|
||
],
|
||
"open_items": [
|
||
"Beam web length needed for geometric feasibility validation (holes_diameter × hole_count vs available length)",
|
||
"Displacement extraction method: result sensor in .sim or .op2 node ID parsing?",
|
||
"Stress extraction scope: whole model or specific element group?",
|
||
"Verify NX expression name 'p173' maps to mass",
|
||
"Benchmark single SOL 101 runtime to refine compute estimates",
|
||
"Confirm baseline stress value (currently unknown)",
|
||
"Clarify relationship between core/face thickness DVs and web height where holes are placed"
|
||
]
|
||
}
|