def test_stream_states_dict(m): d = stream_states_dict(arcs_to_stream_dict(m, descend_into=True)) assert "stream" in d assert "stream_array[0]" in d assert "stream_array[1]" in d assert d["stream_array[0]"] == m.fs.tank_array[1].control_volume.properties_in[0] assert d["stream_array[1]"] == m.fs.tank_array[2].control_volume.properties_in[0]
def serialize_flowsheet(self): """Stores information on the connectivity and components of the input flowsheet. """ for component in self.flowsheet.component_objects(Arc, descend_into=False): self.arcs[component.getname()] = component self._known_endpoints.add(component.source.parent_block()) self._known_endpoints.add(component.dest.parent_block()) for component in self.flowsheet.component_objects(Block, descend_into=True): # TODO try using component_objects(ctype=X) if isinstance(component, UnitModelBlockData): self._add_unit_model_with_ports(component) else: # some unit models are nested within Indexed blocks component_object_op = getattr(component, "component_object", None) if not callable(component_object_op): for item in component.parent_component().values(): if isinstance(item, UnitModelBlockData): if any((item == arc.source.parent_block() or item == arc.dest.parent_block()) for arc in self.arcs.values()): self._add_unit_model_with_ports(item) print(f'sub-indexed: {item.getname()}') for stream_name, stream_value in stream_states_dict(self.arcs).items(): label = "" for var, var_value in stream_value.define_display_vars().items(): var = var.capitalize() for k, v in var_value.items(): if k is None: label += f"{var} {value(v)}\n" else: label += f"{var} {k} {value(v)}\n" self.labels[stream_name] = label[:-2] used_ports = set() self.edges = {} # TODO: necessary? do the attributes need clearing? for name, arc in self.arcs.items(): try: # this is currently(?) necessary because for internally-nested arcs we may not record ports? self.edges[name] = { "source": self.ports[arc.source], "dest": self.ports[arc.dest] } self._logger.info( f'source: {arc.source}; val: {self.ports[arc.source]}') used_ports.add(arc.source) used_ports.add(arc.dest) except KeyError as error: self._logger.error( f"Unable to find port. {name}, {arc.source}, {arc.dest}") # note we're only using the keys from self.ports, {port: parentcomponent} untouched_ports = set(self.ports) - used_ports self._identify_implicit_inlets_and_outlets(untouched_ports)
def _construct_stream_labels(self): # Construct the stream labels # We might have this information from generating self.serialized_components but I (Makayla) don't # know how that connects to the stream names so this will be left alone for now for stream_name, stream_value in stream_states_dict(self.arcs).items(): label = "" for var, var_value in stream_value.define_display_vars().items(): var = var.capitalize() for k, v in var_value.items(): if k is None: label += f"{var} {value(v)}\n" else: label += f"{var} {k} {value(v)}\n" self.labels[stream_name] = label[:-2]
def create_stream_dict(m): """Create a dictionary of stream states. This mostly uses Arc names, but inlet and outlet streams don't have associated Arcs, so those need to be set manually. """ streams = tables.arcs_to_stream_dict( m.fs_main, descend_into=False, additional={ "S002": m.fs_main.fs_stc.turb.inlet_stage[1].inlet, "S007": m.fs_main.fs_stc.turb.hp_split[14].outlet_3, "S012": m.fs_main.fs_stc.turb.lp_stages[1].inlet, "S050b": m.fs_main.fs_stc.condenser_hotwell.makeup, "S050": m.fs_main.fs_stc.makeup_valve.inlet, "S018": m.fs_main.fs_stc.condenser.tube.properties_in, "S020": m.fs_main.fs_stc.condenser.tube.properties_out, "S048": m.fs_main.fs_stc.aux_condenser.tube.properties_in, "S049": m.fs_main.fs_stc.aux_condenser.tube.properties_out, "SA02": m.fs_main.fs_blr.aAPH.side_3_inlet, "PA03": m.fs_main.fs_blr.aAPH.side_2_inlet, "TA02": m.fs_main.fs_blr.Mixer_PA.TA_inlet, "FG06": m.fs_main.fs_blr.aAPH.side_1_outlet, "B020": m.fs_main.fs_blr.blowdown_split.FW_Blowdown, }) tables.arcs_to_stream_dict(m.fs_main.fs_blr, s=streams) tables.arcs_to_stream_dict(m.fs_main.fs_stc, s=streams, descend_into=False) tables.arcs_to_stream_dict(m.fs_main.fs_stc.turb, s=streams) tables.arcs_to_stream_dict(m.fs_main.fs_stc.fwh1, s=streams, prepend="fwh1") tables.arcs_to_stream_dict(m.fs_main.fs_stc.fwh2, s=streams, prepend="fwh2") tables.arcs_to_stream_dict(m.fs_main.fs_stc.fwh3, s=streams, prepend="fwh3") tables.arcs_to_stream_dict(m.fs_main.fs_stc.fwh5, s=streams, prepend="fwh5") tables.arcs_to_stream_dict(m.fs_main.fs_stc.fwh6, s=streams, prepend="fwh6") return tables.stream_states_dict(streams, 0)
def _construct_stream_labels(self): # Construct the stream labels from idaes.core.util.tables import ( stream_states_dict, ) # deferred to avoid circ. import # We might have this information from generating self.serialized_components but I (Makayla) don't # know how that connects to the stream names so this will be left alone for now for stream_name, stream_value in stream_states_dict(self.arcs).items(): label = "" for var, var_value in stream_value.define_display_vars().items(): var = var.capitalize() for k, v in var_value.items(): if k is None: label += f"{var} {round(value(v), self._sig_figs)}\n" else: label += f"{var} {k} {round(value(v), self._sig_figs)}\n" self.labels[stream_name] = label[:-2]
def tag_model(m): """ Create to dictionaries. One is called tags with tags for keys and expressions for values. The second is called tag_format with tags for keys and a formatting string. The formating string controls the number format and can be used to add additional text, to report units for example. The two dictionaries are returned, and also attached to the model. Args: m: (ConcreteModel) model to tag Returns: (dict) tags, (dict) tag_format """ assert m.name == "Gas Turbine Model" tags = {} # dict of with tag keys and expressions for their values tag_format = {} # format string for the tags def new_tag(name, expr, format): # funcion to keep it more compact tags[name] = expr tag_format[name] = format # Create a dict with Arc name keys and state block values stream_states = tables.stream_states_dict( tables.arcs_to_stream_dict(m.fs, descend_into=False)) for i, s in stream_states.items(): # create the tags for steam quantities new_tag(f"{i}_Fvol", expr=s.flow_vol, format="{:.1f} m^3/s") new_tag(f"{i}_Fmol", expr=s.flow_mol/1000, format="{:.3f} kmol/s") new_tag(f"{i}_F", expr=s.flow_mass, format="{:.3f} kg/s") new_tag(f"{i}_P", expr=s.pressure/1000, format="{:.3f} kPa") new_tag(f"{i}_T", expr=s.temperature, format="{:.2f} K") for c in s.mole_frac_comp: new_tag(f"{i}_y{c}", expr=s.mole_frac_comp[c]*100, format="{:.3f}%") # Tags for non-stream things new_tag( "cmp1_power", expr=m.fs.cmp1.control_volume.work[0]/1e6, format="{:.2f} MW") new_tag( "gts1_power", expr=m.fs.gts1.control_volume.work[0]/1e6, format="{:.2f} MW") new_tag( "gts2_power", expr=m.fs.gts2.control_volume.work[0]/1e6, format="{:.2f} MW") new_tag( "gts3_power", expr=m.fs.gts3.control_volume.work[0]/1e6, format="{:.2f} MW") new_tag( "cmp1_head_isen", expr=m.fs.cmp1.performance_curve.head_isentropic[0]/1000, format="{:.2f} kJ/kg") new_tag( "gts1_head_isen", expr=m.fs.gts1.performance_curve.head_isentropic[0]/1000, format="{:.2f} kJ/kg") new_tag( "gts2_head_isen", expr=m.fs.gts2.performance_curve.head_isentropic[0]/1000, format="{:.2f} kJ/kg") new_tag( "gts3_head_isen", expr=m.fs.gts3.performance_curve.head_isentropic[0]/1000, format="{:.2f} kJ/kg") new_tag( "cmp1_eff_isen", expr=m.fs.cmp1.efficiency_isentropic[0]*100, format="{:.2f}%") new_tag( "gts1_eff_isen", expr=m.fs.gts1.efficiency_isentropic[0]*100, format="{:.2f}%") new_tag( "gts2_eff_isen", expr=m.fs.gts2.efficiency_isentropic[0]*100, format="{:.2f}%") new_tag( "gts3_eff_isen", expr=m.fs.gts3.efficiency_isentropic[0]*100, format="{:.2f}%") new_tag( "valve01_opening", expr=m.fs.valve01.valve_opening[0]*100, format="{:.2f}%") new_tag( "valve02_opening", expr=m.fs.valve02.valve_opening[0]*100, format="{:.2f}%") new_tag( "valve03_opening", expr=m.fs.valve03.valve_opening[0]*100, format="{:.2f}%") new_tag( "gt_total_power", expr=m.fs.gt_power[0]/1e6, format="{:.2f} MW") m.tags = tags m.tag_format = tag_format return tags, tag_format