91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
|
|
"""
|
||
|
|
Safety Factor Constraint Hook - Manual Implementation
|
||
|
|
|
||
|
|
This hook enforces a minimum safety factor constraint on stress.
|
||
|
|
If safety_factor < minimum required, the objective is heavily penalized.
|
||
|
|
|
||
|
|
Safety Factor = Yield Strength / Max Stress
|
||
|
|
|
||
|
|
For Aluminum 6061-T6:
|
||
|
|
- Yield Strength: 276 MPa
|
||
|
|
- Required Safety Factor: 4.0
|
||
|
|
- Allowable Stress: 69 MPa
|
||
|
|
|
||
|
|
Author: Atomizer Development Team
|
||
|
|
Version: 1.0
|
||
|
|
"""
|
||
|
|
|
||
|
|
from optimization_engine.plugins.hooks import Hook, HookPoint
|
||
|
|
|
||
|
|
|
||
|
|
def safety_factor_constraint_hook(context: dict) -> dict:
|
||
|
|
"""
|
||
|
|
Enforce safety factor constraint on optimization.
|
||
|
|
|
||
|
|
This hook checks if the calculated safety factor meets the minimum requirement.
|
||
|
|
If violated, it adds a large penalty to the objective to guide optimization
|
||
|
|
away from unsafe designs.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
context: Dict containing:
|
||
|
|
- calculations: Dict with 'safety_factor' value
|
||
|
|
- results: Dict with stress results
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Dict with:
|
||
|
|
- safety_factor_satisfied: bool
|
||
|
|
- safety_factor_violation: float (0 if satisfied, penalty otherwise)
|
||
|
|
- constrained_objective: float (original or penalized objective)
|
||
|
|
"""
|
||
|
|
calculations = context.get('calculations', {})
|
||
|
|
|
||
|
|
# Get safety factor from calculations
|
||
|
|
safety_factor = calculations.get('safety_factor', 0.0)
|
||
|
|
|
||
|
|
# Get objective (negative displacement to maximize)
|
||
|
|
neg_displacement = calculations.get('neg_displacement', 0.0)
|
||
|
|
|
||
|
|
# Required minimum safety factor
|
||
|
|
min_safety_factor = 4.0
|
||
|
|
|
||
|
|
# Check constraint
|
||
|
|
satisfied = safety_factor >= min_safety_factor
|
||
|
|
|
||
|
|
# Calculate violation (how much we're under the limit)
|
||
|
|
violation = max(0.0, min_safety_factor - safety_factor)
|
||
|
|
|
||
|
|
# Apply penalty if constraint violated
|
||
|
|
if not satisfied:
|
||
|
|
# Heavy penalty: add large value to objective (we're minimizing)
|
||
|
|
# Penalty scales with violation severity
|
||
|
|
penalty = 1000.0 * violation
|
||
|
|
constrained_objective = neg_displacement + penalty
|
||
|
|
|
||
|
|
print(f" [CONSTRAINT VIOLATED] Safety factor {safety_factor:.2f} < {min_safety_factor}")
|
||
|
|
print(f" [PENALTY APPLIED] Adding {penalty:.2f} to objective")
|
||
|
|
else:
|
||
|
|
constrained_objective = neg_displacement
|
||
|
|
print(f" [CONSTRAINT SATISFIED] Safety factor {safety_factor:.2f} >= {min_safety_factor}")
|
||
|
|
|
||
|
|
return {
|
||
|
|
'safety_factor_satisfied': satisfied,
|
||
|
|
'safety_factor_violation': violation,
|
||
|
|
'constrained_objective': constrained_objective,
|
||
|
|
'objective': constrained_objective # This becomes the final objective
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
# Register hook with plugin system
|
||
|
|
hook = Hook(
|
||
|
|
name="safety_factor_constraint",
|
||
|
|
hook_point=HookPoint.POST_CALCULATION,
|
||
|
|
function=safety_factor_constraint_hook,
|
||
|
|
enabled=True,
|
||
|
|
description="Enforce minimum safety factor constraint with penalty"
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
def register_hooks(hook_manager):
|
||
|
|
"""Register hooks with the plugin system."""
|
||
|
|
return [hook]
|