def __setitem__(self, name, value): """ Set the unscaled variable value in true units. Parameters ---------- name : str Promoted or relative variable name in the owning system's namespace. value : float or list or tuple or ndarray variable value to set (not scaled, not dimensionless) """ abs_name = name2abs_name(self._system, name, self._names, self._typ) if abs_name is not None: if self._icol is None: slc = _full_slice else: slc = (_full_slice, self._icol) value, _ = ensure_compatible(name, value, self._views[abs_name][slc].shape) if self._vector_info._under_complex_step: # setitem overwrites anything you may have done with numpy indexing try: del self._complex_view_cache[abs_name] except KeyError: pass self._views[abs_name][slc] = value.real self._imag_views[abs_name][slc] = value.imag else: self._views[abs_name][slc] = value else: msg = 'Variable name "{}" not found.' raise KeyError(msg.format(name))
def add_output(self, name, val=1.0, units=None): """ Add an independent variable to this component. This should never be called by a user, as it skips all checks. Parameters ---------- name : str Name of the variable in this component's namespace. val : float or list or tuple or ndarray The initial value of the variable being added in user-defined units. Default is 1.0. units : str or None Units in which the output variables will be provided to the component during execution. Default is None, which means it has no units. Returns ------- dict Metadata for added variable. """ # Add the output quickly. # We don't need to check for errors because we get the value straight from a # source, and ivc metadata is minimal. value, shape = ensure_compatible(name, val, None) metadata = { 'val': value, 'shape': shape, 'size': shape_to_len(shape), 'units': units, 'res_units': None, 'desc': '', 'distributed': False, 'tags': set(), 'ref': 1.0, 'ref0': 0.0, 'res_ref': 1.0, 'lower': None, 'upper': None, 'shape_by_conn': False, 'copy_shape': None } self._static_var_rel2meta[name] = metadata self._static_var_rel_names['output'].append(name) self._var_added(name) return metadata
def add_output(self, name, val=1.0, shape=None, units=None, res_units=None, desc='', lower=None, upper=None, ref=1.0, ref0=0.0, res_ref=1.0, var_set=0): """ Add an output variable to the component. Parameters ---------- name : str name of the variable in this component's namespace. val : float or list or tuple or ndarray The initial value of the variable being added in user-defined units. Default is 1.0. shape : int or tuple or list or None Shape of this variable, only required if val is not an array. Default is None. units : str or None Units in which the output variables will be provided to the component during execution. Default is None, which means it has no units. res_units : str or None Units in which the residuals of this output will be given to the user when requested. Default is None, which means it has no units. desc : str description of the variable. lower : float or list or tuple or ndarray or Iterable or None lower bound(s) in user-defined units. It can be (1) a float, (2) an array_like consistent with the shape arg (if given), or (3) an array_like matching the shape of val, if val is array_like. A value of None means this output has no lower bound. Default is None. upper : float or list or tuple or ndarray or or Iterable None upper bound(s) in user-defined units. It can be (1) a float, (2) an array_like consistent with the shape arg (if given), or (3) an array_like matching the shape of val, if val is array_like. A value of None means this output has no upper bound. Default is None. ref : float or ndarray Scaling parameter. The value in the user-defined units of this output variable when the scaled value is 1. Default is 1. ref0 : float or ndarray Scaling parameter. The value in the user-defined units of this output variable when the scaled value is 0. Default is 0. res_ref : float or ndarray Scaling parameter. The value in the user-defined res_units of this output's residual when the scaled value is 1. Default is 1. var_set : hashable object For advanced users only. ID or color for this variable, relevant for reconfigurability. Default is 0. Returns ------- dict metadata for added variable """ if units == 'unitless': warn_deprecation("Output '%s' has units='unitless' but 'unitless' " "has been deprecated. Use " "units=None instead. Note that connecting a " "unitless variable to one with units is no longer " "an error, but will issue a warning instead." % name) units = None # First, type check all arguments if not isinstance(name, str): raise TypeError('The name argument should be a string') if not np.isscalar(val) and not isinstance(val, (list, tuple, np.ndarray, Iterable)): raise TypeError('The val argument should be a float, list, tuple, or ndarray') if not np.isscalar(ref) and not isinstance(val, (list, tuple, np.ndarray, Iterable)): raise TypeError('The ref argument should be a float, list, tuple, or ndarray') if not np.isscalar(ref0) and not isinstance(val, (list, tuple, np.ndarray, Iterable)): raise TypeError('The ref0 argument should be a float, list, tuple, or ndarray') if not np.isscalar(res_ref) and not isinstance(val, (list, tuple, np.ndarray, Iterable)): raise TypeError('The res_ref argument should be a float, list, tuple, or ndarray') if shape is not None and not isinstance(shape, (int, tuple, list, np.integer)): raise TypeError("The shape argument should be an int, tuple, or list but " "a '%s' was given" % type(shape)) if units is not None and not isinstance(units, str): raise TypeError('The units argument should be a str or None') if res_units is not None and not isinstance(res_units, str): raise TypeError('The res_units argument should be a str or None') # Check that units are valid if units is not None and not valid_units(units): raise ValueError("The units '%s' are invalid" % units) metadata = {} # value, shape: based on args, making sure they are compatible metadata['value'], metadata['shape'] = ensure_compatible(name, val, shape) metadata['size'] = np.prod(metadata['shape']) # units, res_units: taken as is metadata['units'] = units metadata['res_units'] = res_units # desc: taken as is metadata['desc'] = desc if lower is not None: lower = ensure_compatible(name, lower, metadata['shape'])[0] if upper is not None: upper = ensure_compatible(name, upper, metadata['shape'])[0] metadata['lower'] = lower metadata['upper'] = upper # All refs: check the shape if necessary for item, item_name in zip([ref, ref0, res_ref], ['ref', 'ref0', 'res_ref']): if not np.isscalar(item): if np.atleast_1d(item).shape != metadata['shape']: raise ValueError('The %s argument has the wrong shape' % item_name) if np.isscalar(ref): self._has_output_scaling |= ref != 1.0 else: self._has_output_scaling |= np.any(ref != 1.0) if np.isscalar(ref0): self._has_output_scaling |= ref0 != 0.0 else: self._has_output_scaling |= np.any(ref0) if np.isscalar(res_ref): self._has_resid_scaling |= res_ref != 1.0 else: self._has_resid_scaling |= np.any(res_ref != 1.0) ref = format_as_float_or_array('ref', ref, flatten=True) ref0 = format_as_float_or_array('ref0', ref0, flatten=True) res_ref = format_as_float_or_array('res_ref', res_ref, flatten=True) # ref, ref0, res_ref: taken as is metadata['ref'] = ref metadata['ref0'] = ref0 metadata['res_ref'] = res_ref # var_set: taken as is metadata['var_set'] = var_set metadata['distributed'] = self.distributed # We may not know the pathname yet, so we have to use name for now, instead of abs_name. if self._static_mode: var_rel2data_io = self._static_var_rel2data_io var_rel_names = self._static_var_rel_names else: var_rel2data_io = self._var_rel2data_io var_rel_names = self._var_rel_names # Disallow dupes if name in var_rel2data_io: msg = "Variable name '{}' already exists.".format(name) raise ValueError(msg) var_rel2data_io[name] = { 'prom': name, 'rel': name, 'my_idx': len(self._var_rel_names['output']), 'type': 'output', 'metadata': metadata} var_rel_names['output'].append(name) return metadata
def add_input(self, name, val=1.0, shape=None, src_indices=None, flat_src_indices=None, units=None, desc='', var_set=0): """ Add an input variable to the component. Parameters ---------- name : str name of the variable in this component's namespace. val : float or list or tuple or ndarray or Iterable The initial value of the variable being added in user-defined units. Default is 1.0. shape : int or tuple or list or None Shape of this variable, only required if src_indices not provided and val is not an array. Default is None. src_indices : int or list of ints or tuple of ints or int ndarray or Iterable or None The global indices of the source variable to transfer data from. A value of None implies this input depends on all entries of source. Default is None. The shapes of the target and src_indices must match, and form of the entries within is determined by the value of 'flat_src_indices'. flat_src_indices : bool If True, each entry of src_indices is assumed to be an index into the flattened source. Otherwise each entry must be a tuple or list of size equal to the number of dimensions of the source. units : str or None Units in which this input variable will be provided to the component during execution. Default is None, which means it is unitless. desc : str description of the variable var_set : hashable object For advanced users only. ID or color for this variable, relevant for reconfigurability. Default is 0. Returns ------- dict metadata for added variable """ if units == 'unitless': warn_deprecation("Input '%s' has units='unitless' but 'unitless' " "has been deprecated. Use " "units=None instead. Note that connecting a " "unitless variable to one with units is no longer " "an error, but will issue a warning instead." % name) units = None # First, type check all arguments if not isinstance(name, str): raise TypeError('The name argument should be a string') if not np.isscalar(val) and not isinstance(val, (list, tuple, np.ndarray, Iterable)): raise TypeError('The val argument should be a float, list, tuple, ndarray or Iterable') if shape is not None and not isinstance(shape, (int, tuple, list, np.integer)): raise TypeError("The shape argument should be an int, tuple, or list but " "a '%s' was given" % type(shape)) if src_indices is not None and not isinstance(src_indices, (int, list, tuple, np.ndarray, Iterable)): raise TypeError('The src_indices argument should be an int, list, ' 'tuple, ndarray or Iterable') if units is not None and not isinstance(units, str): raise TypeError('The units argument should be a str or None') # Check that units are valid if units is not None and not valid_units(units): raise ValueError("The units '%s' are invalid" % units) metadata = {} # value, shape: based on args, making sure they are compatible metadata['value'], metadata['shape'] = ensure_compatible(name, val, shape, src_indices) metadata['size'] = np.prod(metadata['shape']) # src_indices: None or ndarray if src_indices is None: metadata['src_indices'] = None else: metadata['src_indices'] = np.atleast_1d(src_indices) metadata['flat_src_indices'] = flat_src_indices # units: taken as is metadata['units'] = units # desc: taken as is metadata['desc'] = desc # var_set: taken as is metadata['var_set'] = var_set # We may not know the pathname yet, so we have to use name for now, instead of abs_name. if self._static_mode: var_rel2data_io = self._static_var_rel2data_io var_rel_names = self._static_var_rel_names else: var_rel2data_io = self._var_rel2data_io var_rel_names = self._var_rel_names # Disallow dupes if name in var_rel2data_io: msg = "Variable name '{}' already exists.".format(name) raise ValueError(msg) var_rel2data_io[name] = { 'prom': name, 'rel': name, 'my_idx': len(self._var_rel_names['input']), 'type': 'input', 'metadata': metadata} var_rel_names['input'].append(name) return metadata
def add_output(self, name, val=1.0, shape=None, units=None, res_units=None, desc='', lower=None, upper=None, ref=None, ref0=None, res_ref=None, tags=None, shape_by_conn=False, copy_shape=None): """ Add an independent variable to this component. This should never be called by a user, as it skips all checks. Parameters ---------- name : str name of the variable in this component's namespace. val : float or list or tuple or ndarray The initial value of the variable being added in user-defined units. Default is 1.0. shape : int or tuple or list or None Shape of this variable, only required if val is not an array. Default is None. units : str or None Units in which the output variables will be provided to the component during execution. Default is None, which means it has no units. res_units : None This argument is deprecated because it was unused. desc : str description of the variable lower : None This argument is deprecated because it was unused. upper : None This argument is deprecated because it was unused. ref : None This argument is deprecated because it was unused. ref0 : None This argument is deprecated because it was unused. res_ref : None This argument is deprecated because it was unused. tags : str or list of strs User defined tags that can be used to filter what gets listed when calling list_outputs. shape_by_conn : bool If True, shape this output to match its connected input(s). copy_shape : str or None If a str, that str is the name of a variable. Shape this output to match that of the named variable. """ # Add the output quickly. # We don't need to check for errors because we get the value straight from a # source, and ivc metadata is minimal. value, shape, _ = ensure_compatible(name, val, None) metadata = { 'value': value, 'shape': shape, 'size': shape_to_len(shape), 'units': units, 'res_units': None, 'desc': '', 'distributed': False, 'tags': set(), 'ref': 1.0, 'ref0': 0.0, 'res_ref': 1.0, 'lower': None, 'upper': None, 'shape_by_conn': False, 'copy_shape': None } self._static_var_rel2meta[name] = metadata self._static_var_rel_names['output'].append(name) self._var_added(name)
def add_output(self, name, val=1.0, shape=None, units=None, res_units=None, desc='', lower=None, upper=None, ref=1.0, ref0=0.0, res_ref=1.0): """ Add an output variable to the component. Parameters ---------- name : str name of the variable in this component's namespace. val : float or list or tuple or ndarray The initial value of the variable being added in user-defined units. Default is 1.0. shape : int or tuple or list or None Shape of this variable, only required if val is not an array. Default is None. units : str or None Units in which the output variables will be provided to the component during execution. Default is None, which means it has no units. res_units : str or None Units in which the residuals of this output will be given to the user when requested. Default is None, which means it has no units. desc : str description of the variable. lower : float or list or tuple or ndarray or Iterable or None lower bound(s) in user-defined units. It can be (1) a float, (2) an array_like consistent with the shape arg (if given), or (3) an array_like matching the shape of val, if val is array_like. A value of None means this output has no lower bound. Default is None. upper : float or list or tuple or ndarray or or Iterable None upper bound(s) in user-defined units. It can be (1) a float, (2) an array_like consistent with the shape arg (if given), or (3) an array_like matching the shape of val, if val is array_like. A value of None means this output has no upper bound. Default is None. ref : float or ndarray Scaling parameter. The value in the user-defined units of this output variable when the scaled value is 1. Default is 1. ref0 : float or ndarray Scaling parameter. The value in the user-defined units of this output variable when the scaled value is 0. Default is 0. res_ref : float or ndarray Scaling parameter. The value in the user-defined res_units of this output's residual when the scaled value is 1. Default is 1. Returns ------- dict metadata for added variable """ if units == 'unitless': warn_deprecation("Output '%s' has units='unitless' but 'unitless' " "has been deprecated. Use " "units=None instead. Note that connecting a " "unitless variable to one with units is no longer " "an error, but will issue a warning instead." % name) units = None if not isinstance(name, str): raise TypeError('The name argument should be a string') if not _valid_var_name(name): raise NameError("'%s' is not a valid output name." % name) if not isscalar(val) and not isinstance(val, (list, tuple, ndarray, Iterable)): msg = 'The val argument should be a float, list, tuple, ndarray or Iterable' raise TypeError(msg) if not isscalar(ref) and not isinstance(val, (list, tuple, ndarray, Iterable)): msg = 'The ref argument should be a float, list, tuple, ndarray or Iterable' raise TypeError(msg) if not isscalar(ref0) and not isinstance(val, (list, tuple, ndarray, Iterable)): msg = 'The ref0 argument should be a float, list, tuple, ndarray or Iterable' raise TypeError(msg) if not isscalar(res_ref) and not isinstance(val, (list, tuple, ndarray, Iterable)): msg = 'The res_ref argument should be a float, list, tuple, ndarray or Iterable' raise TypeError(msg) if shape is not None and not isinstance(shape, (int, tuple, list, np.integer)): raise TypeError("The shape argument should be an int, tuple, or list but " "a '%s' was given" % type(shape)) if units is not None and not isinstance(units, str): raise TypeError('The units argument should be a str or None') if res_units is not None and not isinstance(res_units, str): raise TypeError('The res_units argument should be a str or None') # Check that units are valid if units is not None and not valid_units(units): raise ValueError("The units '%s' are invalid" % units) metadata = {} # value, shape: based on args, making sure they are compatible metadata['value'], metadata['shape'], _ = ensure_compatible(name, val, shape) metadata['size'] = np.prod(metadata['shape']) # units, res_units: taken as is metadata['units'] = units metadata['res_units'] = res_units # desc: taken as is metadata['desc'] = desc if lower is not None: lower = ensure_compatible(name, lower, metadata['shape'])[0] if upper is not None: upper = ensure_compatible(name, upper, metadata['shape'])[0] metadata['lower'] = lower metadata['upper'] = upper # All refs: check the shape if necessary for item, item_name in zip([ref, ref0, res_ref], ['ref', 'ref0', 'res_ref']): if not isscalar(item): it = atleast_1d(item) if it.shape != metadata['shape']: raise ValueError("'{}': When adding output '{}', expected shape {} but got " "shape {} for argument '{}'.".format(self.name, name, metadata['shape'], it.shape, item_name)) if isscalar(ref): self._has_output_scaling |= ref != 1.0 else: self._has_output_scaling |= np.any(ref != 1.0) if isscalar(ref0): self._has_output_scaling |= ref0 != 0.0 else: self._has_output_scaling |= np.any(ref0) if isscalar(res_ref): self._has_resid_scaling |= res_ref != 1.0 else: self._has_resid_scaling |= np.any(res_ref != 1.0) ref = format_as_float_or_array('ref', ref, flatten=True) ref0 = format_as_float_or_array('ref0', ref0, flatten=True) res_ref = format_as_float_or_array('res_ref', res_ref, flatten=True) metadata['ref'] = ref metadata['ref0'] = ref0 metadata['res_ref'] = res_ref metadata['distributed'] = self.options['distributed'] # We may not know the pathname yet, so we have to use name for now, instead of abs_name. if self._static_mode: var_rel2meta = self._static_var_rel2meta var_rel_names = self._static_var_rel_names else: var_rel2meta = self._var_rel2meta var_rel_names = self._var_rel_names # Disallow dupes if name in var_rel2meta: msg = "Variable name '{}' already exists.".format(name) raise ValueError(msg) var_rel2meta[name] = metadata var_rel_names['output'].append(name) return metadata
def add_input(self, name, val=1.0, shape=None, src_indices=None, flat_src_indices=None, units=None, desc=''): """ Add an input variable to the component. Parameters ---------- name : str name of the variable in this component's namespace. val : float or list or tuple or ndarray or Iterable The initial value of the variable being added in user-defined units. Default is 1.0. shape : int or tuple or list or None Shape of this variable, only required if src_indices not provided and val is not an array. Default is None. src_indices : int or list of ints or tuple of ints or int ndarray or Iterable or None The global indices of the source variable to transfer data from. A value of None implies this input depends on all entries of source. Default is None. The shapes of the target and src_indices must match, and form of the entries within is determined by the value of 'flat_src_indices'. flat_src_indices : bool If True, each entry of src_indices is assumed to be an index into the flattened source. Otherwise each entry must be a tuple or list of size equal to the number of dimensions of the source. units : str or None Units in which this input variable will be provided to the component during execution. Default is None, which means it is unitless. desc : str description of the variable Returns ------- dict metadata for added variable """ if units == 'unitless': warn_deprecation("Input '%s' has units='unitless' but 'unitless' " "has been deprecated. Use " "units=None instead. Note that connecting a " "unitless variable to one with units is no longer " "an error, but will issue a warning instead." % name) units = None # First, type check all arguments if not isinstance(name, str): raise TypeError('The name argument should be a string') if not _valid_var_name(name): raise NameError("'%s' is not a valid input name." % name) if not isscalar(val) and not isinstance(val, (list, tuple, ndarray, Iterable)): raise TypeError('The val argument should be a float, list, tuple, ndarray or Iterable') if shape is not None and not isinstance(shape, (int, tuple, list, np.integer)): raise TypeError("The shape argument should be an int, tuple, or list but " "a '%s' was given" % type(shape)) if src_indices is not None and not isinstance(src_indices, (int, list, tuple, ndarray, Iterable)): raise TypeError('The src_indices argument should be an int, list, ' 'tuple, ndarray or Iterable') if units is not None and not isinstance(units, str): raise TypeError('The units argument should be a str or None') # Check that units are valid if units is not None and not valid_units(units): raise ValueError("The units '%s' are invalid" % units) metadata = {} # value, shape: based on args, making sure they are compatible metadata['value'], metadata['shape'], src_indices = ensure_compatible(name, val, shape, src_indices) metadata['size'] = np.prod(metadata['shape']) # src_indices: None or ndarray if src_indices is None: metadata['src_indices'] = None else: metadata['src_indices'] = np.asarray(src_indices, dtype=INT_DTYPE) metadata['flat_src_indices'] = flat_src_indices metadata['units'] = units metadata['desc'] = desc metadata['distributed'] = self.options['distributed'] # We may not know the pathname yet, so we have to use name for now, instead of abs_name. if self._static_mode: var_rel2meta = self._static_var_rel2meta var_rel_names = self._static_var_rel_names else: var_rel2meta = self._var_rel2meta var_rel_names = self._var_rel_names # Disallow dupes if name in var_rel2meta: msg = "Variable name '{}' already exists.".format(name) raise ValueError(msg) var_rel2meta[name] = metadata var_rel_names['input'].append(name) return metadata