def push_mda(self, problem, options):
        name = problem.model.__class__.__name__
        data = _get_viewer_data(problem)
        #print(name, data)
        self.scalar_format = options['--scalar-format']
        self.tree = data['tree']
        #print("TREE("+name+")=", self.tree)
        self.connections = data['connections_list']
        #print("CONNECTIONS("+name+")=", self.connections)

        # MDA informations
        self.vars = {}
        self.vardescs = {}
        self.discmap = {}
        self._collect_disc_infos(problem.model, self.tree)
        self._collect_var_infos(problem.model)
        mda_attrs = self._get_mda_attributes(problem.model, self.tree)

        if options['--dry-run']:
            print(json.dumps(mda_attrs, indent=2))
            # print(self.discmap)
        else:
            url =  self._endpoint('/api/v1/analyses')
            resp = self.session.post(url, headers=self.headers, json={'analysis': mda_attrs})
            resp.raise_for_status()
            print("Analysis %s pushed" % name)
Example #2
0
def record_viewer_data(problem):
    """
    Record model viewer data for all recorders that have that option enabled.

    We don't want to collect the viewer data if it's not needed though,
    so first we'll find all recorders that need the data (if any) and
    then record it for those recorders.

    Parameters
    ----------
    problem : Problem
        The problem for which model viewer data is to be recorded.
    """
    # assemble list of all objects that may have recorders
    systems = [system for system in problem.model.system_iter(include_self=True, recurse=True)]
    nl_solv = [system._nonlinear_solver for system in systems if system._nonlinear_solver]
    ls_solv = [nl.linesearch for nl in nl_solv if hasattr(nl, 'linesearch') and nl.linesearch]
    rec_obj = [problem, problem.driver] + systems + nl_solv + ls_solv

    # get all recorders that need to record the viewer data
    recorders = set()
    for obj in rec_obj:
        for recorder in obj._rec_mgr._recorders:
            if recorder._record_viewer_data:
                recorders.add(recorder)

    # if any recorders were found, get the viewer data and record it
    if recorders:
        from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
        viewer_data = _get_viewer_data(problem)
        for recorder in recorders:
            recorder.record_viewer_data(viewer_data)
Example #3
0
    def test_model_viewer_has_correct_data_from_problem(self):
        """
        Verify that the correct model structure data exists when stored as compared
        to the expected structure, using the SellarStateConnection model.
        """
        p = Problem(model=SellarStateConnection())
        p.setup(check=False)

        model_viewer_data = _get_viewer_data(p)

        # check expected model tree
        self.assertDictEqual(model_viewer_data['tree'], self.expected_tree)

        # check expected system pathnames
        pathnames = model_viewer_data['sys_pathnames_list']
        self.assertListEqual(sorted(pathnames), self.expected_pathnames)

        # check expected connections, after mapping cycle_arrows indices back to pathnames
        connections = model_viewer_data['connections_list']
        for conn in connections:
            if 'cycle_arrows' in conn:
                cycle_arrows = []
                for src, tgt in conn['cycle_arrows']:
                    cycle_arrows.append(' '.join([pathnames[src], pathnames[tgt]]))
                conn['cycle_arrows'] = sorted(cycle_arrows)
        self.assertListEqual(connections, self.expected_conns)

        # check expected abs2prom map
        self.assertDictEqual(model_viewer_data['abs2prom'], self.expected_abs2prom)
Example #4
0
    def test_model_viewer_has_correct_data_from_problem(self):
        """
        Verify that the correct model structure data exists when stored as compared
        to the expected structure, using the SellarStateConnection model.
        """
        p = Problem(model=SellarStateConnection())
        p.setup(check=False)

        model_viewer_data = _get_viewer_data(p)

        # check expected model tree
        self.assertDictEqual(model_viewer_data['tree'], self.expected_tree)

        # check expected system pathnames
        pathnames = model_viewer_data['sys_pathnames_list']
        self.assertListEqual(sorted(pathnames), self.expected_pathnames)

        # check expected connections, after mapping cycle_arrows indices back to pathnames
        connections = model_viewer_data['connections_list']
        for conn in connections:
            if 'cycle_arrows' in conn:
                cycle_arrows = []
                for src, tgt in conn['cycle_arrows']:
                    cycle_arrows.append(' '.join(
                        [pathnames[src], pathnames[tgt]]))
                conn['cycle_arrows'] = sorted(cycle_arrows)
        self.assertListEqual(connections, self.expected_conns)

        # check expected abs2prom map
        self.assertDictEqual(model_viewer_data['abs2prom'],
                             self.expected_abs2prom)
Example #5
0
 def __init__(self, problem, scalar_format):
     data = _get_viewer_data(problem)
     self.problem = problem
     self.scalar_format = scalar_format
     self.tree = data["tree"]
     self.connections = data["connections_list"]
     self.vars = {}
     self.vardescs = {}
     self.discmap = {}
Example #6
0
    def test_model_viewer_has_correct_data_from_problem(self):
        """
        Verify that the correct model structure data exists when stored as compared
        to the expected structure, using the SellarStateConnection model.
        """
        p = Problem()
        p.model = SellarStateConnection()
        p.setup(check=False)
        model_viewer_data = _get_viewer_data(p)
        tree_json = json.dumps(model_viewer_data['tree'])
        conns_json = json.dumps(model_viewer_data['connections_list'])

        self.assertEqual(self.expected_tree_json, tree_json)
        self.assertEqual(self.expected_conns_json, conns_json)
Example #7
0
    def test_model_viewer_has_correct_data_from_problem(self):
        """
        Verify that the correct model structure data exists when stored as compared
        to the expected structure, using the SellarStateConnection model.
        """
        p = Problem()
        p.model = SellarStateConnection()
        p.setup(check=False)
        model_viewer_data = _get_viewer_data(p)
        tree_json = json.dumps(model_viewer_data['tree'])
        conns_json = json.dumps(model_viewer_data['connections_list'])

        self.assertEqual(self.expected_tree_json, tree_json)
        self.assertEqual(self.expected_conns_json, conns_json)
Example #8
0
    def test_model_viewer_has_correct_data_from_problem(self):
        """
        Verify that the correct model structure data exists when stored as compared
        to the expected structure, using the SellarStateConnection model.
        """
        p = Problem()
        p.model = SellarStateConnection()
        p.setup(check=False)
        model_viewer_data = _get_viewer_data(p)

        self.assertDictEqual(model_viewer_data['tree'], self.expected_tree)
        self.assertListEqual(model_viewer_data['connections_list'],
                             self.expected_conns)
        self.assertDictEqual(model_viewer_data['abs2prom'],
                             self.expected_abs2prom)
Example #9
0
    def test_model_viewer_has_correct_data_from_sqlite(self):
        """
        Verify that the correct data exists when a model structure is recorded
        and then pulled out of a sqlite db file and compared to the expected
        structure.  Uses the SellarStateConnection model.
        """
        p = Problem(model=SellarStateConnection())

        r = SqliteRecorder(self.sqlite_db_filename)
        p.driver.add_recorder(r)

        p.setup()
        p.final_setup()
        r.shutdown()

        model_viewer_data = _get_viewer_data(self.sqlite_db_filename)

        # check expected model tree
        self.assertDictEqual(model_viewer_data['tree'], self.expected_tree)

        # check expected system pathnames
        pathnames = model_viewer_data['sys_pathnames_list']
        self.assertListEqual(sorted(pathnames), self.expected_pathnames)

        # check expected connections, after mapping cycle_arrows indices back to pathnames
        connections = sorted(model_viewer_data['connections_list'],
                             key=lambda x: (x['tgt'], x['src']))
        for conn in connections:
            if 'cycle_arrows' in conn:
                cycle_arrows = []
                for src, tgt in conn['cycle_arrows']:
                    cycle_arrows.append(' '.join(
                        [pathnames[src], pathnames[tgt]]))
                conn['cycle_arrows'] = sorted(cycle_arrows)
        self.assertEqual(len(connections), len(self.expected_conns))
        for c, ex in zip(connections, self.expected_conns):
            self.assertEqual(c['src'], ex['src'])
            self.assertEqual(c['tgt'], ex['tgt'])
            self.assertEqual(c.get('cycle_arrows', []),
                             ex.get('cycle_arrows', []))

        # check expected abs2prom map
        self.assertDictEqual(model_viewer_data['abs2prom'],
                             self.expected_abs2prom)
Example #10
0
    def test_model_viewer_has_correct_data_from_sqlite(self):
        """
        Verify that the correct data exists when a model structure is recorded
        and then pulled out of a sqlite db file and compared to the expected
        structure.  Uses the SellarStateConnection model.
        """
        p = Problem()
        p.model = SellarStateConnection()
        r = SqliteRecorder(self.sqlite_db_filename)
        p.driver.add_recorder(r)
        p.setup(check=False)
        p.final_setup()
        r.close()

        model_viewer_data = _get_viewer_data(self.sqlite_db_filename)
        tree_json = json.dumps(model_viewer_data['tree'])
        conns_json = json.dumps(model_viewer_data['connections_list'])

        self.assertEqual(self.expected_tree_json, tree_json)
        self.assertEqual(self.expected_conns_json, conns_json)
Example #11
0
    def test_model_viewer_has_correct_data_from_sqlite(self):
        """
        Verify that the correct data exists when a model structure is recorded
        and then pulled out of a sqlite db file and compared to the expected
        structure.  Uses the SellarStateConnection model.
        """
        p = Problem()
        p.model = SellarStateConnection()
        r = SqliteRecorder(self.sqlite_db_filename)
        p.driver.add_recorder(r)
        p.setup(check=False)
        p.final_setup()
        r.close()

        model_viewer_data = _get_viewer_data(self.sqlite_db_filename)
        tree_json = json.dumps(model_viewer_data['tree'])
        conns_json = json.dumps(model_viewer_data['connections_list'])

        self.assertEqual(self.expected_tree_json, tree_json)
        self.assertEqual(self.expected_conns_json, conns_json)
Example #12
0
def record_viewer_data(problem):
    """
    Record model viewer data for all recorders that have that option enabled.

    We don't want to collect the viewer data if it's not needed though,
    so first we'll find all recorders that need the data (if any) and
    then record it for those recorders.

    Parameters
    ----------
    problem : Problem
        The problem for which model viewer data is to be recorded.
    """
    # assemble list of all objects that may have recorders
    systems = [
        system for system in problem.model.system_iter(include_self=True,
                                                       recurse=True)
    ]
    nl_solv = [
        system._nonlinear_solver for system in systems
        if system._nonlinear_solver
    ]
    ls_solv = [
        nl.linesearch for nl in nl_solv
        if hasattr(nl, 'linesearch') and nl.linesearch
    ]
    rec_obj = [problem, problem.driver] + systems + nl_solv + ls_solv

    # get all recorders that need to record the viewer data
    recorders = set()
    for obj in rec_obj:
        for recorder in obj._rec_mgr._recorders:
            if recorder._record_viewer_data:
                recorders.add(recorder)

    # if any recorders were found, get the viewer data and record it
    if recorders:
        from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
        viewer_data = _get_viewer_data(problem)
        for recorder in recorders:
            recorder.record_viewer_data(viewer_data)
Example #13
0
    def test_model_viewer_has_correct_data_from_sqlite(self):
        """
        Verify that the correct data exists when a model structure is recorded
        and then pulled out of a sqlite db file and compared to the expected
        structure.  Uses the SellarStateConnection model.
        """
        p = Problem(model=SellarStateConnection())

        r = SqliteRecorder(self.sqlite_db_filename)
        p.driver.add_recorder(r)

        p.setup(check=False)
        p.final_setup()
        r.shutdown()

        model_viewer_data = _get_viewer_data(self.sqlite_db_filename)

        # check expected model tree
        self.assertDictEqual(model_viewer_data['tree'], self.expected_tree)

        # check expected system pathnames
        pathnames = model_viewer_data['sys_pathnames_list']
        self.assertListEqual(sorted(pathnames), self.expected_pathnames)

        # check expected connections, after mapping cycle_arrows indices back to pathnames
        connections = model_viewer_data['connections_list']
        for conn in connections:
            if 'cycle_arrows' in conn:
                cycle_arrows = []
                for src, tgt in conn['cycle_arrows']:
                    cycle_arrows.append(' '.join([pathnames[src], pathnames[tgt]]))
                conn['cycle_arrows'] = sorted(cycle_arrows)
        self.assertListEqual(connections, self.expected_conns)

        # check expected abs2prom map
        self.assertDictEqual(model_viewer_data['abs2prom'], self.expected_abs2prom)
Example #14
0
    def _setup_driver(self, problem):
        """
        Prepare the driver for execution.

        This is the final thing to run during setup.

        Parameters
        ----------
        problem : <Problem>
            Pointer to the containing problem.
        """
        self._problem = problem
        model = problem.model

        self._total_jac = None
        self._objs = objs = OrderedDict()
        self._cons = cons = OrderedDict()
        self._responses = model.get_responses(recurse=True)
        response_size = 0
        for name, data in iteritems(self._responses):
            if data['type'] == 'con':
                cons[name] = data
            else:
                objs[name] = data
            response_size += data['size']

        # Gather up the information for design vars.
        self._designvars = model.get_design_vars(recurse=True)
        self._has_scaling = (
            np.any([r['scaler'] is not None for r in self._responses.values()]) or
            np.any([dv['scaler'] is not None for dv in self._designvars.values()])
        )

        con_set = set()
        obj_set = set()
        dv_set = set()

        self._remote_dvs = dv_dict = {}
        self._remote_cons = con_dict = {}
        self._remote_objs = obj_dict = {}

        # Now determine if later we'll need to allgather cons, objs, or desvars.
        if model.comm.size > 1 and model._subsystems_allprocs:
            local_out_vars = set(model._outputs._views)
            remote_dvs = set(self._designvars) - local_out_vars
            remote_cons = set(self._cons) - local_out_vars
            remote_objs = set(self._objs) - local_out_vars
            all_remote_vois = model.comm.allgather(
                (remote_dvs, remote_cons, remote_objs))
            for rem_dvs, rem_cons, rem_objs in all_remote_vois:
                con_set.update(rem_cons)
                obj_set.update(rem_objs)
                dv_set.update(rem_dvs)

            # If we have remote VOIs, pick an owning rank for each and use that
            # to bcast to others later
            owning_ranks = model._owning_rank
            sizes = model._var_sizes['nonlinear']['output']
            for i, vname in enumerate(model._var_allprocs_abs_names['output']):
                owner = owning_ranks[vname]
                if vname in dv_set:
                    dv_dict[vname] = (owner, sizes[owner, i])
                if vname in con_set:
                    con_dict[vname] = (owner, sizes[owner, i])
                if vname in obj_set:
                    obj_dict[vname] = (owner, sizes[owner, i])

        self._remote_responses = self._remote_cons.copy()
        self._remote_responses.update(self._remote_objs)

        # Case recording setup
        mydesvars = myobjectives = myconstraints = myresponses = set()
        mysystem_outputs = set()
        incl = self.recording_options['includes']
        excl = self.recording_options['excludes']
        rec_desvars = self.recording_options['record_desvars']
        rec_objectives = self.recording_options['record_objectives']
        rec_constraints = self.recording_options['record_constraints']
        rec_responses = self.recording_options['record_responses']

        all_desvars = {n for n in self._designvars
                       if check_path(n, incl, excl, True)}
        all_objectives = {n for n in self._objs
                          if check_path(n, incl, excl, True)}
        all_constraints = {n for n in self._cons
                           if check_path(n, incl, excl, True)}
        if rec_desvars:
            mydesvars = all_desvars

        if rec_objectives:
            myobjectives = all_objectives

        if rec_constraints:
            myconstraints = all_constraints

        if rec_responses:
            myresponses = {n for n in self._responses
                           if check_path(n, incl, excl, True)}

        # get the includes that were requested for this Driver recording
        if incl:
            prob = self._problem
            root = prob.model
            # The my* variables are sets

            # First gather all of the desired outputs
            # The following might only be the local vars if MPI
            mysystem_outputs = {n for n in root._outputs
                                if check_path(n, incl, excl)}

            # If MPI, and on rank 0, need to gather up all the variables
            #    even those not local to rank 0
            if MPI:
                all_vars = root.comm.gather(mysystem_outputs, root=0)
                if MPI.COMM_WORLD.rank == 0:
                    mysystem_outputs = all_vars[-1]
                    for d in all_vars[:-1]:
                        mysystem_outputs.update(d)

            # de-duplicate mysystem_outputs
            mysystem_outputs = mysystem_outputs.difference(all_desvars, all_objectives,
                                                           all_constraints)

        if MPI:  # filter based on who owns the variables
            # TODO Eventually, we think we can get rid of this next check. But to be safe,
            #       we are leaving it in there.
            if not model.is_active():
                raise RuntimeError(
                    "RecordingManager.startup should never be called when "
                    "running in parallel on an inactive System")
            rrank = self._problem.comm.rank  # root ( aka model ) rank.
            rowned = model._owning_rank
            mydesvars = [n for n in mydesvars if rrank == rowned[n]]
            myresponses = [n for n in myresponses if rrank == rowned[n]]
            myobjectives = [n for n in myobjectives if rrank == rowned[n]]
            myconstraints = [n for n in myconstraints if rrank == rowned[n]]
            mysystem_outputs = [n for n in mysystem_outputs if rrank == rowned[n]]

        self._filtered_vars_to_record = {
            'des': mydesvars,
            'obj': myobjectives,
            'con': myconstraints,
            'res': myresponses,
            'sys': mysystem_outputs,
        }

        self._rec_mgr.startup(self)
        if self._rec_mgr._recorders:
            from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
            self._model_viewer_data = _get_viewer_data(problem)
        if self.recording_options['record_metadata']:
            self._rec_mgr.record_metadata(self)

        # set up simultaneous deriv coloring
        if (coloring_mod._use_sparsity and self._simul_coloring_info and
                self.supports['simultaneous_derivatives']):
            if problem._mode == 'fwd':
                self._setup_simul_coloring(problem._mode)
            else:
                raise RuntimeError("simultaneous derivs are currently not supported in rev mode.")

        desvar_size = np.sum(data['size'] for data in itervalues(self._designvars))

        # if we're using simultaneous derivatives then our effective design var size is less
        # than the full design var size
        if self._simul_coloring_info:
            col_lists = self._simul_coloring_info[0]
            if col_lists:
                desvar_size = len(col_lists[0])
                desvar_size += len(col_lists) - 1

        if ((problem._mode == 'fwd' and desvar_size > response_size) or
                (problem._mode == 'rev' and response_size > desvar_size)):
            warnings.warn("Inefficient choice of derivative mode.  You chose '%s' for a "
                          "problem with %d design variables and %d response variables "
                          "(objectives and constraints)." %
                          (problem._mode, desvar_size, response_size), RuntimeWarning)
Example #15
0
    def test_obj_pass(self):
        prob = Problem()
        model = prob.model

        indep = model.add_subsystem('indep', IndepVarComp(), promotes_outputs=['x'])
        indep.add_discrete_output('x', _DiscreteVal(19))

        G = model.add_subsystem('G', ParallelGroup(), promotes_inputs=['x'])

        G1 = G.add_subsystem('G1', Group(), promotes_inputs=['x'], promotes_outputs=['y'])
        G1.add_subsystem('C1_1', ObjAdderCompEx(_DiscreteVal(5)), promotes_inputs=['x'])
        G1.add_subsystem('C1_2', ObjAdderCompEx(_DiscreteVal(7)), promotes_outputs=['y'])
        G1.connect('C1_1.y', 'C1_2.x')

        G2 = G.add_subsystem('G2', Group(), promotes_inputs=['x'])
        G2.add_subsystem('C2_1', ObjAdderCompEx(_DiscreteVal(1)), promotes_inputs=['x'])
        G2.add_subsystem('C2_2', ObjAdderCompEx(_DiscreteVal(11)), promotes_outputs=['y'])
        G2.connect('C2_1.y', 'C2_2.x')

        model.add_subsystem('C3', ObjAdderCompEx(_DiscreteVal(9)))
        model.add_subsystem('C4', ObjAdderCompEx(_DiscreteVal(21)))

        model.connect('G.y', 'C3.x')
        model.connect('G.G2.y', 'C4.x')

        prob.setup()
        prob.run_model()

        self.assertEqual(prob['C3.y'].getval(), 40)
        self.assertEqual(prob['C4.y'].getval(), 52)

        def _var_iter(obj):
            name = obj['name']
            if 'children' in obj:
                for c in obj['children']:
                    for vname in _var_iter(c):
                        if name:
                            yield '.'.join((name, vname))
                        else:
                            yield vname
            else:
                yield name

        # add a test to see if discrete vars show up in view_model
        data = _get_viewer_data(prob)
        findvars = [
            'indep.x',
            'G.G1.C1_1.x',
            'G.G1.C1_1.y',
            'G.G1.C1_2.x',
            'G.G1.C1_2.y',
            'G.G2.C2_1.x',
            'G.G2.C2_1.y',
            'G.G2.C2_2.x',
            'G.G2.C2_2.y',
            'C3.x',
            'C3.y',
            'C4.x',
            'C4.y',
        ]
        vnames = list(_var_iter(data['tree']))
        self.assertTrue(sorted(findvars), sorted(vnames))
Example #16
0
    def _setup_driver(self, problem):
        """
        Prepare the driver for execution.

        This is the final thing to run during setup.

        Parameters
        ----------
        problem : <Problem>
            Pointer to the containing problem.
        """
        self._problem = problem
        model = problem.model

        self._objs = objs = OrderedDict()
        self._cons = cons = OrderedDict()
        self._responses = model.get_responses(recurse=True)
        response_size = 0
        for name, data in iteritems(self._responses):
            if data['type'] == 'con':
                cons[name] = data
            else:
                objs[name] = data
            response_size += data['size']

        # Gather up the information for design vars.
        self._designvars = model.get_design_vars(recurse=True)
        desvar_size = np.sum(data['size'] for data in itervalues(self._designvars))

        if ((problem._mode == 'fwd' and desvar_size > response_size) or
                (problem._mode == 'rev' and response_size > desvar_size)):
            warnings.warn("Inefficient choice of derivative mode.  You chose '%s' for a "
                          "problem with %d design variables and %d response variables "
                          "(objectives and constraints)." %
                          (problem._mode, desvar_size, response_size), RuntimeWarning)

        self._has_scaling = (
            np.any([r['scaler'] is not None for r in self._responses.values()]) or
            np.any([dv['scaler'] is not None for dv in self._designvars.values()])
        )

        con_set = set()
        obj_set = set()
        dv_set = set()

        self._remote_dvs = dv_dict = {}
        self._remote_cons = con_dict = {}
        self._remote_objs = obj_dict = {}

        # Now determine if later we'll need to allgather cons, objs, or desvars.
        if model.comm.size > 1 and model._subsystems_allprocs:
            local_out_vars = set(model._outputs._views)
            remote_dvs = set(self._designvars) - local_out_vars
            remote_cons = set(self._cons) - local_out_vars
            remote_objs = set(self._objs) - local_out_vars
            all_remote_vois = model.comm.allgather(
                (remote_dvs, remote_cons, remote_objs))
            for rem_dvs, rem_cons, rem_objs in all_remote_vois:
                con_set.update(rem_cons)
                obj_set.update(rem_objs)
                dv_set.update(rem_dvs)

            # If we have remote VOIs, pick an owning rank for each and use that
            # to bcast to others later
            owning_ranks = model._owning_rank['output']
            sizes = model._var_sizes['nonlinear']['output']
            for i, vname in enumerate(model._var_allprocs_abs_names['output']):
                owner = owning_ranks[vname]
                if vname in dv_set:
                    dv_dict[vname] = (owner, sizes[owner, i])
                if vname in con_set:
                    con_dict[vname] = (owner, sizes[owner, i])
                if vname in obj_set:
                    obj_dict[vname] = (owner, sizes[owner, i])

        self._remote_responses = self._remote_cons.copy()
        self._remote_responses.update(self._remote_objs)

        # Case recording setup
        mydesvars = myobjectives = myconstraints = myresponses = set()
        mysystem_outputs = set()
        incl = self.recording_options['includes']
        excl = self.recording_options['excludes']
        rec_desvars = self.recording_options['record_desvars']
        rec_objectives = self.recording_options['record_objectives']
        rec_constraints = self.recording_options['record_constraints']
        rec_responses = self.recording_options['record_responses']

        all_desvars = {n for n in self._designvars
                       if check_path(n, incl, excl, True)}
        all_objectives = {n for n in self._objs
                          if check_path(n, incl, excl, True)}
        all_constraints = {n for n in self._cons
                           if check_path(n, incl, excl, True)}
        if rec_desvars:
            mydesvars = all_desvars

        if rec_objectives:
            myobjectives = all_objectives

        if rec_constraints:
            myconstraints = all_constraints

        if rec_responses:
            myresponses = {n for n in self._responses
                           if check_path(n, incl, excl, True)}

        # get the includes that were requested for this Driver recording
        if incl:
            prob = self._problem
            root = prob.model
            # The my* variables are sets

            # First gather all of the desired outputs
            # The following might only be the local vars if MPI
            mysystem_outputs = {n for n in root._outputs
                                if check_path(n, incl, excl)}

            # If MPI, and on rank 0, need to gather up all the variables
            #    even those not local to rank 0
            if MPI:
                all_vars = root.comm.gather(mysystem_outputs, root=0)
                if MPI.COMM_WORLD.rank == 0:
                    mysystem_outputs = all_vars[-1]
                    for d in all_vars[:-1]:
                        mysystem_outputs.update(d)

            # de-duplicate mysystem_outputs
            mysystem_outputs = mysystem_outputs.difference(all_desvars, all_objectives,
                                                           all_constraints)

        if MPI:  # filter based on who owns the variables
            # TODO Eventually, we think we can get rid of this next check. But to be safe,
            #       we are leaving it in there.
            if not model.is_active():
                raise RuntimeError(
                    "RecordingManager.startup should never be called when "
                    "running in parallel on an inactive System")
            rrank = self._problem.comm.rank  # root ( aka model ) rank.
            rowned = model._owning_rank['output']
            mydesvars = [n for n in mydesvars if rrank == rowned[n]]
            myresponses = [n for n in myresponses if rrank == rowned[n]]
            myobjectives = [n for n in myobjectives if rrank == rowned[n]]
            myconstraints = [n for n in myconstraints if rrank == rowned[n]]
            mysystem_outputs = [n for n in mysystem_outputs if rrank == rowned[n]]

        self._filtered_vars_to_record = {
            'des': mydesvars,
            'obj': myobjectives,
            'con': myconstraints,
            'res': myresponses,
            'sys': mysystem_outputs,
        }

        self._rec_mgr.startup(self)
        if self._rec_mgr._recorders:
            from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
            self._model_viewer_data = _get_viewer_data(problem)
        if self.recording_options['record_metadata']:
            self._rec_mgr.record_metadata(self)

        # set up simultaneous deriv coloring
        if self._simul_coloring_info and self.supports['simultaneous_derivatives']:
            if problem._mode == 'fwd':
                self._setup_simul_coloring(problem._mode)
            else:
                raise RuntimeError("simultaneous derivs are currently not supported in rev mode.")
Example #17
0
    def _setup_driver(self, problem):
        """
        Prepare the driver for execution.

        This is the final thing to run during setup.

        Parameters
        ----------
        problem : <Problem>
            Pointer to the containing problem.
        """
        self._problem = problem
        model = problem.model

        self._objs = objs = OrderedDict()
        self._cons = cons = OrderedDict()
        self._responses = model.get_responses(recurse=True)
        for name, data in iteritems(self._responses):
            if data['type'] == 'con':
                cons[name] = data
            else:
                objs[name] = data

        # Gather up the information for design vars.
        self._designvars = model.get_design_vars(recurse=True)

        con_set = set()
        obj_set = set()
        dv_set = set()

        self._remote_dvs = dv_dict = {}
        self._remote_cons = con_dict = {}
        self._remote_objs = obj_dict = {}

        # Now determine if later we'll need to allgather cons, objs, or desvars.
        if model.comm.size > 1 and model._subsystems_allprocs:
            local_out_vars = set(model._outputs._views)
            remote_dvs = set(self._designvars) - local_out_vars
            remote_cons = set(self._cons) - local_out_vars
            remote_objs = set(self._objs) - local_out_vars
            all_remote_vois = model.comm.allgather(
                (remote_dvs, remote_cons, remote_objs))
            for rem_dvs, rem_cons, rem_objs in all_remote_vois:
                con_set.update(rem_cons)
                obj_set.update(rem_objs)
                dv_set.update(rem_dvs)

            # If we have remote VOIs, pick an owning rank for each and use that
            # to bcast to others later
            owning_ranks = model._owning_rank['output']
            sizes = model._var_sizes['nonlinear']['output']
            for i, vname in enumerate(model._var_allprocs_abs_names['output']):
                owner = owning_ranks[vname]
                if vname in dv_set:
                    dv_dict[vname] = (owner, sizes[owner, i])
                if vname in con_set:
                    con_dict[vname] = (owner, sizes[owner, i])
                if vname in obj_set:
                    obj_dict[vname] = (owner, sizes[owner, i])

        self._remote_responses = self._remote_cons.copy()
        self._remote_responses.update(self._remote_objs)

        self._rec_mgr.startup(self)
        if (self._rec_mgr._recorders):
            from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
            self._model_viewer_data = _get_viewer_data(problem)
        self._rec_mgr.record_metadata(self)
Example #18
0
    def _setup_recording(self):
        """
        Set up case recording.
        """
        problem = self._problem
        model = problem.model

        mydesvars = myobjectives = myconstraints = myresponses = set()
        myinputs = set()
        mysystem_outputs = set()

        incl = self.recording_options['includes']
        excl = self.recording_options['excludes']

        rec_desvars = self.recording_options['record_desvars']
        rec_objectives = self.recording_options['record_objectives']
        rec_constraints = self.recording_options['record_constraints']
        rec_responses = self.recording_options['record_responses']
        rec_inputs = self.recording_options['record_inputs']

        all_desvars = {
            n
            for n in self._designvars if check_path(n, incl, excl, True)
        }
        all_objectives = {
            n
            for n in self._objs if check_path(n, incl, excl, True)
        }
        all_constraints = {
            n
            for n in self._cons if check_path(n, incl, excl, True)
        }
        if rec_desvars:
            mydesvars = all_desvars

        if rec_objectives:
            myobjectives = all_objectives

        if rec_constraints:
            myconstraints = all_constraints

        if rec_responses:
            myresponses = {
                n
                for n in self._responses if check_path(n, incl, excl, True)
            }

        # get the includes that were requested for this Driver recording
        if incl:
            # The my* variables are sets

            # First gather all of the desired outputs
            # The following might only be the local vars if MPI
            mysystem_outputs = {
                n
                for n in model._outputs if check_path(n, incl, excl)
            }

            # If MPI, and on rank 0, need to gather up all the variables
            #    even those not local to rank 0
            if MPI:
                all_vars = model.comm.gather(mysystem_outputs, root=0)
                if MPI.COMM_WORLD.rank == 0:
                    mysystem_outputs = all_vars[-1]
                    for d in all_vars[:-1]:
                        mysystem_outputs.update(d)

            # de-duplicate mysystem_outputs
            mysystem_outputs = mysystem_outputs.difference(
                all_desvars, all_objectives, all_constraints)

        if rec_inputs:
            prob = self._problem
            root = prob.model
            myinputs = {n for n in root._inputs if check_path(n, incl, excl)}

            if MPI:
                all_vars = root.comm.gather(myinputs, root=0)
                if MPI.COMM_WORLD.rank == 0:
                    myinputs = all_vars[-1]
                    for d in all_vars[:-1]:
                        myinputs.update(d)

        if MPI:  # filter based on who owns the variables
            # TODO Eventually, we think we can get rid of this next check. But to be safe,
            #       we are leaving it in there.
            if not model.is_active():
                raise RuntimeError(
                    "RecordingManager.startup should never be called when "
                    "running in parallel on an inactive System")
            rrank = problem.comm.rank
            rowned = model._owning_rank
            mydesvars = [n for n in mydesvars if rrank == rowned[n]]
            myresponses = [n for n in myresponses if rrank == rowned[n]]
            myobjectives = [n for n in myobjectives if rrank == rowned[n]]
            myconstraints = [n for n in myconstraints if rrank == rowned[n]]
            mysystem_outputs = [
                n for n in mysystem_outputs if rrank == rowned[n]
            ]
            myinputs = [n for n in myinputs if rrank == rowned[n]]

        self._filtered_vars_to_record = {
            'des': mydesvars,
            'obj': myobjectives,
            'con': myconstraints,
            'res': myresponses,
            'sys': mysystem_outputs,
            'in': myinputs
        }

        self._rec_mgr.startup(self)
        if self._rec_mgr._recorders:
            from openmdao.devtools.problem_viewer.problem_viewer import _get_viewer_data
            self._model_viewer_data = _get_viewer_data(problem)
        if self.recording_options['record_metadata']:
            self._rec_mgr.record_metadata(self)
Example #19
0
def write_xdsm(problem,
               filename,
               model_path=None,
               recurse=True,
               include_external_outputs=True,
               out_format='tex',
               include_solver=False,
               subs=_CHAR_SUBS,
               show_browser=True,
               add_process_conns=True,
               **kwargs):
    """
    Writes XDSM diagram of an optimization problem.

    With the 'tex' or 'pdf' output format it uses the pyXDSM package, with 'json' or 'HTML'
    output format it uses XDSMjs.

    If a component (or group) name is not unique in the diagram, the systems absolute path is
    used as a label. If the component (or group) name is unique, the relative name of the
    system is the label.

    In the diagram the connections are marked with the source name.

    Writer specific settings and default:

    pyXDSM
    ~~~~~~

    * The appearance of the boxes can be controlled with "box_stacking" and "box_width" arguments.
      The box stacking can be:

      * "horizontal" - All variables in one line
      * "vertical" - All variables in one column
      * "cut_chars" - The text in the box will be one line with the maximum number of characters
        limited by "box_width".
      * "max_chars" - The "box_width" argument is used to determine
        the maximum allowed width of boxes (in characters).
      * "empty" - There are no variable names in the data block. Good for large diagrams.

      A default value is taken, if not specified.
    * By default the part of variable names following underscores (_)
      are not converted to subscripts.
      To write in subscripts wrap that part of the name into a round bracket.
      Example: To write :math:`x_12` the variable name should be "x(12)"
    * "box_lines" can be used to limit the number of lines, if the box stacking is vertical
    * "numbered_comps": bool, If True, components are numbered. Defaults to True.
    * "number_alignment": str, Horizontal or vertical. Defaults to horizontal. If "numbered_comps"
      is True, it positions the number either above or in front of the component label.

    XDSMjs
    ~~~~~~

    * If "embed_data" is true, a single standalone HTML file will be generated, which includes
      the data of the XDSM diagram.
    * variable names with exactly one underscore have a subscript.
      Example: "x_12" will be :math:`x_12`
    * If "embeddable" is True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>,
      <body> and <head> tags. If False, gives a single, standalone HTML file for viewing.

    Parameters
    ----------
    problem : Problem
        Problem
    filename : str
        Name of the output files (do not provide file extension)
    model_path : str or None
        Path to the subsystem to be transcribed to XDSM.  If None, use the model root.
    recurse : bool
        If False, treat the top level of each name as the source/target component.
    include_external_outputs : bool
        If True, show externally connected outputs when transcribing a subsystem.
        Defaults to True.
    out_format : str, optional
        Output format, one of "tex" (pyXDSM) or "json"/"html" (XDSMjs)
        Defaults to "tex".
    include_solver : bool
        Include or not the problem model's nonlinear solver in the XDSM.
    subs : dict(str, tuple), tuple(str, str), optional
        Characters to be replaced. Dictionary with writer names and character pairs or just the
        character pairs.
    show_browser : bool, optional
        If True, pop up a browser to view the generated html file.
        Defaults to True.
    add_process_conns: bool
        Add process connections (thin black lines)
        Defaults to True
    kwargs : dict
        Keyword arguments
    Returns
    -------
       XDSM
    """

    viewer_data = _get_viewer_data(problem)
    driver = problem.driver
    if model_path is None:
        _model = problem.model
    else:
        _model = problem.model._get_subsystem(model_path)

    # Name is None if the driver is not specified
    driver_name = _get_cls_name(driver) if driver else None

    design_vars = _model.get_design_vars()
    responses = _model.get_responses()

    filename = filename.replace('\\', '/')  # Needed for LaTeX

    out_formats = _OUT_FORMATS
    try:
        writer = out_formats[out_format]
    except KeyError:
        msg = 'Invalid output format "{}", choose from: {}'
        raise ValueError(msg.format(out_format, out_formats.keys()))
    writer_name = writer.lower()  # making it case insensitive
    if isinstance(subs, dict):
        subs = subs[
            writer_name]  # Getting the character substitutes of the chosen writer
    return _write_xdsm(filename,
                       viewer_data=viewer_data,
                       optimizer=driver_name,
                       include_solver=include_solver,
                       model_path=model_path,
                       design_vars=design_vars,
                       responses=responses,
                       writer=writer,
                       recurse=recurse,
                       subs=subs,
                       include_external_outputs=include_external_outputs,
                       show_browser=show_browser,
                       add_process_conns=add_process_conns,
                       **kwargs)