CO Framework
Extracted documentation from src/mdotoolbox/frameworks/co.py.
Overview
Mathematical Formulation
System Level: min_{z_bar, x_bar, y_bar} f(z_bar, x_bar, y_bar) s.t. g_sys(z_bar, x_bar, y_bar) >= 0 J_i = 0 for all i (strict consistency)
Subsystem Level i:
min_{z_under_i, x_under_i} J_i(z_under_i, x_under_i; z_bar, x_bar_i, y_bar_i)
s.t. g_i(z_under_i, x_under_i, y_bar_coupled) >= 0
where J_i = ||z_bar - z_under_i||**2 + ||x_bar_i - x_under_i||**2 + ||y_bar_i - y_i(z_under_i, x_under_i)||**2
Key Components: - COSubsystem: Individual discipline (inherits from BaseSubsystem) - COSystem: System-level coordinator (inherits from BaseSystem) - CollaborativeOptimization: Main solver (inherits from BaseSolver)
For implementation details of the base bilevel structure, see: - BaseSubsystem: Common subsystem optimization logic - BaseSystem: Common system-level coordination - BaseSolver: Common iteration and budget management
Features: - Parallel subsystem optimization capability - Flexible budget management (system vs subsystem allocation) - Comprehensive iteration history tracking - Convergence based on coupling discrepancy epsilon
References: Braun, R. D., & Kroo, I. M. (1997). "Development and Application of the Collaborative Optimization Architecture in a Multidisciplinary Design Environment." In Multidisciplinary design optimization: State of the art.
COSubsystem
Attributes
problem: Problem Local subsystem optimization problem with objective and constraints z_idxs: ndarray Indices of shared design variables in the global variable vector x_idxs: ndarray Indices of local design variables in the global variable vector y_idxs: ndarray Indices of subsystem outputs in the global output vector y_bar_coupled_idxs: List[ndarray] List of index arrays for coupled variables (targets) from other subsystems z_under_i: ndarray Subsystem's copy of shared variables (optimized to match z_bar) x_under_i: ndarray Subsystem's local variables y_i: ndarray Actual subsystem outputs from discipline analysis best_J_i: float Best (lowest) discrepancy achieved best_h: float Best (lowest) constraint violation achieved iteration_history: List[dict] History of subsystem optimization iterations
Example: >>> from mdotoolbox.core import Problem, Function >>> # Define discipline problem >>> y_func = Function(func=lambda z, x: z**2 + x, x=['z', 'x'], name='disc1') >>> problem = Problem(objective=y_func, lbounds=[0, 0], ubounds=[10, 10]) >>> >>> # Create subsystem >>> subsystem = COSubsystem( ... problem=problem, ... z_idxs=[0], # First variable is shared ... x_idxs=[1], # Second variable is local ... y_idxs=[0], # First output ... y_bar_coupled_idxs=[] # No coupling ... )
COSystem
Attributes
problem: Problem System-level optimization problem with objective and constraints subsystems: List[COSubsystem] All subsystems in the MDO problem z_bar: ndarray Current shared design variables x_bar: ndarray System-level targets for local variables (concatenated from all subsystems) y_bar: ndarray System-level targets for coupling variables (concatenated from all subsystems) iteration_history: List[dict] System-level optimization iteration metrics best_J_total: float Best total discrepancy (sum of all J_i) best_h_total: float Best system constraint violation best_f_bar: float Best system objective value
Workflow: 1. Receive discrepancies J_i from subsystems 2. Optimize system objective subject to J_i = 0 and system constraints 3. Return updated targets (z_bar, x_bar, y_bar) to subsystems 4. Repeat until convergence
Example: >>> system = COSystem( ... problem=system_problem, ... subsystems=[subsystem1, subsystem2] ... ) >>> # System solves for optimal targets >>> z_bar, x_bar, y_bar, f, h, n_evals = system.solve( ... optimizer='cobyqa', ... system_iter=1, ... global_start_time=time.time() ... )
CollaborativeOptimization
Attributes
system: COSystem System-level coordinator with subsystems subsystem_optimizer: str or Callable Optimizer for subsystem minimization (e.g., 'cobyqa', 'cobyla') system_optimizer: str or Callable Optimizer for system-level coordination epsilon_J: float, optional Convergence tolerance for coupling discrepancy J_total (default: 1e-6) epsilon_h: float, optional Convergence tolerance for constraint violation h_total (default: 1e-6) budget: BudgetManager or int, optional Budget allocation strategy. If int, creates weighted budget manager. (default: 100) max_iter: int or None, optional Maximum number of CO iterations. None for unlimited. (default: None)
Budget Management: Three modes available via BudgetManager:
1. Weighted (recommended):
- Distributes total_budget proportionally
- system_ratio: fraction for system level
- subsystem_weights: relative allocation per subsystem
- iteration_ratio: min budget per iteration
2. Fixed:
- Explicit budgets for each subsystem and system
- system_budget: evaluations for system
- subsystem_budgets: list of budgets per subsystem
3. Shared:
- Single pool shared by all levels
- First-come, first-served allocation
Examples
Basic usage with integer budget
>>> solver = CollaborativeOptimization( ... system=co_system, ... subsystem_optimizer='cobyqa', ... system_optimizer='cobyqa', ... epsilon_J=1e-6, ... epsilon_h=1e-6, ... budget=400 ... ) >>> >>> # Weighted budget allocation >>> budget = BudgetManager( ... mode='weighted', ... total_budget=500, ... system_ratio=0.4, ... subsystem_weights=[0.6, 0.4], # 60% to subsys 1, 40% to subsys 2 ... iteration_ratio=0.05 ... ) >>> solver = CollaborativeOptimization( ... system=co_system, ... subsystem_optimizer='cobyla', ... system_optimizer='slsqp', ... budget=budget ... ) >>> >>> # Solve the problem >>> z_bar0 = np.array([1.0, 2.0]) >>> x_bar0 = np.array([0.5]) >>> y_bar0 = np.array([1.0, 1.0]) >>> z_under0 = np.array([1.0, 2.0]) >>> x_under0 = np.array([0.5]) >>> result = solver.solve(z_bar0, x_bar0, y_bar0, z_under0, x_under0) >>> >>> print(f"Optimal objective: {result.best.f_bar}") >>> print(f"Final discrepancy: {result.best.J_total}")
Notes
- Convergence requires all J_i <= epsilon_J AND feasibility (h_total <= epsilon_h)
- System targets (z_bar, x_bar, y_bar) updated each iteration
- Subsystems optimize in parallel conceptually
- Budget exhaustion triggers early termination