constraint_explorer =================== .. py:module:: constraint_explorer .. autoapi-nested-parse:: Constraint boundary exploration utilities for OpenMDAO systems. This module provides tools to automatically explore and visualize constraint boundaries in parameter space using adaptive sampling and refinement techniques. Functions --------- .. autoapisummary:: constraint_explorer.explore_constraint_boundary_2d constraint_explorer.trace_constraint_boundary_2d Module Contents --------------- .. py:function:: explore_constraint_boundary_2d(prob, param1, param2, constraint_name, param1_range, param2_range, initial_resolution = (20, 20), refinement_levels = 0, refinement_factor = 2, constraint_tolerance = 0.1, feasibility_threshold = 1.0) Explore 2D parameter space to find constraint boundary. Evaluates the constraint on a grid of parameter values to identify the boundary between feasible and infeasible regions. Optionally performs adaptive mesh refinement near the boundary for improved accuracy. :param prob: OpenMDAO Problem instance (must be set up). :type prob: :py:class:`om.Problem` :param param1: Name of first input parameter to vary. :type param1: :py:class:`str` :param param2: Name of second input parameter to vary. :type param2: :py:class:`str` :param constraint_name: Name of constraint output to evaluate. :type constraint_name: :py:class:`str` :param param1_range: (min, max) range for param1. :type param1_range: :py:class:`tuple` of :py:class:`float` :param param2_range: (min, max) range for param2. :type param2_range: :py:class:`tuple` of :py:class:`float` :param initial_resolution: (n1, n2) grid resolution for initial sampling. Default is (20, 20). :type initial_resolution: :py:class:`tuple` of :py:class:`int`, *optional* :param refinement_levels: Number of adaptive refinement iterations. Default is 0 (no refinement). :type refinement_levels: :py:class:`int`, *optional* :param refinement_factor: Grid subdivision factor near boundaries. Default is 2. :type refinement_factor: :py:class:`int`, *optional* :param constraint_tolerance: Distance from threshold to consider "near boundary". Default is 0.1. :type constraint_tolerance: :py:class:`float`, *optional* :param feasibility_threshold: Constraint value for feasibility (>= threshold is feasible). Default is 1.0. :type feasibility_threshold: :py:class:`float`, *optional* :returns: Dictionary containing: - 'param1_values': Array of param1 evaluation points - 'param2_values': Array of param2 evaluation points - 'constraint_values': Array of constraint values - 'feasible_mask': Boolean array (True where feasible) - 'boundary_points': List of (param1, param2) tuples near boundary - 'num_evaluations': Total number of system evaluations :rtype: :py:class:`dict` .. rubric:: Notes The function uses OpenMDAO's `prob.set_val()` and `prob.run_model()` to evaluate the system at each grid point. The constraint is considered feasible when its value is >= feasibility_threshold. For normalized OpenMDAO constraints, feasibility_threshold=1.0 means the constraint is satisfied. .. rubric:: Examples >>> prob = om.Problem() >>> # ... setup problem ... >>> result = explore_constraint_boundary_2d( ... prob, ... "frequency", ... "voltage", ... "hv_operating_window_satisfied", ... param1_range=(1e3, 1e6), ... param2_range=(1e3, 2e4), ... ) >>> print(f"Evaluated {result['num_evaluations']} points") .. py:function:: trace_constraint_boundary_2d(prob, param1, param2, constraint_name, start_point, step_size = 0.01, max_points = 100, constraint_tolerance = 0.001, feasibility_threshold = 1.0) Trace constraint boundary curve starting from a known boundary point. Uses a predictor-corrector method to follow the constraint boundary curve in parameter space. This is more efficient than grid sampling for smooth, well-defined boundaries. :param prob: OpenMDAO Problem instance (must be set up). :type prob: :py:class:`om.Problem` :param param1: Name of first input parameter. :type param1: :py:class:`str` :param param2: Name of second input parameter. :type param2: :py:class:`str` :param constraint_name: Name of constraint output to trace. :type constraint_name: :py:class:`str` :param start_point: (param1_val, param2_val) starting point on or near the boundary. :type start_point: :py:class:`tuple` of :py:class:`float` :param step_size: Arc length step size along curve. Default is 0.01 (relative to parameter ranges). :type step_size: :py:class:`float`, *optional* :param max_points: Maximum number of points to trace. Default is 100. :type max_points: :py:class:`int`, *optional* :param constraint_tolerance: How close to threshold to maintain (convergence criterion). Default is 1e-3. :type constraint_tolerance: :py:class:`float`, *optional* :param feasibility_threshold: Constraint value defining the boundary. Default is 1.0. :type feasibility_threshold: :py:class:`float`, *optional* :returns: Array of shape (n_points, 2) containing (param1, param2) boundary points. :rtype: :py:class:`np.ndarray` .. rubric:: Notes The algorithm: 1. Project start_point onto boundary if needed (solve constraint = threshold) 2. Compute constraint gradient via finite differences 3. Step along tangent direction (perpendicular to gradient) 4. Project back to boundary using Newton iteration 5. Repeat until domain boundary reached or max_points exceeded .. rubric:: Examples >>> prob = om.Problem() >>> # ... setup problem ... >>> boundary = trace_constraint_boundary_2d( ... prob, ... "frequency", ... "voltage", ... "hv_operating_window_satisfied", ... start_point=(10e3, 5000.0), ... )