def _add_eq_constraint(self, lhs, rhs, name=None, scope=None, linear=False, jacs=None): """Adds an equality constraint as two strings, a left-hand side and a right-hand side. """ if not isinstance(lhs, basestring): msg = "Constraint left-hand side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(rhs, basestring): msg = "Constraint right-hand-side (%s) is not a string" % rhs raise ValueError(msg) ident = _remove_spaces('='.join((lhs, rhs))) if ident in self._constraints: self.parent.raise_exception('A constraint of the form "%s" already' ' exists in the driver. Add failed.' % ident, ValueError) elif name is not None and name in self._constraints: self.parent.raise_exception('A constraint named "%s" already exists' ' in the driver. Add failed.' % name, ValueError) constraint = Constraint(lhs, '=', rhs, scope=_get_scope(self, scope), jacs=jacs) constraint.linear = linear if IDriver.providedBy(self.parent): #constraint.activate(self.parent) self.parent.config_changed() name = ident if name is None else name self._constraints[name] = constraint
def _add_eq_constraint(self, lhs, rhs, name=None, scope=None, linear=False): """Adds an equality constraint as two strings, a left-hand side and a right-hand side. """ if not isinstance(lhs, basestring): msg = "Constraint left-hand side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(rhs, basestring): msg = "Constraint right-hand-side (%s) is not a string" % rhs raise ValueError(msg) ident = _remove_spaces('='.join((lhs, rhs))) if ident in self._constraints: self.parent.raise_exception( 'A constraint of the form "%s" already' ' exists in the driver. Add failed.' % ident, ValueError) elif name is not None and name in self._constraints: self.parent.raise_exception( 'A constraint named "%s" already exists' ' in the driver. Add failed.' % name, ValueError) constraint = Constraint(lhs, '=', rhs, scope=_get_scope(self, scope)) constraint.linear = linear if IDriver.providedBy(self.parent): constraint.activate(self.parent) self.parent.config_changed() name = ident if name is None else name self._constraints[name] = constraint
def write_driver_cluster(f, G, driver, indent, counts, alledges, excludes=()): global _cluster_count, IDriver show = driver.name not in excludes comps = list(driver.workflow) subG = G.subgraph([c.name for c in comps]) tab = ' ' * indent if show: f.write('%ssubgraph cluster%s {\n' % (tab, _cluster_count)) _cluster_count += 1 indent += 3 tab = ' ' * indent f.write('%s%s [shape=invhouse];\n' % (tab, driver.name)) if len(comps) > 0: dcount = 1 for comp in comps: if IDriver.providedBy(comp): write_driver_cluster(f, G, comp, indent, counts, alledges) f.write("%s%s -> %s [style=dashed, label=%d];\n" % (tab, driver.name, comp.name, dcount)) alledges.add((driver.name, comp.name)) dcount += 1 subG = G.subgraph([c.name for c in comps]) edges = subG.edges() # now remove subdrivers subG.remove_nodes_from( [c.name for c in comps if IDriver.providedBy(c)]) write_nodes(f, subG, indent, counts, driver.name) for u, v in edges: alledges.add((u, v)) if counts[u] > 0: u = '"%s@%s"' % (u, driver.name) if counts[v] > 0: v = '"%s@%s"' % (v, driver.name) f.write('%s%s -> %s;\n' % (tab, u, v)) for pname in driver.list_pseudocomps(): f.write('%s%s -> %s [style=dotted];\n' % (tab, pname, driver.name)) alledges.add((pname, driver.name)) f.write('%s}\n' % tab)
def write_driver_cluster(f, G, driver, indent, counts, alledges, excludes=()): global _cluster_count, IDriver show = driver.name not in excludes comps = list(driver.workflow) subG = G.subgraph([c.name for c in comps]) tab = ' '*indent if show: f.write('%ssubgraph cluster%s {\n' % (tab, _cluster_count)) _cluster_count += 1 indent += 3 tab = ' '*indent f.write('%s%s [shape=invhouse];\n' % (tab, driver.name)) if len(comps) > 0: dcount = 1 for comp in comps: if IDriver.providedBy(comp): write_driver_cluster(f, G, comp, indent, counts, alledges) f.write("%s%s -> %s [style=dashed, label=%d];\n" % (tab, driver.name, comp.name, dcount)) alledges.add((driver.name,comp.name)) dcount += 1 subG = G.subgraph([c.name for c in comps]) edges = subG.edges() # now remove subdrivers subG.remove_nodes_from([c.name for c in comps if IDriver.providedBy(c)]) write_nodes(f, subG, indent, counts, driver.name) for u,v in edges: alledges.add((u,v)) if counts[u] > 0: u = '"%s@%s"' % (u, driver.name) if counts[v] > 0: v = '"%s@%s"' % (v, driver.name) f.write('%s%s -> %s;\n' % (tab, u, v)) for pname in driver.list_pseudocomps(): f.write('%s%s -> %s [style=dotted];\n' % (tab, pname, driver.name)) alledges.add((pname, driver.name)) f.write('%s}\n' % tab)
def add_2sided_constraint(self, lhs, center, rhs, rel, name=None, scope=None, linear=False): """Adds an 2-sided constraint as four strings; a left-hand side, a center, a right-hand side, and a comparator ('<','>','<=', or '>=') """ if rel == '=': msg = "Equality is not supported in a double sided constraint" self.parent.raise_exception(msg, ValueError) if not isinstance(lhs, basestring): msg = "Constraint left-hand-side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(center, basestring): msg = "Constraint center-side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(rhs, basestring): msg = "Constraint right-hand-side (%s) is not a string" % rhs raise ValueError(msg) # Let's define left as low and right as high if rel == '>': rel = '<' rhs, lhs = lhs, rhs ident = _remove_spaces(rel.join((lhs, center, rhs))) if ident in self._constraints: self.parent.raise_exception( 'A constraint of the form "%s" already' ' exists in the driver. Add failed.' % ident, ValueError) elif name is not None and name in self._constraints: self.parent.raise_exception( 'A constraint named "%s" already exists' ' in the driver. Add failed.' % name, ValueError) constraint = Constraint2Sided(lhs, center, rhs, rel, scope=_get_scope(self, scope)) constraint.linear = linear if IDriver.providedBy(self.parent): constraint.activate(self.parent) self.parent.config_changed() if name is None: self._constraints[ident] = constraint else: self._constraints[name] = constraint
def remove_parameter(self, name): """Removes the parameter with the given name.""" param = self._parameters.get(name) if param: del self._parameters[name] else: self.parent.raise_exception("Trying to remove parameter '%s' " "that is not in this driver." % (name,), AttributeError) if IDriver.providedBy(self.parent): self.parent.config_changed()
def add_existing_2sided_constraint(self, scope, constraint, name=None): """Adds an existing Constraint object to the driver. scope: container object where constraint expression will be evaluated. constraint: Constraint object name: str (optional) Name to be used to refer to the constraint rather than its expression string. """ self._constraints[name] = constraint if IDriver.providedBy(self.parent): constraint.activate(self.parent) self.parent.config_changed()
def add_existing_2sided_constraint(self, scope, constraint, name=None): """Adds an existing Constraint object to the driver. scope: container object where constraint expression will be evaluated. constraint: Constraint object name: str (optional) Name to be used to refer to the constraint rather than its expression string. """ self._constraints[name] = constraint if IDriver.providedBy(self.parent): #constraint.activate(self.parent) self.parent.config_changed()
def add_objective(self, expr, name=None, scope=None): """Adds an objective to the driver. expr: string String containing the objective expression. name: string (optional) Name to be used to refer to the objective in place of the expression string. scope: object (optional) The object to be used as the scope when evaluating the expression. """ if self._max_objectives > 0 and \ len(self._objectives) >= self._max_objectives: self.parent.raise_exception( "Can't add objective '%s'. Only %d" " objectives are allowed" % (expr, self._max_objectives), RuntimeError) expr = _remove_spaces(expr) if expr in self._objectives: self.parent.raise_exception( "Trying to add objective '%s' to" " driver, but it's already there" % expr, AttributeError) if name is not None and name in self._objectives: self.parent.raise_exception( "Trying to add objective '%s' to" " driver using name '%s', but name is" " already used" % (expr, name), AttributeError) scope = self._get_scope(scope) expreval = Objective(expr, scope) unresolved_vars = expreval.get_unresolved() if unresolved_vars: msg = "Can't add objective '{0}' because of invalid variables {1}" error = ConnectedExprEvaluator._invalid_expression_error( unresolved_vars, expreval.text, msg) self.parent.raise_exception(str(error), type(error)) name = expr if name is None else name if IDriver.providedBy(self.parent): expreval.activate(self.parent) self.parent.config_changed() self._objectives[name] = expreval
def add_2sided_constraint(self, lhs, center, rhs, rel, name=None, scope=None, linear=False, jacs=None): """Adds an 2-sided constraint as four strings; a left-hand side, a center, a right-hand side, and a comparator ('<','>','<=', or '>=') """ if rel == '=': msg = "Equality is not supported in a double sided constraint" self.parent.raise_exception(msg, ValueError) if not isinstance(lhs, basestring): msg = "Constraint left-hand-side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(center, basestring): msg = "Constraint center-side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(rhs, basestring): msg = "Constraint right-hand-side (%s) is not a string" % rhs raise ValueError(msg) # Let's define left as low and right as high if rel == '>': rel = '<' rhs, lhs = lhs, rhs ident = _remove_spaces(rel.join((lhs, center, rhs))) if ident in self._constraints: self.parent.raise_exception('A constraint of the form "%s" already' ' exists in the driver. Add failed.' % ident, ValueError) elif name is not None and name in self._constraints: self.parent.raise_exception('A constraint named "%s" already exists' ' in the driver. Add failed.' % name, ValueError) constraint = Constraint2Sided(lhs, center, rhs, rel, scope=_get_scope(self, scope), jacs=jacs) constraint.linear = linear if IDriver.providedBy(self.parent): #constraint.activate(self.parent) self.parent.config_changed() if name is None: self._constraints[ident] = constraint else: self._constraints[name] = constraint
def add_objective(self, expr, name=None, scope=None): """Adds an objective to the driver. expr: string String containing the objective expression. name: string (optional) Name to be used to refer to the objective in place of the expression string. scope: object (optional) The object to be used as the scope when evaluating the expression. """ if self._max_objectives > 0 and \ len(self._objectives) >= self._max_objectives: self.parent.raise_exception("Can't add objective '%s'. Only %d" " objectives are allowed" % (expr, self._max_objectives), RuntimeError) expr = _remove_spaces(expr) if expr in self._objectives: self.parent.raise_exception("Trying to add objective '%s' to" " driver, but it's already there" % expr, AttributeError) if name is not None and name in self._objectives: self.parent.raise_exception("Trying to add objective '%s' to" " driver using name '%s', but name is" " already used" % (expr, name), AttributeError) scope = self._get_scope(scope) try: expreval = Objective(expr, scope) except Exception as err: self.parent.raise_exception(str(err), type(err)) name = expr if name is None else name if IDriver.providedBy(self.parent): #expreval.activate(self.parent) self.parent.config_changed() self._objectives[name] = expreval
def add_existing_constraint(self, scope, constraint, name=None): """Adds an existing Constraint object to the driver. scope: container object where constraint expression will be evaluated. constraint: Constraint object name: str (optional) Name to be used to refer to the constraint rather than its expression string. """ if constraint.comparator != '=': self._constraints[name] = constraint if IDriver.providedBy(self.parent): #constraint.activate(self.parent) self.parent.config_changed() else: self.parent.raise_exception("Equality constraint '%s' is not" " supported on this driver" % constraint, ValueError)
def add_existing_constraint(self, scope, constraint, name=None): """Adds an existing Constraint object to the driver. scope: container object where constraint expression will be evaluated. constraint: Constraint object name: str (optional) Name to be used to refer to the constraint rather than its expression string. """ if constraint.comparator != '=': self._constraints[name] = constraint if IDriver.providedBy(self.parent): constraint.activate(self.parent) self.parent.config_changed() else: self.parent.raise_exception( "Equality constraint '%s' is not" " supported on this driver" % constraint, ValueError)
def _add_ineq_constraint(self, lhs, rel, rhs, name=None, scope=None, linear=False): """Adds an inequality constraint as three strings; a left-hand side, a comparator ('<','>','<=', or '>='), and a right-hand side. """ if rel == '=': msg = "Equality constraints are not supported on this driver" self.parent.raise_exception(msg, ValueError) if not isinstance(lhs, basestring): msg = "Constraint left-hand-side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(rhs, basestring): msg = "Constraint right-hand-side (%s) is not a string" % rhs raise ValueError(msg) ident = _remove_spaces(rel.join((lhs, rhs))) if ident in self._constraints: self.parent.raise_exception( 'A constraint of the form "%s" already' ' exists in the driver. Add failed.' % ident, ValueError) elif name is not None and name in self._constraints: self.parent.raise_exception( 'A constraint named "%s" already exists' ' in the driver. Add failed.' % name, ValueError) constraint = Constraint(lhs, rel, rhs, scope=_get_scope(self, scope)) constraint.linear = linear if IDriver.providedBy(self.parent): constraint.activate(self.parent) self.parent.config_changed() if name is None: self._constraints[ident] = constraint else: self._constraints[name] = constraint
def _add_ineq_constraint(self, lhs, rel, rhs, name=None, scope=None, linear=False, jacs=None): """Adds an inequality constraint as three strings; a left-hand side, a comparator ('<','>','<=', or '>='), and a right-hand side. """ if rel == '=': msg = "Equality constraints are not supported on this driver" self.parent.raise_exception(msg, ValueError) if not isinstance(lhs, basestring): msg = "Constraint left-hand-side (%s) is not a string" % lhs raise ValueError(msg) if not isinstance(rhs, basestring): msg = "Constraint right-hand-side (%s) is not a string" % rhs raise ValueError(msg) ident = _remove_spaces(rel.join((lhs, rhs))) if ident in self._constraints: self.parent.raise_exception('A constraint of the form "%s" already' ' exists in the driver. Add failed.' % ident, ValueError) elif name is not None and name in self._constraints: self.parent.raise_exception('A constraint named "%s" already exists' ' in the driver. Add failed.' % name, ValueError) constraint = Constraint(lhs, rel, rhs, scope=_get_scope(self, scope), jacs=jacs) constraint.linear = linear if IDriver.providedBy(self.parent): #constraint.activate(self.parent) self.parent.config_changed() if name is None: self._constraints[ident] = constraint else: self._constraints[name] = constraint
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 _get_comp_counts(drv, counts): for cname in drv._ordering: comp = getattr(drv.parent, cname) counts[cname] += 1 if IDriver.providedBy(comp): _get_comp_counts(comp, counts)
def add_parameter(self, target, low=None, high=None, scaler=None, adder=None, start=None, fd_step=None, name=None, scope=None): """Adds a parameter or group of parameters to the driver. target: string or iter of strings or Parameter What the driver should vary during execution. A *target* is an expression that can reside on the left-hand side of an assignment statement, so typically it will be the name of a variable or possibly a subscript expression indicating an entry within an array variable, e.g., x[3]. If an iterator of targets is given, then the driver will set all targets given to the same value whenever it varies this parameter during execution. If a Parameter instance is given, then that instance is copied into the driver with any other arguments specified, overiding the values in the given parameter. low: float (optional) Minimum allowed value of the parameter. If scaler and/or adder is supplied, use the transformed value here. If target is an array, this may also be an array, but must have the same size. high: float (optional) Maximum allowed value of the parameter. If scaler and/or adder is supplied, use the transformed value here. If target is an array, this may also be an array, but must have the same size. scaler: float (optional) Value to multiply the possibly offset parameter value by. If target is an array, this may also be an array, but must have the same size. adder: float (optional) Value to add to parameter prior to possible scaling. If target is an array, this may also be an array, but must have the same size. start: any (optional) Value to set into the target or targets of a parameter before starting any executions. If not given, analysis will start with whatever values are in the target or targets at that time. If target is an array, this may also be an array, but must have the same size. fd_step: float (optional) Step-size to use for finite difference calculation. If no value is given, the differentiator will use its own default. If target is an array, this may also be an array, but must have the same size. name: str (optional) Name used to refer to the parameter in place of the name of the variable referred to in the parameter string. This is sometimes useful if, for example, multiple entries in the same array variable are declared as parameters. scope: object (optional) The object to be used as the scope when evaluating the expression. If neither "low" nor "high" is specified, the min and max will default to the values in the metadata of the variable being referenced. """ if isinstance(target, (ParameterBase, ParameterGroup)): self._parameters[target.name] = target target.override(low, high, scaler, adder, start, fd_step, name) else: if isinstance(target, basestring): names = [target] key = target elif len(target) == 1: names = target key = target[0] else: names = target key = tuple(target) if name is not None: key = name dups = set(self.list_param_targets()).intersection(names) if dups: self.parent.raise_exception("%s are already Parameter targets" % sorted(list(dups)), ValueError) if key in self._parameters: self.parent.raise_exception("%s is already a Parameter" % key, ValueError) try: _scope = self._get_scope(scope) if len(names) == 1: target = self._create(names[0], low, high, scaler, adder, start, fd_step, key, _scope) else: # defining a ParameterGroup parameters = [self._create(n, low, high, scaler, adder, start, fd_step, key, _scope) for n in names] types = set([p.valtypename for p in parameters]) if len(types) > 1: raise ValueError("Can't add parameter %s because " "%s are not all of the same type" % (key, " and ".join(names))) target = ParameterGroup(parameters) self._parameters[key] = target except Exception: self.parent.reraise_exception(info=sys.exc_info()) if IDriver.providedBy(self.parent): self.parent.config_changed()
def _get_comp_counts(drv, counts): for comp in drv.workflow: counts[comp.name] += 1 if IDriver.providedBy(comp): _get_comp_counts(comp, counts)