Question-and-Answer Resource for the Building Energy Modeling Community
Get started with the Help page
Ask Your Question

Revision history [back]

For those that are working on radiant cooling panels modeling, I have written an energyplus measure codes to fix the issue.

def get_tzone_of_rad_clg_pnls(rad_pnls: list[openstudio.WorkspaceObject], workspace: openstudio.Workspace) -> dict:
            # get all rad pnl in the starting workspace
            rad_pnl_dicts = {}
            for rad_pnl in rad_pnls:
                rad_name_ = rad_pnl.getString(0)
                frac_rad_on_ppl_ = rad_pnl.getString(18)
                if rad_name_.is_initialized():
                    rad_name = rad_name_.get()
                    rad_pnl_dicts[rad_name] = {'idf_obj': rad_pnl}
                if frac_rad_on_ppl_.is_initialized():
                    frac_rad_on_ppl = float(frac_rad_on_ppl_.get())
                    rad_pnl_dicts[rad_name]['frac_rad_on_ppl'] = frac_rad_on_ppl

            # get all the zonehvac equip list
            rad_pnl_names = rad_pnl_dicts.keys()
            zhvac_equip_lss = workspace.getObjectsByType('ZoneHVAC:EquipmentList')
            for zhvac_equip_ls in zhvac_equip_lss:
                ext_grps = zhvac_equip_ls.extensibleGroups()
                for ext_grp in ext_grps:
                    zequip_obj_type = str(ext_grp.getString(0))
                    if zequip_obj_type == 'ZoneHVAC:CoolingPanel:RadiantConvective:Water':
                        zequip_name = str(ext_grp.getString(1))
                        if zequip_name in rad_pnl_names:
                            rad_pnl_dicts[zequip_name]['zone_hvac_equip_list'] = str(zhvac_equip_ls.getString(0))

            # get all the zonehvac equip connections and get the zone name 
            zhvac_equip_conns = workspace.getObjectsByType('ZoneHVAC:EquipmentConnections')
            for zhvac_equip_conn in zhvac_equip_conns:
                equip_ls_name = str(zhvac_equip_conn.getString(1))
                for rad_pnl_name in rad_pnl_names:
                    equip_ls_name_ref = rad_pnl_dicts[rad_pnl_name]['zone_hvac_equip_list']
                    if equip_ls_name == equip_ls_name_ref:
                        tzone_name = str(zhvac_equip_conn.getString(0))
                        rad_pnl_dicts[rad_pnl_name]['thermal_zone_name'] = tzone_name
                        break

            return rad_pnl_dicts

def run( self, workspace: openstudio.Workspace,
            runner: openstudio.measure.OSRunner,
            user_arguments: openstudio.measure.OSArgumentMap,):
            """Defines what happens when the measure is run."""
            super().run(workspace, runner, user_arguments)  # Do **NOT** remove this line

            if not (runner.validateUserArguments(self.arguments(workspace), user_arguments)):
                return False

            rad_pnls = workspace.getObjectsByType('ZoneHVAC:CoolingPanel:RadiantConvective:Water')
            # get which thermal zone the radiant panel 
            rad_pnl_dicts = get_tzone_of_rad_clg_pnls(rad_pnls, workspace, runner)
            # report initial condition of workspace
            runner.registerInitialCondition(f"The building has {len(rad_pnls)} rad_panels")
            # reverse translate the idf into osmod
            rev_translate = openstudio.energyplus.ReverseTranslator()
            osmod = rev_translate.translateWorkspace(workspace)
            # get all the thermal zones
            thermal_zones = osmod.getThermalZones()
            rad_pnl_names = rad_pnl_dicts.keys()
            for rad_pnl_name in rad_pnl_names:
                thermal_zone_name_ref = rad_pnl_dicts[rad_pnl_name]['thermal_zone_name']
                # get all the surfaces that is in this zone
                sel_tzone = None
                for thermal_zone in thermal_zones:
                    thermal_zone_name = thermal_zone.nameString()
                    if thermal_zone_name == thermal_zone_name_ref:
                        sel_tzone = thermal_zone
                        break
                tzone_surfaces = []
                tzone_spaces = sel_tzone.spaces()
                for tzone_space in tzone_spaces:
                    tzone_surfaces.extend(tzone_space.surfaces())

                # region: calculate all the surface areas of each surface type
                ttl_wall_area = 0
                ttl_flr_area = 0
                ttl_ceil_area = 0
                for tzone_srf in tzone_surfaces:
                    srf_type = str(tzone_srf.surfaceType())
                    srf_area = tzone_srf.grossArea()
                    if srf_type == 'Wall':
                        ttl_wall_area += srf_area
                    elif srf_type == 'Floor':
                        ttl_flr_area += srf_area
                    elif srf_type == 'RoofCeiling':
                        ttl_ceil_area += srf_area
                # endregion: calculate all the surface areas of each surface type

                frac_rad_on_ppl = rad_pnl_dicts[rad_pnl_name]['frac_rad_on_ppl']
                # Assume that 45% of what is not on people is on the walls
                frac_wall = (1.0 - frac_rad_on_ppl) * 0.45
                # Assume that 50% of what is not on people is on the floor
                frac_floor = (1.0 - frac_rad_on_ppl) * 0.5
                # Assume that 5% of what is not on people is on the walls
                frac_ceil = (1.0 - frac_rad_on_ppl) * 0.05

                rad_pnl_idf = rad_pnl_dicts[rad_pnl_name]['idf_obj']
                rad_pnl_idf.clearExtensibleGroups()
                ttl_frac = 0
                for scnt,tzone_srf in enumerate(tzone_surfaces):
                    new_grp = rad_pnl_idf.pushExtensibleGroup()
                    srf_name = tzone_srf.nameString()
                    srf_type = str(tzone_srf.surfaceType())
                    srf_area = tzone_srf.grossArea()
                    new_grp.setString(0, srf_name)
                    if srf_type == 'Wall':
                        frac_srf = srf_area/ttl_wall_area*frac_wall
                    elif srf_type == 'Floor':
                        frac_srf = srf_area/ttl_flr_area*frac_floor
                    elif srf_type == 'RoofCeiling':
                        frac_srf = srf_area/ttl_ceil_area*frac_ceil
                    ttl_frac+=frac_srf
                    new_grp.setDouble(1, frac_srf)

            runner.registerFinalCondition(f"The building finished with {len(rad_pnls)} zones.")
            return True