feat: Add substudy system with live history tracking and workflow fixes

Major Features:
- Hierarchical substudy system (like NX Solutions/Subcases)
  * Shared model files across all substudies
  * Independent configuration per substudy
  * Continuation support from previous substudies
  * Real-time incremental history updates
- Live history tracking with optimization_history_incremental.json
- Complete bracket_displacement_maximizing study with substudy examples

Core Fixes:
- Fixed expression update workflow to pass design_vars through simulation_runner
  * Restored working NX journal expression update mechanism
  * OP2 timestamp verification instead of file deletion
  * Resolved issue where all trials returned identical objective values
- Fixed LLMOptimizationRunner to pass design variables to simulation runner
- Enhanced NXSolver with timestamp-based file regeneration verification

New Components:
- optimization_engine/llm_optimization_runner.py - LLM-driven optimization runner
- optimization_engine/optimization_setup_wizard.py - Phase 3.3 setup wizard
- studies/bracket_displacement_maximizing/ - Complete substudy example
  * run_substudy.py - Substudy runner with continuation
  * run_optimization.py - Standalone optimization runner
  * config/substudy_template.json - Template for new substudies
  * substudies/coarse_exploration/ - 20-trial coarse search
  * substudies/fine_tuning/ - 50-trial refinement (continuation example)
  * SUBSTUDIES_README.md - Complete substudy documentation

Technical Improvements:
- Incremental history saving after each trial (optimization_history_incremental.json)
- Expression update workflow: .prt update → NX journal receives values → geometry update → FEM update → solve
- Trial indexing fix in substudy result saving
- Updated README with substudy system documentation

Testing:
- Successfully ran 20-trial coarse_exploration substudy
- Verified different objective values across trials (workflow fix validated)
- Confirmed live history updates in real-time
- Tested shared model file usage across substudies

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-16 21:29:54 -05:00
parent 90a9e020d8
commit 2f3afc3813
126 changed files with 15592 additions and 97 deletions

View File

@@ -0,0 +1,31 @@
{
"substudy_name": "coarse_exploration",
"description": "Fast coarse exploration with 20 trials across wide parameter space",
"parent_study": "bracket_displacement_maximizing",
"created_date": "2025-11-16",
"optimization": {
"algorithm": "TPE",
"direction": "minimize",
"n_trials": 20,
"n_startup_trials": 10,
"design_variables": [
{
"parameter": "tip_thickness",
"min": 15.0,
"max": 25.0,
"units": "mm"
},
{
"parameter": "support_angle",
"min": 20.0,
"max": 40.0,
"units": "degrees"
}
]
},
"continuation": {
"enabled": false
}
}

View File

@@ -0,0 +1,56 @@
"""
Auto-generated by Atomizer Phase 3 - pyNastran Research Agent
Pattern: displacement
Element Type: General
Result Type: displacement
API: model.displacements[subcase]
"""
from pathlib import Path
from typing import Dict, Any
import numpy as np
from pyNastran.op2.op2 import OP2
def extract_displacement(op2_file: Path, subcase: int = 1):
"""Extract displacement results from OP2 file."""
from pyNastran.op2.op2 import OP2
import numpy as np
model = OP2()
model.read_op2(str(op2_file))
disp = model.displacements[subcase]
itime = 0 # static case
# Extract translation components
txyz = disp.data[itime, :, :3] # [tx, ty, tz]
# Calculate total displacement
total_disp = np.linalg.norm(txyz, axis=1)
max_disp = np.max(total_disp)
# Get node info
node_ids = [nid for (nid, grid_type) in disp.node_gridtype]
max_disp_node = node_ids[np.argmax(total_disp)]
return {
'max_displacement': float(max_disp),
'max_disp_node': int(max_disp_node),
'max_disp_x': float(np.max(np.abs(txyz[:, 0]))),
'max_disp_y': float(np.max(np.abs(txyz[:, 1]))),
'max_disp_z': float(np.max(np.abs(txyz[:, 2])))
}
if __name__ == '__main__':
# Example usage
import sys
if len(sys.argv) > 1:
op2_file = Path(sys.argv[1])
result = extract_displacement(op2_file)
print(f"Extraction result: {result}")
else:
print("Usage: python {sys.argv[0]} <op2_file>")

View File

@@ -0,0 +1,64 @@
"""
Auto-generated by Atomizer Phase 3 - pyNastran Research Agent
Pattern: solid_stress
Element Type: CTETRA
Result Type: stress
API: model.ctetra_stress[subcase] or model.chexa_stress[subcase]
"""
from pathlib import Path
from typing import Dict, Any
import numpy as np
from pyNastran.op2.op2 import OP2
def extract_solid_stress(op2_file: Path, subcase: int = 1, element_type: str = 'ctetra'):
"""Extract stress from solid elements."""
from pyNastran.op2.op2 import OP2
import numpy as np
model = OP2()
model.read_op2(str(op2_file))
# Get stress object for element type
# In pyNastran, stress is stored in model.op2_results.stress
stress_attr = f"{element_type}_stress"
if not hasattr(model, 'op2_results') or not hasattr(model.op2_results, 'stress'):
raise ValueError(f"No stress results in OP2")
stress_obj = model.op2_results.stress
if not hasattr(stress_obj, stress_attr):
raise ValueError(f"No {element_type} stress results in OP2")
stress = getattr(stress_obj, stress_attr)[subcase]
itime = 0
# Extract von Mises if available
if stress.is_von_mises: # Property, not method
von_mises = stress.data[itime, :, 9] # Column 9 is von Mises
max_stress = float(np.max(von_mises))
# Get element info
element_ids = [eid for (eid, node) in stress.element_node]
max_stress_elem = element_ids[np.argmax(von_mises)]
return {
'max_von_mises': max_stress,
'max_stress_element': int(max_stress_elem)
}
else:
raise ValueError("von Mises stress not available")
if __name__ == '__main__':
# Example usage
import sys
if len(sys.argv) > 1:
op2_file = Path(sys.argv[1])
result = extract_solid_stress(op2_file)
print(f"Extraction result: {result}")
else:
print("Usage: python {sys.argv[0]} <op2_file>")

View File

@@ -0,0 +1,362 @@
[
{
"trial_number": 1,
"design_variables": {
"tip_thickness": 17.389878779619163,
"support_angle": 20.866887194604573
},
"results": {
"max_displacement": 0.6116114854812622,
"max_disp_node": 55,
"max_disp_x": 0.0039984011091291904,
"max_disp_y": 0.10416693240404129,
"max_disp_z": 0.6026755571365356
},
"calculations": {
"neg_displacement": -0.6116114854812622
},
"objective": 0.6116114854812622
},
{
"trial_number": 2,
"design_variables": {
"tip_thickness": 22.220441224956033,
"support_angle": 30.840923860420357
},
"results": {
"max_displacement": 0.28716832399368286,
"max_disp_node": 58,
"max_disp_x": 0.0024955333210527897,
"max_disp_y": 0.06367127597332001,
"max_disp_z": 0.28002074360847473
},
"calculations": {
"neg_displacement": -0.28716832399368286
},
"objective": 0.28716832399368286
},
{
"trial_number": 3,
"design_variables": {
"tip_thickness": 16.556374034848037,
"support_angle": 22.45231282549564
},
"results": {
"max_displacement": 0.6623445749282837,
"max_disp_node": 58,
"max_disp_x": 0.004246150143444538,
"max_disp_y": 0.1103561595082283,
"max_disp_z": 0.6530864238739014
},
"calculations": {
"neg_displacement": -0.6623445749282837
},
"objective": 0.6623445749282837
},
{
"trial_number": 4,
"design_variables": {
"tip_thickness": 22.88337112412688,
"support_angle": 34.142850054848
},
"results": {
"max_displacement": 0.2482926845550537,
"max_disp_node": 58,
"max_disp_x": 0.002143946709111333,
"max_disp_y": 0.05768103152513504,
"max_disp_z": 0.24149981141090393
},
"calculations": {
"neg_displacement": -0.2482926845550537
},
"objective": 0.2482926845550537
},
{
"trial_number": 5,
"design_variables": {
"tip_thickness": 20.338667724550465,
"support_angle": 29.92278029095064
},
"results": {
"max_displacement": 0.34881672263145447,
"max_disp_node": 58,
"max_disp_x": 0.0029699159786105156,
"max_disp_y": 0.07262033224105835,
"max_disp_z": 0.34117355942726135
},
"calculations": {
"neg_displacement": -0.34881672263145447
},
"objective": 0.34881672263145447
},
{
"trial_number": 6,
"design_variables": {
"tip_thickness": 24.50967137117151,
"support_angle": 21.697159236156473
},
"results": {
"max_displacement": 0.2758632004261017,
"max_disp_node": 58,
"max_disp_x": 0.00244400673545897,
"max_disp_y": 0.06081655994057655,
"max_disp_z": 0.2690759301185608
},
"calculations": {
"neg_displacement": -0.2758632004261017
},
"objective": 0.2758632004261017
},
{
"trial_number": 7,
"design_variables": {
"tip_thickness": 22.377093973916722,
"support_angle": 31.532495067510975
},
"results": {
"max_displacement": 0.27826353907585144,
"max_disp_node": 58,
"max_disp_x": 0.0023749535903334618,
"max_disp_y": 0.06228335201740265,
"max_disp_z": 0.27120357751846313
},
"calculations": {
"neg_displacement": -0.27826353907585144
},
"objective": 0.27826353907585144
},
{
"trial_number": 8,
"design_variables": {
"tip_thickness": 16.397088760589114,
"support_angle": 39.6907686972716
},
"results": {
"max_displacement": 0.38282549381256104,
"max_disp_node": 58,
"max_disp_x": 0.0032198228873312473,
"max_disp_y": 0.08009155839681625,
"max_disp_z": 0.37435370683670044
},
"calculations": {
"neg_displacement": -0.38282549381256104
},
"objective": 0.38282549381256104
},
{
"trial_number": 9,
"design_variables": {
"tip_thickness": 15.779109046050685,
"support_angle": 37.544844028080135
},
"results": {
"max_displacement": 0.4436984956264496,
"max_disp_node": 58,
"max_disp_x": 0.003604060271754861,
"max_disp_y": 0.08796636015176773,
"max_disp_z": 0.43489110469818115
},
"calculations": {
"neg_displacement": -0.4436984956264496
},
"objective": 0.4436984956264496
},
{
"trial_number": 10,
"design_variables": {
"tip_thickness": 21.072632312643005,
"support_angle": 38.313469876751704
},
"results": {
"max_displacement": 0.2564539313316345,
"max_disp_node": 58,
"max_disp_x": 0.002298053354024887,
"max_disp_y": 0.05997171252965927,
"max_disp_z": 0.2493431717157364
},
"calculations": {
"neg_displacement": -0.2564539313316345
},
"objective": 0.2564539313316345
},
{
"trial_number": 11,
"design_variables": {
"tip_thickness": 24.95032894956337,
"support_angle": 34.20965061068569
},
"results": {
"max_displacement": 0.21304214000701904,
"max_disp_node": 58,
"max_disp_x": 0.002044219756498933,
"max_disp_y": 0.052074797451496124,
"max_disp_z": 0.20657968521118164
},
"calculations": {
"neg_displacement": -0.21304214000701904
},
"objective": 0.21304214000701904
},
{
"trial_number": 12,
"design_variables": {
"tip_thickness": 24.894489548087346,
"support_angle": 34.551063779949075
},
"results": {
"max_displacement": 0.21274541318416595,
"max_disp_node": 58,
"max_disp_x": 0.002061901381239295,
"max_disp_y": 0.052174802869558334,
"max_disp_z": 0.20624838769435883
},
"calculations": {
"neg_displacement": -0.21274541318416595
},
"objective": 0.21274541318416595
},
{
"trial_number": 13,
"design_variables": {
"tip_thickness": 24.952883393809497,
"support_angle": 34.77451710881955
},
"results": {
"max_displacement": 0.21082018315792084,
"max_disp_node": 58,
"max_disp_x": 0.0020510517060756683,
"max_disp_y": 0.05187264829874039,
"max_disp_z": 0.20433887839317322
},
"calculations": {
"neg_displacement": -0.21082018315792084
},
"objective": 0.21082018315792084
},
{
"trial_number": 14,
"design_variables": {
"tip_thickness": 18.70443149555537,
"support_angle": 26.11221806912443
},
"results": {
"max_displacement": 0.46135807037353516,
"max_disp_node": 58,
"max_disp_x": 0.0034599562641233206,
"max_disp_y": 0.08689243346452713,
"max_disp_z": 0.4531014859676361
},
"calculations": {
"neg_displacement": -0.46135807037353516
},
"objective": 0.46135807037353516
},
{
"trial_number": 15,
"design_variables": {
"tip_thickness": 23.84954584574589,
"support_angle": 34.69889355903453
},
"results": {
"max_displacement": 0.22793325781822205,
"max_disp_node": 58,
"max_disp_x": 0.0021433867514133453,
"max_disp_y": 0.05458956956863403,
"max_disp_z": 0.2212996780872345
},
"calculations": {
"neg_displacement": -0.22793325781822205
},
"objective": 0.22793325781822205
},
{
"trial_number": 16,
"design_variables": {
"tip_thickness": 23.545082857154053,
"support_angle": 27.33776442268342
},
"results": {
"max_displacement": 0.27459517121315,
"max_disp_node": 58,
"max_disp_x": 0.002392930444329977,
"max_disp_y": 0.06125558167695999,
"max_disp_z": 0.2676756680011749
},
"calculations": {
"neg_displacement": -0.27459517121315
},
"objective": 0.27459517121315
},
{
"trial_number": 17,
"design_variables": {
"tip_thickness": 19.395958700724172,
"support_angle": 35.874156921626124
},
"results": {
"max_displacement": 0.32070934772491455,
"max_disp_node": 58,
"max_disp_x": 0.002739877672865987,
"max_disp_y": 0.06964103132486343,
"max_disp_z": 0.3130568861961365
},
"calculations": {
"neg_displacement": -0.32070934772491455
},
"objective": 0.32070934772491455
},
{
"trial_number": 18,
"design_variables": {
"tip_thickness": 21.536592042850017,
"support_angle": 32.171364735552
},
"results": {
"max_displacement": 0.29555052518844604,
"max_disp_node": 58,
"max_disp_x": 0.0025494550354778767,
"max_disp_y": 0.06503863632678986,
"max_disp_z": 0.2883055508136749
},
"calculations": {
"neg_displacement": -0.29555052518844604
},
"objective": 0.29555052518844604
},
{
"trial_number": 19,
"design_variables": {
"tip_thickness": 23.75885172872223,
"support_angle": 28.17043178772967
},
"results": {
"max_displacement": 0.2622140347957611,
"max_disp_node": 58,
"max_disp_x": 0.002298196544870734,
"max_disp_y": 0.05939820408821106,
"max_disp_z": 0.25539782643318176
},
"calculations": {
"neg_displacement": -0.2622140347957611
},
"objective": 0.2622140347957611
},
{
"trial_number": 20,
"design_variables": {
"tip_thickness": 24.946257551293495,
"support_angle": 36.54595394544202
},
"results": {
"max_displacement": 0.20071247220039368,
"max_disp_node": 58,
"max_disp_x": 0.0018801360856741667,
"max_disp_y": 0.05026965215802193,
"max_disp_z": 0.1943153589963913
},
"calculations": {
"neg_displacement": -0.20071247220039368
},
"objective": 0.20071247220039368
}
]

View File

@@ -0,0 +1,362 @@
[
{
"trial_number": 1,
"design_variables": {
"tip_thickness": 17.389878779619163,
"support_angle": 20.866887194604573
},
"results": {
"max_displacement": 0.6116114854812622,
"max_disp_node": 55.0,
"max_disp_x": 0.0039984011091291904,
"max_disp_y": 0.10416693240404129,
"max_disp_z": 0.6026755571365356
},
"calculations": {
"neg_displacement": -0.6116114854812622
},
"objective": 0.6116114854812622
},
{
"trial_number": 2,
"design_variables": {
"tip_thickness": 22.220441224956033,
"support_angle": 30.840923860420357
},
"results": {
"max_displacement": 0.28716832399368286,
"max_disp_node": 58.0,
"max_disp_x": 0.0024955333210527897,
"max_disp_y": 0.06367127597332001,
"max_disp_z": 0.28002074360847473
},
"calculations": {
"neg_displacement": -0.28716832399368286
},
"objective": 0.28716832399368286
},
{
"trial_number": 3,
"design_variables": {
"tip_thickness": 16.556374034848037,
"support_angle": 22.45231282549564
},
"results": {
"max_displacement": 0.6623445749282837,
"max_disp_node": 58.0,
"max_disp_x": 0.004246150143444538,
"max_disp_y": 0.1103561595082283,
"max_disp_z": 0.6530864238739014
},
"calculations": {
"neg_displacement": -0.6623445749282837
},
"objective": 0.6623445749282837
},
{
"trial_number": 4,
"design_variables": {
"tip_thickness": 22.88337112412688,
"support_angle": 34.142850054848
},
"results": {
"max_displacement": 0.2482926845550537,
"max_disp_node": 58.0,
"max_disp_x": 0.002143946709111333,
"max_disp_y": 0.05768103152513504,
"max_disp_z": 0.24149981141090393
},
"calculations": {
"neg_displacement": -0.2482926845550537
},
"objective": 0.2482926845550537
},
{
"trial_number": 5,
"design_variables": {
"tip_thickness": 20.338667724550465,
"support_angle": 29.92278029095064
},
"results": {
"max_displacement": 0.34881672263145447,
"max_disp_node": 58.0,
"max_disp_x": 0.0029699159786105156,
"max_disp_y": 0.07262033224105835,
"max_disp_z": 0.34117355942726135
},
"calculations": {
"neg_displacement": -0.34881672263145447
},
"objective": 0.34881672263145447
},
{
"trial_number": 6,
"design_variables": {
"tip_thickness": 24.50967137117151,
"support_angle": 21.697159236156473
},
"results": {
"max_displacement": 0.2758632004261017,
"max_disp_node": 58.0,
"max_disp_x": 0.00244400673545897,
"max_disp_y": 0.06081655994057655,
"max_disp_z": 0.2690759301185608
},
"calculations": {
"neg_displacement": -0.2758632004261017
},
"objective": 0.2758632004261017
},
{
"trial_number": 7,
"design_variables": {
"tip_thickness": 22.377093973916722,
"support_angle": 31.532495067510975
},
"results": {
"max_displacement": 0.27826353907585144,
"max_disp_node": 58.0,
"max_disp_x": 0.0023749535903334618,
"max_disp_y": 0.06228335201740265,
"max_disp_z": 0.27120357751846313
},
"calculations": {
"neg_displacement": -0.27826353907585144
},
"objective": 0.27826353907585144
},
{
"trial_number": 8,
"design_variables": {
"tip_thickness": 16.397088760589114,
"support_angle": 39.6907686972716
},
"results": {
"max_displacement": 0.38282549381256104,
"max_disp_node": 58.0,
"max_disp_x": 0.0032198228873312473,
"max_disp_y": 0.08009155839681625,
"max_disp_z": 0.37435370683670044
},
"calculations": {
"neg_displacement": -0.38282549381256104
},
"objective": 0.38282549381256104
},
{
"trial_number": 9,
"design_variables": {
"tip_thickness": 15.779109046050685,
"support_angle": 37.544844028080135
},
"results": {
"max_displacement": 0.4436984956264496,
"max_disp_node": 58.0,
"max_disp_x": 0.003604060271754861,
"max_disp_y": 0.08796636015176773,
"max_disp_z": 0.43489110469818115
},
"calculations": {
"neg_displacement": -0.4436984956264496
},
"objective": 0.4436984956264496
},
{
"trial_number": 10,
"design_variables": {
"tip_thickness": 21.072632312643005,
"support_angle": 38.313469876751704
},
"results": {
"max_displacement": 0.2564539313316345,
"max_disp_node": 58.0,
"max_disp_x": 0.002298053354024887,
"max_disp_y": 0.05997171252965927,
"max_disp_z": 0.2493431717157364
},
"calculations": {
"neg_displacement": -0.2564539313316345
},
"objective": 0.2564539313316345
},
{
"trial_number": 11,
"design_variables": {
"tip_thickness": 24.95032894956337,
"support_angle": 34.20965061068569
},
"results": {
"max_displacement": 0.21304214000701904,
"max_disp_node": 58.0,
"max_disp_x": 0.002044219756498933,
"max_disp_y": 0.052074797451496124,
"max_disp_z": 0.20657968521118164
},
"calculations": {
"neg_displacement": -0.21304214000701904
},
"objective": 0.21304214000701904
},
{
"trial_number": 12,
"design_variables": {
"tip_thickness": 24.894489548087346,
"support_angle": 34.551063779949075
},
"results": {
"max_displacement": 0.21274541318416595,
"max_disp_node": 58.0,
"max_disp_x": 0.002061901381239295,
"max_disp_y": 0.052174802869558334,
"max_disp_z": 0.20624838769435883
},
"calculations": {
"neg_displacement": -0.21274541318416595
},
"objective": 0.21274541318416595
},
{
"trial_number": 13,
"design_variables": {
"tip_thickness": 24.952883393809497,
"support_angle": 34.77451710881955
},
"results": {
"max_displacement": 0.21082018315792084,
"max_disp_node": 58.0,
"max_disp_x": 0.0020510517060756683,
"max_disp_y": 0.05187264829874039,
"max_disp_z": 0.20433887839317322
},
"calculations": {
"neg_displacement": -0.21082018315792084
},
"objective": 0.21082018315792084
},
{
"trial_number": 14,
"design_variables": {
"tip_thickness": 18.70443149555537,
"support_angle": 26.11221806912443
},
"results": {
"max_displacement": 0.46135807037353516,
"max_disp_node": 58.0,
"max_disp_x": 0.0034599562641233206,
"max_disp_y": 0.08689243346452713,
"max_disp_z": 0.4531014859676361
},
"calculations": {
"neg_displacement": -0.46135807037353516
},
"objective": 0.46135807037353516
},
{
"trial_number": 15,
"design_variables": {
"tip_thickness": 23.84954584574589,
"support_angle": 34.69889355903453
},
"results": {
"max_displacement": 0.22793325781822205,
"max_disp_node": 58.0,
"max_disp_x": 0.0021433867514133453,
"max_disp_y": 0.05458956956863403,
"max_disp_z": 0.2212996780872345
},
"calculations": {
"neg_displacement": -0.22793325781822205
},
"objective": 0.22793325781822205
},
{
"trial_number": 16,
"design_variables": {
"tip_thickness": 23.545082857154053,
"support_angle": 27.33776442268342
},
"results": {
"max_displacement": 0.27459517121315,
"max_disp_node": 58.0,
"max_disp_x": 0.002392930444329977,
"max_disp_y": 0.06125558167695999,
"max_disp_z": 0.2676756680011749
},
"calculations": {
"neg_displacement": -0.27459517121315
},
"objective": 0.27459517121315
},
{
"trial_number": 17,
"design_variables": {
"tip_thickness": 19.395958700724172,
"support_angle": 35.874156921626124
},
"results": {
"max_displacement": 0.32070934772491455,
"max_disp_node": 58.0,
"max_disp_x": 0.002739877672865987,
"max_disp_y": 0.06964103132486343,
"max_disp_z": 0.3130568861961365
},
"calculations": {
"neg_displacement": -0.32070934772491455
},
"objective": 0.32070934772491455
},
{
"trial_number": 18,
"design_variables": {
"tip_thickness": 21.536592042850017,
"support_angle": 32.171364735552
},
"results": {
"max_displacement": 0.29555052518844604,
"max_disp_node": 58.0,
"max_disp_x": 0.0025494550354778767,
"max_disp_y": 0.06503863632678986,
"max_disp_z": 0.2883055508136749
},
"calculations": {
"neg_displacement": -0.29555052518844604
},
"objective": 0.29555052518844604
},
{
"trial_number": 19,
"design_variables": {
"tip_thickness": 23.75885172872223,
"support_angle": 28.17043178772967
},
"results": {
"max_displacement": 0.2622140347957611,
"max_disp_node": 58.0,
"max_disp_x": 0.002298196544870734,
"max_disp_y": 0.05939820408821106,
"max_disp_z": 0.25539782643318176
},
"calculations": {
"neg_displacement": -0.2622140347957611
},
"objective": 0.2622140347957611
},
{
"trial_number": 20,
"design_variables": {
"tip_thickness": 24.946257551293495,
"support_angle": 36.54595394544202
},
"results": {
"max_displacement": 0.20071247220039368,
"max_disp_node": 58.0,
"max_disp_x": 0.0018801360856741667,
"max_disp_y": 0.05026965215802193,
"max_disp_z": 0.1943153589963913
},
"calculations": {
"neg_displacement": -0.20071247220039368
},
"objective": 0.20071247220039368
}
]

View File

@@ -0,0 +1,11 @@
{
"best_params": {
"tip_thickness": 24.946257551293495,
"support_angle": 36.54595394544202
},
"best_value": 0.20071247220039368,
"best_trial_number": 20,
"timestamp": "2025-11-16T21:21:37.211289",
"study_name": "coarse_exploration",
"n_trials": 20
}

View File

@@ -0,0 +1,36 @@
{
"substudy_name": "fine_tuning",
"description": "Fine-grained optimization with 50 trials in narrow bounds around best design from coarse exploration",
"parent_study": "bracket_displacement_maximizing",
"created_date": "2025-11-16",
"optimization": {
"algorithm": "TPE",
"direction": "minimize",
"n_trials": 50,
"n_startup_trials": 5,
"design_variables": [
{
"parameter": "tip_thickness",
"min": 18.0,
"max": 22.0,
"units": "mm",
"comment": "Narrowed from coarse_exploration results"
},
{
"parameter": "support_angle",
"min": 28.0,
"max": 35.0,
"units": "degrees",
"comment": "Narrowed from coarse_exploration results"
}
]
},
"continuation": {
"enabled": true,
"from_substudy": "coarse_exploration",
"inherit_best_params": true,
"comment": "Start from best design found in coarse exploration"
}
}