示例#1
0
def plot_graphs(obj, recurse=True, fmt='pdf', pseudos=True,
                workflow=False, sysdone=False, prefix=''):
    if IAssembly.providedBy(obj):
        name = 'top' if obj.get_pathname()=='' else obj.get_pathname()

        try:
            plot_graph(obj._depgraph.get_pruned(), fmt=fmt,
                       outfile=prefix+name+'_depgraph'+'.'+fmt, pseudos=pseudos)
        except Exception as err:
            print "Can't plot depgraph of '%s': %s" % (name, str(err))
        try:
            plot_graph(obj._reduced_graph, fmt=fmt,
                       outfile=prefix+name+'_reduced'+'.'+fmt, pseudos=pseudos)
        except Exception as err:
            print "Can't plot reduced graph of '%s': %s" % (name, str(err))

        if not sysdone:
            try:
                plot_system_tree(obj._system, fmt=fmt,
                           outfile=prefix+name+'_system_tree'+'.'+fmt)
            except Exception as err:
                print "Can't plot system graph of '%s': %s" % (name, str(err))

        try:
            plot_graph(obj._reduced_graph.component_graph(),
                       fmt=fmt, outfile=prefix+name+'_compgraph'+'.'+fmt,
                       pseudos=pseudos, workflow=workflow, scope=obj)
        except Exception as err:
            print "Can't plot component_graph of '%s': %s" % (name, str(err))

        _driver_plots(obj._top_driver, recurse=recurse, fmt=fmt,
                      pseudos=pseudos, workflow=workflow, sysdone=True,
                      prefix=prefix)
def plot_graphs(obj, recurse=True, fmt='pdf', pseudos=True,
                workflow=False, sysdone=False, prefix=''):
    if IAssembly.providedBy(obj):
        name = 'top' if obj.get_pathname()=='' else obj.get_pathname()

        try:
            plot_graph(obj._depgraph.get_pruned(), fmt=fmt,
                       outfile=prefix+name+'_depgraph'+'.'+fmt, pseudos=pseudos)
        except Exception as err:
            print "Can't plot depgraph of '%s': %s" % (name, str(err))
        try:
            plot_graph(obj._reduced_graph, fmt=fmt,
                       outfile=prefix+name+'_reduced'+'.'+fmt, pseudos=pseudos)
        except Exception as err:
            print "Can't plot reduced graph of '%s': %s" % (name, str(err))

        if not sysdone:
            try:
                plot_system_tree(obj._system, fmt=fmt,
                           outfile=prefix+name+'_system_tree'+'.'+fmt)
            except Exception as err:
                print "Can't plot system graph of '%s': %s" % (name, str(err))

        try:
            plot_graph(obj._reduced_graph.component_graph(),
                       fmt=fmt, outfile=prefix+name+'_compgraph'+'.'+fmt,
                       pseudos=pseudos, workflow=workflow, scope=obj)
        except Exception as err:
            print "Can't plot component_graph of '%s': %s" % (name, str(err))

        _driver_plots(obj._top_driver, recurse=recurse, fmt=fmt,
                      pseudos=pseudos, workflow=workflow, sysdone=True,
                      prefix=prefix)
示例#3
0
def _driver_plots(obj, recurse=True, fmt='pdf', pseudos=True,
                  workflow=False, sysdone=False, prefix=''):
    # driver graph
    try:
        plot_graph(obj.get_reduced_graph(), fmt=fmt,
                   outfile=prefix+obj.get_pathname()+'_reduced'+'.'+fmt, pseudos=pseudos)
    except Exception as err:
        print "Can't plot reduced graph of '%s': %s" % (obj.get_pathname(), str(err))

    # workflow graph
    try:
        plot_graph(obj.workflow._reduced_graph, fmt=fmt,
                   outfile=prefix+obj.get_pathname()+'_wflow_reduced'+'.'+fmt, pseudos=pseudos)
    except Exception as err:
        print "Can't plot reduced graph of '%s' workflow: %s" % (obj.get_pathname(), str(err))

    if recurse:
        for comp in obj.workflow:
            if IAssembly.providedBy(comp):
                plot_graphs(comp, recurse, fmt=fmt, pseudos=pseudos,
                            workflow=workflow, sysdone=True, prefix=prefix)
            elif IDriver.providedBy(comp):
                _driver_plots(comp, recurse, fmt=fmt, pseudos=pseudos,
                              workflow=workflow, sysdone=True, prefix=prefix)
def _driver_plots(obj, recurse=True, fmt='pdf', pseudos=True,
                  workflow=False, sysdone=False, prefix=''):
    # driver graph
    try:
        plot_graph(obj.get_reduced_graph(), fmt=fmt,
                   outfile=prefix+obj.get_pathname()+'_reduced'+'.'+fmt, pseudos=pseudos)
    except Exception as err:
        print "Can't plot reduced graph of '%s': %s" % (obj.get_pathname(), str(err))

    # workflow graph
    try:
        plot_graph(obj.workflow._reduced_graph, fmt=fmt,
                   outfile=prefix+obj.get_pathname()+'_wflow_reduced'+'.'+fmt, pseudos=pseudos)
    except Exception as err:
        print "Can't plot reduced graph of '%s' workflow: %s" % (obj.get_pathname(), str(err))

    if recurse:
        for comp in obj.workflow:
            if IAssembly.providedBy(comp):
                plot_graphs(comp, recurse, fmt=fmt, pseudos=pseudos,
                            workflow=workflow, sysdone=True, prefix=prefix)
            elif IDriver.providedBy(comp):
                _driver_plots(comp, recurse, fmt=fmt, pseudos=pseudos,
                              workflow=workflow, sysdone=True, prefix=prefix)
示例#5
0
def applyJ(system, variables):
    """Multiply an input vector by the Jacobian. For an Explicit Component,
    this automatically forms the "fake" residual, and calls into the
    function hook "apply_deriv".
    """

    J = system.J
    obj = system.inner()
    scope = system.scope

    is_sys = ISystem.providedBy(obj)

    arg = {}
    for item in system.list_states():

        collapsed = scope.name2collapsed.get(item)
        if collapsed not in variables:
            continue

        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        parent = system

        while True:
            if item in parent.vec['du']:
                arg[key] = parent.vec['du'][item]
                break
            parent = parent._parent_system

    for item in system.list_inputs():

        collapsed = scope.name2collapsed.get(item)
        if collapsed not in variables:
            continue

        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        parent = system

        while True:
            parent = parent._parent_system
            if item in parent.vec['dp']:
                arg[key] = parent.vec['dp'][item]
                break

    result = {}
    for item in system.list_outputs():

        collapsed = scope.name2collapsed.get(item)
        if collapsed not in variables:
            continue

        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        result[key] = system.rhs_vec[item]

    for item in system.list_residuals():
        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        result[key] = system.rhs_vec[item]

    # Bail if this component is not connected in the graph
    if len(arg) == 0 or len(result) == 0:
        return

    # Speedhack, don't call component's derivatives if incoming vector is zero.
    nonzero = False
    for key, value in arg.iteritems():
        if any(value != 0):
            nonzero = True
            break

    if nonzero is False:
        #print 'applyJ', obj.name, arg, result
        return

    # If storage of the local Jacobian is a problem, the user can specify the
    # 'apply_deriv' function instead of provideJ.
    if J is None and hasattr(obj, 'apply_deriv'):

        # TODO - We shouldn't need to calculate the size of the full arrays,
        # so the cache shouldn't be needed. Cache is None for now.
        shape_cache = {}

        # The apply_deriv function expects the argument and result dicts for
        # each input and output to have the same shape as the input/output.
        resultkeys = sorted(result.keys())
        for key in resultkeys:
            pre_process_dicts(obj, key, result, shape_cache, scope, is_sys)

        argkeys = arg.keys()
        for key in sorted(argkeys):
            pre_process_dicts(obj, key, arg, shape_cache, scope, is_sys)

        obj.apply_deriv(arg, result)

        # Result vector needs to be flattened.
        for key in reversed(resultkeys):
            post_process_dicts(key, result)

        # Arg is still called afterwards, so flatten it back.
        for key in argkeys:
            value = arg[key]
            if hasattr(value, 'flatten'):
                arg[key] = value.flatten()

        #print 'applyJ', obj.name, arg, result
        return

    if is_sys:
        input_keys = system.list_inputs() + system.list_states()
        output_keys = system.list_outputs() + system.list_residuals()
    elif IAssembly.providedBy(obj):
        input_keys = [item.partition('.')[-1] \
                      for item in system.list_inputs()]
        output_keys = [item.partition('.')[-1] \
                       for item in system.list_outputs()]
    else:
        input_keys, output_keys = list_deriv_vars(obj)

    #print 'J', input_keys, output_keys, J

    # The Jacobian from provideJ is a 2D array containing the derivatives of
    # the flattened output_keys with respect to the flattened input keys. We
    # need to find the start and end index of each input and output.

    if obj._provideJ_bounds is None:
        obj._provideJ_bounds = get_bounds(obj, input_keys, output_keys, J)
    ibounds, obounds = obj._provideJ_bounds

    for okey in result:

        odx = None
        if okey in obounds:
            o1, o2, osh = obounds[okey]
        else:
            basekey, _, odx = okey.partition('[')
            try:
                o1, o2, osh = obounds[basekey]
            except KeyError:
                if obj.missing_deriv_policy == 'error':
                    msg = "does not provide analytical derivatives" + \
                          " for %s" % okey
                    obj.raise_exception(msg, KeyError)
                continue

        tmp = result[okey]
        used = set()
        for ikey in arg:

            idx = None
            if ikey in ibounds:
                i1, i2, ish = ibounds[ikey]
                if (i1, i2) in used:
                    continue
                used.add((i1, i2))
            else:
                basekey, _, idx = ikey.partition('[')
                try:
                    i1, i2, ish = ibounds[basekey]
                except KeyError:
                    if obj.missing_deriv_policy == 'error':
                        msg = "does not provide analytical derivatives" + \
                              " for %s" % ikey
                        obj.raise_exception(msg, KeyError)
                    continue

                if (i1, i2, idx) in used or (i1, i2) in used:
                    continue
                used.add((i1, i2, idx))

            Jsub = reduce_jacobian(J, i1, i2, idx, ish, o1, o2, odx, osh)
            #print ikey, okey, Jsub

            tmp += Jsub.dot(arg[ikey])
def applyJ(system, variables):
    """Multiply an input vector by the Jacobian. For an Explicit Component,
    this automatically forms the "fake" residual, and calls into the
    function hook "apply_deriv".
    """

    J = system.J
    obj = system.inner()
    scope = system.scope

    is_sys = ISystem.providedBy(obj)

    arg = {}
    for item in system.list_states():

        collapsed = scope.name2collapsed.get(item)
        if collapsed not in variables:
            continue

        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        parent = system

        while True:
            if item in parent.vec['du']:
                arg[key] = parent.vec['du'][item]
                break
            parent = parent._parent_system

    for item in system.list_inputs():

        collapsed = scope.name2collapsed.get(item)
        if collapsed not in variables:
            continue

        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        parent = system

        while True:
            parent = parent._parent_system
            if item in parent.vec['dp']:
                arg[key] = parent.vec['dp'][item]
                break

    result = {}
    for item in system.list_outputs():

        collapsed = scope.name2collapsed.get(item)
        if collapsed not in variables:
            continue

        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        result[key] = system.rhs_vec[item]

    for item in system.list_residuals():
        key = item
        if not is_sys:
            key = item.partition('.')[-1]
        result[key] = system.rhs_vec[item]

    # Bail if this component is not connected in the graph
    if len(arg) == 0 or len(result) == 0:
        return

    # Speedhack, don't call component's derivatives if incoming vector is zero.
    nonzero = False
    for key, value in arg.iteritems():
        if any(value != 0):
            nonzero = True
            break

    if nonzero is False:
        #print 'applyJ', obj.name, arg, result
        return

    # If storage of the local Jacobian is a problem, the user can specify the
    # 'apply_deriv' function instead of provideJ.
    if J is None and hasattr(obj, 'apply_deriv'):

        # TODO - We shouldn't need to calculate the size of the full arrays,
        # so the cache shouldn't be needed. Cache is None for now.
        shape_cache = {}

        # The apply_deriv function expects the argument and result dicts for
        # each input and output to have the same shape as the input/output.
        resultkeys = sorted(result.keys())
        for key in resultkeys:
            pre_process_dicts(obj, key, result, shape_cache, scope, is_sys)

        argkeys = arg.keys()
        for key in sorted(argkeys):
            pre_process_dicts(obj, key, arg, shape_cache, scope, is_sys)

        obj.apply_deriv(arg, result)

        # Result vector needs to be flattened.
        for key in reversed(resultkeys):
            post_process_dicts(key, result)

        # Arg is still called afterwards, so flatten it back.
        for key in argkeys:
            value = arg[key]
            if hasattr(value, 'flatten'):
                arg[key] = value.flatten()

        #print 'applyJ', obj.name, arg, result
        return

    if is_sys:
        input_keys = system.list_inputs() + system.list_states()
        output_keys = system.list_outputs() + system.list_residuals()
    elif IAssembly.providedBy(obj):
        input_keys = [item.partition('.')[-1] \
                      for item in system.list_inputs()]
        output_keys = [item.partition('.')[-1] \
                       for item in system.list_outputs()]
    else:
        input_keys, output_keys = list_deriv_vars(obj)

    #print 'J', input_keys, output_keys, J

    # The Jacobian from provideJ is a 2D array containing the derivatives of
    # the flattened output_keys with respect to the flattened input keys. We
    # need to find the start and end index of each input and output.

    if obj._provideJ_bounds is None:
        obj._provideJ_bounds = get_bounds(obj, input_keys, output_keys, J)
    ibounds, obounds = obj._provideJ_bounds

    for okey in result:

        odx = None
        if okey in obounds:
            o1, o2, osh = obounds[okey]
        else:
            basekey, _, odx = okey.partition('[')
            try:
                o1, o2, osh = obounds[basekey]
            except KeyError:
                if obj.missing_deriv_policy == 'error':
                    msg = "does not provide analytical derivatives" + \
                          " for %s" % okey
                    obj.raise_exception(msg, KeyError)
                continue

        tmp = result[okey]
        used = set()
        for ikey in arg:

            idx = None
            if ikey in ibounds:
                i1, i2, ish = ibounds[ikey]
                if (i1, i2) in used:
                    continue
                used.add((i1, i2))
            else:
                basekey, _, idx = ikey.partition('[')
                try:
                    i1, i2, ish = ibounds[basekey]
                except KeyError:
                    if obj.missing_deriv_policy == 'error':
                        msg = "does not provide analytical derivatives" + \
                              " for %s" % ikey
                        obj.raise_exception(msg, KeyError)
                    continue

                if (i1, i2, idx) in used or (i1, i2) in used:
                    continue
                used.add((i1, i2, idx))

            Jsub = reduce_jacobian(J, i1, i2, idx, ish,
                                      o1, o2, odx, osh)
            #print ikey, okey, Jsub

            tmp += Jsub.dot(arg[ikey])
示例#7
0
def print_vars(comp, list_type="inputs", prefix="", astable=False):

    comp_reserved = ["driver"]
    reserved = ["missing_deriv_policy", "force_execute", "directory", "force_fd", "printvars", "exec_count"]

    # recursively search for subassemblies
    if IAssembly.providedBy(comp):  # outer needs to be an assembly
        subcomp = comp.list_components()

        for subc_name in subcomp:
            if subc_name in comp_reserved:
                continue

            subc = getattr(comp, subc_name)
            if IAssembly.providedBy(subc):  # inner must be an subassembly
                if prefix is not None:
                    newprefix = prefix + "." + subc_name
                else:
                    newprefix = subc_name
                print_vars(subc, list_type, newprefix, astable)
                continue

    if list_type == "inputs":
        thelist = comp.list_inputs(connected=False)
    elif list_type == "outputs":
        thelist = comp.list_outputs(connected=False)
    elif list_type == "vars":
        thelist = comp.list_vars()

    for name in thelist:

        if name in reserved:
            continue

        trait = comp.get_trait(name)
        thetype = trait.trait_type.__str__().split()[0].split(".")[-1]

        if thetype == "VarTree":
            vartree = getattr(comp, name)
            if prefix is not None:
                newprefix = prefix + "." + name
            else:
                newprefix = name
            print_vars(vartree, "vars", newprefix, astable)
            continue

        units = trait.units
        desc = trait.desc
        default = trait.default
        # print trait.category

        if units is None:
            description = "(" + thetype + ")"
        else:
            description = "(" + thetype + ", " + units + ")"

        if desc is not None:
            description += ": " + desc

        if prefix is not "":
            name = prefix + "." + name

        if not astable:
            name = name + " = " + str(default)
            print name + "  # " + description

        else:

            if not units:
                units = ""
            if not desc:
                desc = ""
            strdefault = str(default)
            if strdefault == "<undefined>":
                strdefault = ""

            print "{0:15}\t{1:10}\t{2:15}\t{3:10}\t{4}".format(name, thetype, strdefault, units, desc)
示例#8
0
def print_vars(comp, list_type='inputs', prefix='', astable=False):

    comp_reserved = ['driver']
    reserved = ['missing_deriv_policy', 'force_execute', 'directory', 'force_fd', 'printvars', 'exec_count']

    # recursively search for subassemblies
    if IAssembly.providedBy(comp):  # outer needs to be an assembly
        subcomp = comp.list_components()

        for subc_name in subcomp:
            if subc_name in comp_reserved:
                continue

            subc = getattr(comp, subc_name)
            if IAssembly.providedBy(subc):  # inner must be an subassembly
                if prefix is not None:
                    newprefix = prefix + '.' + subc_name
                else:
                    newprefix = subc_name
                print_vars(subc, list_type, newprefix, astable)
                continue


    if list_type == 'inputs':
        thelist = comp.list_inputs(connected=False)
    elif list_type == 'outputs':
        thelist = comp.list_outputs(connected=False)
    elif list_type == 'vars':
        thelist = comp.list_vars()

    for name in thelist:

        if name in reserved:
            continue

        trait = comp.get_trait(name)
        thetype = trait.trait_type.__str__().split()[0].split('.')[-1]

        if thetype == 'VarTree':
            vartree = getattr(comp, name)
            if prefix is not None:
                newprefix = prefix + '.' + name
            else:
                newprefix = name
            print_vars(vartree, 'vars', newprefix, astable)
            continue

        units = trait.units
        desc = trait.desc
        default = trait.default
        # print trait.category

        if units is None:
            description = '(' + thetype + ')'
        else:
            description = '(' + thetype + ', ' + units + ')'

        if desc is not None:
            description += ': ' + desc


        if prefix is not '':
            name = prefix + '.' + name

        if not astable:
            name = name + ' = ' + str(default)
            print name + '  # ' + description

        else:

            if not units:
                units = ''
            if not desc:
                desc = ''
            strdefault = str(default)
            if strdefault == '<undefined>':
                strdefault = ''

            print '{0:15}\t{1:10}\t{2:15}\t{3:10}\t{4}'.format(name, thetype, strdefault, units, desc)