예제 #1
0
    def __init__(self, comp1, outlet_id, comp2, inlet_id, **kwargs):

        # check input parameters
        if not (isinstance(comp1, component) and
                isinstance(comp2, component)):
            msg = ('Error creating connection. Check if comp1, comp2 are of '
                   'type component.')
            logging.error(msg)
            raise TypeError(msg)

        if comp1 == comp2:
            msg = ('Error creating connection. Cannot connect component ' +
                   comp1.label + ' to itself.')
            logging.error(msg)
            raise TESPyConnectionError(msg)

        if outlet_id not in comp1.outlets():
            msg = ('Error creating connection. Specified oulet_id (' +
                   outlet_id + ') is not valid for component ' +
                   comp1.component() + '. Valid ids are: ' +
                   str(comp1.outlets()) + '.')
            logging.error(msg)
            raise ValueError(msg)

        if inlet_id not in comp2.inlets():
            msg = (
                'Error creating connection. Specified inlet_id (' + inlet_id +
                ') is not valid for component ' + comp2.component() +
                '. Valid ids are: ' + str(comp2.inlets()) + '.')
            logging.error(msg)
            raise ValueError(msg)

        self.label = (
            comp1.label + ':' + outlet_id + '_' + comp2.label + ':' + inlet_id)

        # set specified values
        self.source = comp1
        self.source_id = outlet_id
        self.target = comp2
        self.target_id = inlet_id

        # defaults
        self.new_design = True
        self.design_path = None
        self.design = []
        self.offdesign = []
        self.local_design = False
        self.local_offdesign = False
        self.printout = True

        # set default values for kwargs
        self.variables = self.attr()
        self.variables0 = [x + '0' for x in self.variables.keys()]
        self.__dict__.update(self.variables)
        self.set_attr(**kwargs)

        msg = (
            'Created connection ' + self.source.label + ' (' + self.source_id +
            ') -> ' + self.target.label + ' (' + self.target_id + ').')
        logging.debug(msg)
예제 #2
0
 def __init__(self, *args, **kwargs):
     msg = ('Version 0.4.x introduced PEP 8 conform class names for all '
            'classes used in TESPy. Please refer to '
            'https://tespy.readthedocs.io/en/master/whats_new.html '
            'learn about the changes necessary to adapt your script to the '
            'latest API.')
     logging.error(msg)
     raise TESPyConnectionError(msg)
예제 #3
0
    def __init__(self, comp1, outlet_id, comp2, inlet_id, **kwargs):

        # check input parameters
        if not (isinstance(comp1, cmp.component)
                and isinstance(comp2, cmp.component)):
            msg = ('Error creating connection. Check if comp1, comp2 are of '
                   'type component.')
            logging.error(msg)
            raise TypeError(msg)

        if comp1 == comp2:
            msg = ('Error creating connection. Can\'t connect component ' +
                   comp1.label + ' to itself.')
            logging.error(msg)
            raise TESPyConnectionError(msg)

        if outlet_id not in comp1.outlets():
            msg = ('Error creating connection. Specified oulet_id (' +
                   outlet_id + ') is not valid for component ' +
                   comp1.component() + '. Valid ids are: ' +
                   str(comp1.outlets()) + '.')
            logging.error(msg)
            raise ValueError(msg)

        if inlet_id not in comp2.inlets():
            msg = ('Error creating connection. Specified inlet_id (' +
                   inlet_id + ') is not valid for component ' +
                   comp2.component() + '. Valid ids are: ' +
                   str(comp2.inlets()) + '.')
            logging.error(msg)
            raise ValueError(msg)

        # set specified values
        self.s = comp1
        self.s_id = outlet_id
        self.t = comp2
        self.t_id = inlet_id

        # defaults
        self.new_design = True
        self.design_path = None
        self.design = []
        self.offdesign = []
        self.local_design = False
        self.local_offdesign = False

        # set default values for kwargs
        var = self.attr()

        for key in self.attr().keys():
            self.__dict__.update({key: var[key]})

        self.set_attr(**kwargs)

        msg = ('Created connection ' + self.s.label + ' (' + self.s_id +
               ') -> ' + self.t.label + ' (' + self.t_id + ').')
        logging.debug(msg)
예제 #4
0
    def add_comps(self, *args):
        r"""
        Add components to a bus.

        Parameters
        ----------
        c : dict
            Dictionary containing the component information to be added to the bus.
            These information are described in the notes!

        Note
        ----
        Keys for the dictionary c:

        - c (tespy.components.components.component): Component you want to add to the bus.
        - p (str): Bus parameter, optional.

            - You do not need to provide a parameter, if the component only has one
              option for the bus (turbomachines, heat exchangers, combustion
              chamber).
            - For instance, you do neet do provide a parameter, if you want to add
              a cogeneration unit ('Q', 'Q1', 'Q2', 'TI', 'P', 'Qloss').

        - char (float/tespy.components.characteristics.characteristics):
          Characteristic function for this components share to the bus value, optional.

            - If you do not provide a characteristic line at all, TESPy assumes a
              constant factor of 1.
            - If you provide a numeric value instead of a characteristic line,
              TESPy takes this numeric value as a constant factor.
            - Provide a TESPy.characteristic (cmp_char), if you want the factor
              to follow a characteristic line.

        - P_ref (float): Energy flow specification for reference case, :math:`P \text{/W}`, optional.
        """
        for c in args:
            if isinstance(c, dict):
                if 'c' in c.keys():
                    if isinstance(c['c'], cmp.component):
                        self.comps.loc[c['c']] = [None, np.nan, self.char]
                    else:
                        msg = ('Keyword c must hold a TESPy component.')
                        logging.error(msg)
                        raise TypeError(msg)
                else:
                    msg = ('You must provide the component c.')
                    logging.error(msg)
                    raise TypeError(msg)

                for k, v in c.items():
                    if k == 'p':
                        if isinstance(v, str) or v is None:
                            self.comps.loc[c['c']]['param'] = v
                        else:
                            msg = ('Parameter p must be a string.')
                            logging.error(msg)
                            raise TypeError(msg)

                    elif k == 'char':
                        if isinstance(v, cmp_char.characteristics):
                            self.comps.loc[c['c']]['char'] = v
                        elif (isinstance(v, float)
                              or isinstance(v, np.float64)
                              or isinstance(v, np.int64)
                              or isinstance(v, int)):
                            x = np.array([0, 1, 2, 3])
                            y = np.array([1, 1, 1, 1]) * v
                            self.comps.loc[c['c']]['char'] = (
                                cmp_char.characteristics(x=x, y=y))
                        else:
                            msg = (
                                'Char must be a number or a TESPy characteristics.'
                            )
                            logging.error(msg)
                            raise TypeError(msg)

                    elif k == 'P_ref':
                        if (v is None or isinstance(v, float)
                                or isinstance(v, np.float64)
                                or isinstance(v, np.int64)
                                or isinstance(v, int)):
                            self.comps.loc[c['c']]['P_ref'] = v
                        else:
                            msg = ('Reference value must be numeric.')
                            logging.error(msg)
                            raise TypeError(msg)
            else:
                msg = (
                    'Provide arguments as dicts. See the documentation of bus.add_comps() for more information.'
                )
                logging.error(msg)
                raise TESPyConnectionError(msg)

            msg = 'Added component ' + c[
                'c'].label + ' to bus ' + self.label + '.'
            logging.debug(msg)
예제 #5
0
    def set_attr(self, **kwargs):
        r"""
        Set, reset or unset attributes of a connection.

        Parameters
        ----------
        m : float, tespy.connections.connection.Ref
            Mass flow specification.

        m0 : float
            Starting value specification for mass flow.

        p : float, tespy.connections.connection.Ref
            Pressure specification.

        p0 : float
            Starting value specification for pressure.

        h : float, tespy.connections.connection.Ref
            Enthalpy specification.

        h0 : float
            Starting value specification for enthalpy.

        fluid : dict
            Fluid compostition specification.

        fluid0 : dict
            Starting value specification for fluid compostition.

        fluid_balance : boolean
            Fluid balance equation specification.

        x : float
            Gas phase mass fraction specification.

        T : float, tespy.connections.connection.Ref
            Temperature specification.

        Td_bp : float
            Temperature difference to boiling point at pressure corresponding
            pressure of this connection in K.

        v : float
            Volumetric flow specification.

        state : str
            State of the pure fluid on this connection: liquid ('l') or gaseous
            ('g').

        design : list
            List containing design parameters (stated as string).

        offdesign : list
            List containing offdesign parameters (stated as string).

        design_path : str
            Path to individual design case for this connection.

        local_offdesign : boolean
            Treat this connection in offdesign mode in a design calculation.

        local_design : boolean
            Treat this connection in design mode in an offdesign calculation.

        printout : boolean
            Include this connection in the network's results printout.

        Note
        ----
        - The fluid balance parameter applies a balancing of the fluid vector
          on the specified conntion to 100 %. For example, you have four fluid
          components (a, b, c and d) in your vector, you set two of them
          (a and b) and want the other two (components c and d) to be a result
          of your calculation. If you set this parameter to True, the equation
          (0 = 1 - a - b - c - d) will be applied.
        - The specification of values for design and/or offdesign is used for
          automatic switch from design to offdesign calculation: All parameters
          given in 'design', e.g. :code:`design=['T', 'p']`, are unset in any
          offdesign calculation, parameters given in 'offdesign' are set for
          offdesign calculation.
        - The property state is applied on pure fluids only. If you specify the
          desired state of the fluid at a connection the convergence check will
          adjust the enthalpy values of that connection for the first
          iterations in order to meet the state requirement.
        """
        # set specified values
        for key in kwargs:
            if key == 'label':
                # bad datatype
                msg = 'Label can only be specified on instance creation.'
                logging.error(msg)
                raise TESPyConnectionError(msg)
            elif key in self.variables or key in self.variables0:
                # fluid specification
                try:
                    float(kwargs[key])
                    is_numeric = True
                except (TypeError, ValueError):
                    is_numeric = False
                if 'fluid' in key and key != 'fluid_balance':
                    if isinstance(kwargs[key], dict):
                        # starting values
                        if key in self.variables0:
                            self.fluid.set_attr(val0=kwargs[key].copy())
                        # specified parameters
                        else:
                            self.fluid.set_attr(val=kwargs[key].copy())
                            self.fluid.set_attr(
                                val_set={f: True
                                         for f in kwargs[key].keys()})

                    else:
                        # bad datatype
                        msg = (
                            'Datatype for fluid vector specification must be '
                            'dict.')
                        logging.error(msg)
                        raise TypeError(msg)

                elif key == 'state':
                    if kwargs[key] in ['l', 'g']:
                        self.state.set_attr(val=kwargs[key], is_set=True)
                    elif kwargs[key] is None:
                        self.state.set_attr(is_set=False)
                    elif is_numeric:
                        if np.isnan(kwargs[key]):
                            self.get_attr(key).set_attr(is_set=False)
                        else:
                            msg = (
                                'To unset the state specification either use '
                                'np.nan or None.')
                            logging.error(msg)
                            raise ValueError(msg)
                    else:
                        msg = ('Keyword argument "state" must either be '
                               '"l" or "g" or be None or np.nan.')
                        logging.error(msg)
                        raise TypeError(msg)

                elif kwargs[key] is None:
                    self.get_attr(key).set_attr(val_set=False)
                    self.get_attr(key).set_attr(ref_set=False)

                elif is_numeric:
                    if np.isnan(kwargs[key]):
                        self.get_attr(key).set_attr(val_set=False)
                        self.get_attr(key).set_attr(ref_set=False)
                    else:
                        # value specification
                        if key in self.variables:
                            self.get_attr(key).set_attr(val_set=True,
                                                        val=kwargs[key])
                        # starting value specification
                        else:
                            self.get_attr(key.replace(
                                '0', '')).set_attr(val0=kwargs[key])

                # reference object
                elif isinstance(kwargs[key], Ref):
                    if key in ['x', 'v', 'Td_bp']:
                        msg = ('References for volumetric flow, vapor mass '
                               'fraction and subcooling/superheating are not '
                               'implemented.')
                        logging.error(msg)
                        raise NotImplementedError(msg)
                    else:
                        self.get_attr(key).set_attr(ref=kwargs[key])
                        self.get_attr(key).set_attr(ref_set=True)

                # invalid datatype for keyword
                else:
                    msg = 'Bad datatype for keyword argument ' + key + '.'
                    logging.error(msg)
                    raise TypeError(msg)

            # fluid balance
            elif key == 'fluid_balance':
                if isinstance(kwargs[key], bool):
                    self.get_attr('fluid').set_attr(balance=kwargs[key])
                else:
                    msg = (
                        'Datatype for keyword argument fluid_balance must be '
                        'boolean.')
                    logging.error(msg)
                    raise TypeError(msg)

            # design/offdesign parameter list
            elif key == 'design' or key == 'offdesign':
                if not isinstance(kwargs[key], list):
                    msg = 'Please provide the ' + key + ' parameters as list!'
                    logging.error(msg)
                    raise TypeError(msg)
                elif set(kwargs[key]).issubset(self.variables.keys()):
                    self.__dict__.update({key: kwargs[key]})
                else:
                    params = ', '.join(self.variables.keys())
                    msg = (
                        'Available parameters for (off-)design specification '
                        'are: ' + params + '.')
                    logging.error(msg)
                    raise ValueError(msg)

            # design path
            elif key == 'design_path':
                if isinstance(kwargs[key], str):
                    self.__dict__.update({key: kwargs[key]})
                elif np.isnan(kwargs[key]):
                    self.design_path = None
                else:
                    msg = (
                        'Please provide the design_path parameter as string '
                        'or as nan.')
                    logging.error(msg)
                    raise TypeError(msg)

                self.new_design = True

            # other boolean keywords
            elif key in ['printout', 'local_design', 'local_offdesign']:
                if not isinstance(kwargs[key], bool):
                    msg = ('Please provide the ' + key + ' as boolean.')
                    logging.error(msg)
                    raise TypeError(msg)
                else:
                    self.__dict__.update({key: kwargs[key]})

            # invalid keyword
            else:
                msg = 'Connection has no attribute ' + key + '.'
                logging.error(msg)
                raise KeyError(msg)