# Path: openlego/utils/general_utils.py
# def str_to_valid_sys_name(string):
#     # type: (str) -> str
#     """Ensures a given string is a valid OpenMDAO system name."""
#     sys_name = re_sys_name_char.sub('', string)
#     while not re_sys_name_starts.match(sys_name):
#         sys_name = sys_name[1:]
#     return sys_name
# 
# def unscale_value(v, ref0, ref):
#     # TODO: add docstring
#     if isinstance(v, list):
#         v = np.array(v)
#     return v*(ref-ref0)+ref0
# 
# def scale_value(v, adder, scaler):
#     # TODO: add docstring
#     if adder is None:
#         adder = 0.
#     if scaler is None:
#         scaler = 1.
#     if isinstance(v, list):
#         v = np.array(v)
#     return (v + adder) * scaler
# 
# Path: openlego/utils/xml_utils.py
# def param_to_xpath(param):
#     # type: (str) -> str
#     """Convert an ``OpenMDAO`` parameter name to the corresponding XML XPath.
# 
#     This function is the inverse of `xpath_to_param()`.
# 
#     Parameters
#     ----------
#         param : str
#             Valid ``OpenMDAO`` parameter name.
# 
#     Returns
#     -------
#         str
#             Corresponding XML XPath.
#     """
#     xpath = param.replace(repl_emm, repl_emm_inv)
#     xpath = xpath.replace(repl_qtm, repl_qtm_inv)
#     xpath = xpath.replace(repl_str, repl_str_inv)
#     xpath = xpath.replace(repl_dot, repl_dot_inv)
#     xpath = re_ind_inv.sub(repl_ind_inv, xpath)
#     xpath = re_atr_inv.sub(repl_atr_inv, xpath)
#     return xpath


import copy
import os
import pickle
import numpy as np
import plotly
import plotly.graph_objs as go
from math import isnan as isnan
from typing import List
from openmdao.api import NonlinearBlockGS
from openmdao.core.analysis_error import AnalysisError
from openmdao.recorders.recording_iteration_stack import Recording
from openmdao.utils.general_utils import format_as_float_or_array
from openlego.utils.general_utils import str_to_valid_sys_name, unscale_value, scale_value
from openlego.utils.xml_utils import param_to_xpath
            attrbs_new['initial'] = np.array([unscaled((val_ub_new+val_lb_new) / 2.)])
        else:
            attrbs_new['initial'] = np.array([unscaled(val_opt)])
        attrbs_new['lower'], attrbs_new['ref0'] = unscaled(val_lb_new), unscaled(val_lb_new)
        attrbs_new['upper'], attrbs_new['ref'] = unscaled(val_ub_new), unscaled(val_ub_new)

        return attrbs_new

    def _apply_new_bounds(self, var_name, attrbs):
        # type: (str, dict) -> None
        """Apply new bounds on design variables

        Parameters
        ----------
            var_name : str
                Design variable name of which new bounds should be determined
            attrbs : dict
                Attributes of the design variable (ref0, ref, lower, upper, adder, scaler)
        """
        opt_prob = self.system_optimizer_prob
        opt_prob[var_name] = attrbs['initial']
        opt_prob.model.adjust_design_var(var_name,
                                         initial=attrbs['initial'],
                                         lower=attrbs['lower'], upper=attrbs['upper'],
                                         ref=attrbs['ref'], ref0=attrbs['ref0'])
        for doe_prob in self.system_doe_probs:
            for doe_des_var in doe_prob.model.design_vars.keys():
                # TODO: Performance could be drastically improved here by creating an
                # TODO: object with static design variable mappings
                if doe_prob.model.parameter_uids_are_related(param_to_xpath(var_name),

# Path: openlego/utils/general_utils.py
# def str_to_valid_sys_name(string):
#     # type: (str) -> str
#     """Ensures a given string is a valid OpenMDAO system name."""
#     sys_name = re_sys_name_char.sub('', string)
#     while not re_sys_name_starts.match(sys_name):
#         sys_name = sys_name[1:]
#     return sys_name
# 
# def unscale_value(v, ref0, ref):
#     # TODO: add docstring
#     if isinstance(v, list):
#         v = np.array(v)
#     return v*(ref-ref0)+ref0
# 
# def scale_value(v, adder, scaler):
#     # TODO: add docstring
#     if adder is None:
#         adder = 0.
#     if scaler is None:
#         scaler = 1.
#     if isinstance(v, list):
#         v = np.array(v)
#     return (v + adder) * scaler
# 
# Path: openlego/utils/xml_utils.py
# def param_to_xpath(param):
#     # type: (str) -> str
#     """Convert an ``OpenMDAO`` parameter name to the corresponding XML XPath.
# 
#     This function is the inverse of `xpath_to_param()`.
# 
#     Parameters
#     ----------
#         param : str
#             Valid ``OpenMDAO`` parameter name.
# 
#     Returns
#     -------
#         str
#             Corresponding XML XPath.
#     """
#     xpath = param.replace(repl_emm, repl_emm_inv)
#     xpath = xpath.replace(repl_qtm, repl_qtm_inv)
#     xpath = xpath.replace(repl_str, repl_str_inv)
#     xpath = xpath.replace(repl_dot, repl_dot_inv)
#     xpath = re_ind_inv.sub(repl_ind_inv, xpath)
#     xpath = re_atr_inv.sub(repl_atr_inv, xpath)
#     return xpath


# Path: openlego/core/b2k_solver.py
import copy
import os
import pickle
import numpy as np
import plotly
import plotly.graph_objs as go
from math import isnan as isnan
from typing import List
from openmdao.api import NonlinearBlockGS
from openmdao.core.analysis_error import AnalysisError
from openmdao.recorders.recording_iteration_stack import Recording
from openmdao.utils.general_utils import format_as_float_or_array
from openlego.utils.general_utils import str_to_valid_sys_name, unscale_value, scale_value
from openlego.utils.xml_utils import param_to_xpath

            attrbs_new['initial'] = np.array([unscaled((val_ub_new+val_lb_new) / 2.)])
        else:
            attrbs_new['initial'] = np.array([unscaled(val_opt)])
        attrbs_new['lower'], attrbs_new['ref0'] = unscaled(val_lb_new), unscaled(val_lb_new)
        attrbs_new['upper'], attrbs_new['ref'] = unscaled(val_ub_new), unscaled(val_ub_new)

        return attrbs_new

    def _apply_new_bounds(self, var_name, attrbs):
        # type: (str, dict) -> None
        """Apply new bounds on design variables

        Parameters
        ----------
            var_name : str
                Design variable name of which new bounds should be determined
            attrbs : dict
                Attributes of the design variable (ref0, ref, lower, upper, adder, scaler)
        """
        opt_prob = self.system_optimizer_prob
        opt_prob[var_name] = attrbs['initial']
        opt_prob.model.adjust_design_var(var_name,
                                         initial=attrbs['initial'],
                                         lower=attrbs['lower'], upper=attrbs['upper'],
                                         ref=attrbs['ref'], ref0=attrbs['ref0'])
        for doe_prob in self.system_doe_probs:
            for doe_des_var in doe_prob.model.design_vars.keys():
                # TODO: Performance could be drastically improved here by creating an
                # TODO: object with static design variable mappings
                if doe_prob.model.parameter_uids_are_related(param_to_xpath(var_name),

                                                             param_to_xpath(doe_des_var)):