def test_night_ventilation(result_main_folder): cfg_file = _TESTFIXTURE_FOLDER / Path("cooling") / Path("main_config.yml") cfg = cesarp.common.load_config_full(cfg_file) cfg["OPERATION"] = { "WINDOW_SHADING_CONTROL": { "ACTIVE": False }, "NIGHT_VENTILATION": { "ACTIVE": True } } # Note: trick to debug results: remove deleting result folder in res_folder(), then run it once, then uncomment # sim_mgr.run_all_steps(), change load_from_disk=True and then debug and check the results... sim_mgr = SimulationManager(result_main_folder / Path("sim_test"), cfg, cesarp.common.init_unit_registry(), load_from_disk=False, fids_to_use=[7]) sim_mgr.run_all_steps() results = sim_mgr.get_all_results_summary() dhw_annual_expected = pytest.approx(10364.1775, rel=0.005) electricity_annual_expected = pytest.approx(71952.9883) assert results.loc[7, "h * kiloW / year"]["Cooling Annual"] == pytest.approx( 13633.8, rel=0.005) assert results.loc[7, "h * kiloW / year"]["Heating Annual"] == pytest.approx( 14744.2, rel=0.005) assert results.loc[7, "h * kiloW / year"]["DHW Annual"] == dhw_annual_expected assert results.loc[7, "h * kiloW / year"][ "Electricity Annual"] == electricity_annual_expected
def test_no_adjacencies(config_no_adjacencies_case, result_main_folder): """ Testcase data provided by Manolis """ """ Tests usage of parallel workers, as the run_all_steps() function is called and not the run_single_bldg() as in the other testcases """ config = config_no_adjacencies_case expected_folder_path = os.path.dirname(__file__) / Path( "expected_result") / Path("no_adjacencies_case") expected_idf_file_path = str(expected_folder_path / Path("fid_{}.idf")) expected_result_file_path = str(expected_folder_path / Path("fid_job{}Table.csv")) res_base_path = result_main_folder / Path("no_adjacencies_case/") bldg_fids = [307143, 1150082] sim_mgr = SimulationManager(res_base_path, config, cesarp.common.init_unit_registry()) sim_mgr.run_all_steps() for bldg_fid in bldg_fids: assert are_files_equal(sim_mgr.idf_pathes[bldg_fid], expected_idf_file_path.format(bldg_fid), ignore_line_nrs=[1], ignore_filesep_mismatch=True ) is True, f'IDF files not equal for {bldg_fid}' # Line 0 and 177 contain energyplus veriosn and date/time of execution, thus ignore those; # on line 709 and 1463 there is a small numeric difference when run on windows vs linux... assert are_files_equal( sim_mgr.output_folders[bldg_fid] / Path("eplustbl.csv"), expected_result_file_path.format(bldg_fid), ignore_line_nrs=[ 1, 178, 709, 1463 ]) is True, f'result files not equal for {bldg_fid}'
def load_from_disk(base_output_folder, main_config_path): base_output_folder = __abs_path(base_output_folder) assert os.path.exists( base_output_folder ), f"folder {base_output_folder} to load scenario from is not available!" sim_manager = SimulationManager(base_output_folder, main_config_path, cesarp.common.init_unit_registry(), load_from_disk=True) if sim_manager.is_demand_results_available(): res_summary = sim_manager.get_all_results_summary() print(res_summary) else: print( f"are you sure simulation was run for scenario saved under {base_output_folder}?" )
def load_saved_scenario(self, name, specific_config_path=None) -> bool: """ Load existing building models and IDF for the specified scenario. :param name: name/key of the scenario (matching folder name from which to load) :param specific_config_path: if you have scenario specific configuration parameters, you can specify the config file path here. it overwrites properties of project configuration. :return: True if both, Building Models and IDF pathes including weather files mapping could be laoded """ sc_path = self.__get_scenario_path_for_name(name) if not os.path.exists(sc_path): return False sc_config = self._merge_config(specific_config_path) simMgr = SimulationManager(sc_path, sc_config, self.ureg, load_from_disk=True) if simMgr.is_ready_to_run_sim(): self._scenarios[name] = simMgr return True else: return False
def test_run_cesar_no_neighbourhood(config_sample_case, result_main_folder): config = config_sample_case res_base_path = result_main_folder / Path("sample_case_no_neighbourhood") result_idf_file_path = res_base_path / Path("idfs") / "fid_2.idf" result_eplus_folder = res_base_path / Path("eplus_output") / Path("fid_2") result_file_path = result_eplus_folder / Path("eplustbl.csv") result_summary_path = res_base_path / Path("site_result_summary.csvy") expected_folder_path = os.path.dirname(__file__) / Path( "./expected_result/sample_case_no_neighbourhood/gis_fid2/") expected_res_sum_path = os.path.dirname(__file__) / Path( "./expected_result/sample_case_no_neighbourhood/site_result_summary.csvy" ) expected_idf_file_path = expected_folder_path / Path( "fid_2_fixed_constr_fixed_sched_no_neighbourhood.idf") expected_res_file_path = expected_folder_path / Path( "eplustbl_result_fid2_fixed_constr_fixed_sched_no_neighbourhood.csv") config["GEOMETRY"] = {"NEIGHBOURHOOD": {"RADIUS": 0}} gis_fid = 2 sim_mgr = SimulationManager(res_base_path, config, cesarp.common.init_unit_registry(), fids_to_use=[gis_fid]) sim_mgr.run_all_steps() assert are_files_equal( result_idf_file_path, expected_idf_file_path, ignore_line_nrs=[1], ignore_filesep_mismatch=True) is True, "IDF files not equal" # Line 0 and 177 contain energyplus veriosn and date/time of execution, thus ignore those assert are_files_equal( result_file_path, expected_res_file_path, ignore_line_nrs=[1, 178]) is True, "E+ results not equal" assert are_files_equal(result_summary_path, expected_res_sum_path, ignore_line_nrs=[189], ignore_changing_config=True)
def test_window_shading(result_main_folder, default_main_cfg, ep_version_setup, caplog): caplog.set_level(logging.DEBUG, logger="cesarp.manager.processing_steps") caplog.set_level(logging.DEBUG, logger="cesarp.manager.SimulationManager") all_config = cesarp.common.load_config_full(default_main_cfg) if not "EPLUS_ADAPTER" in all_config.keys(): all_config["EPLUS_ADAPTER"] = {} all_config["EPLUS_ADAPTER"]["EPLUS_VERSION"] = "9.5" all_config["OPERATION"] = {"WINDOW_SHADING_CONTROL": {"ACTIVE": True}} if "GEOMETRY" not in all_config.keys(): all_config["GEOMETRY"] = {} if "NEIGHBOURHOIOD" not in all_config["GEOMETRY"].keys(): all_config["GEOMETRY"]["NEIGHBOURHOOD"] = {} all_config["GEOMETRY"]["NEIGHBOURHOOD"]["RADIUS"] = 0 # to get less complicated IDF base_folder = str(result_main_folder / Path("win_shading_ep95")) idf_output = base_folder / Path("idfs") / "fid_4.idf" #run_single_bldg(4, "dummy_weather.epw", idf_output, str(base_folder/Path("ep_res_fid4")), all_config, cesarp.common.init_unit_registry()) sim_manager = SimulationManager(base_folder, all_config, cesarp.common.init_unit_registry(), fids_to_use=[4]) sim_manager.create_bldg_models() sim_manager.create_IDFs() expected_output = os.path.dirname(__file__) / Path("expected_result") / Path("win_shading") / Path("fid_4_win_shading_ep95.idf") assert test_helpers.are_files_equal(idf_output, expected_output, ignore_changing_config=True, ignore_filesep_mismatch=True, ignore_line_nrs=[1])
def test_create_idf_with_SIA_generated_profiles(config_sample_case, result_main_folder): config = config_sample_case res_base_path = result_main_folder / Path( "sia_test_sample_case_no_neighbourhood") config["MANAGER"]["BLDG_TYPE_PER_BLDG_FILE"] = { "PATH": str( os.path.dirname(__file__) / Path("./testfixture/sample_case/BuildingInformation.csv")) } config["MANAGER"][ "BUILDING_OPERATION_FACTORY_CLASS"] = "cesarp.SIA2024.SIA2024Facade.SIA2024Facade" config["MANAGER"]["INFILTRATION_RATE_SOURCE"] = "SIA2024" expected_folder_path = os.path.dirname(__file__) / Path( "./expected_result/sia_test_sample_case_no_neighbourhood/") expected_idf_file_path = expected_folder_path / Path("gis_fid2") / Path( "fid_2.idf") config["GEOMETRY"] = {"NEIGHBOURHOOD": {"RADIUS": 0}} gis_fid = 2 sim_mgr = SimulationManager(res_base_path, config, cesarp.common.init_unit_registry(), fids_to_use=[gis_fid]) sim_mgr.create_bldg_models() sim_mgr.create_IDFs() assert are_files_equal(sim_mgr.idf_pathes[gis_fid], expected_idf_file_path, ignore_line_nrs=[1], ignore_filesep_mismatch=True)
def test_window_shading(result_main_folder, default_main_cfg, ep_version_setup): all_config = cesarp.common.load_config_full(default_main_cfg) if "EPLUS_ADAPTER" not in all_config.keys(): all_config["EPLUS_ADAPTER"] = {} #all_config["OPERATION"]= {"WINDOW_SHADING_CONTROL": {"ACTIVE": True}} if "GEOMETRY" not in all_config.keys(): all_config["GEOMETRY"] = {} if "NEIGHBOURHOIOD" not in all_config["GEOMETRY"].keys(): all_config["GEOMETRY"]["NEIGHBOURHOOD"] = {} all_config["GEOMETRY"]["NEIGHBOURHOOD"][ "RADIUS"] = 0 # to get less complicated IDF base_folder = str(result_main_folder / Path("win_shading_ep85")) sim_manager = SimulationManager(base_folder, all_config, cesarp.common.init_unit_registry(), fids_to_use=[4]) sim_manager.create_bldg_models() sim_manager.create_IDFs() idf_output = base_folder / Path("idfs") / "fid_4.idf" expected_output = os.path.dirname(__file__) / Path( "expected_result") / Path("win_shading") / Path( "fid_4_win_shading_ep85.idf") assert test_helpers.are_files_equal(idf_output, expected_output, ignore_changing_config=True, ignore_filesep_mismatch=True, ignore_line_nrs=[1])
def test_weather_per_community(result_main_folder, default_main_cfg): base_folder = str(result_main_folder / Path("weather_per_community")) sim_manager = SimulationManager(base_folder, default_main_cfg, cesarp.common.init_unit_registry()) sim_manager.create_bldg_models() sim_manager.save_bldg_containers() mdls_outpath = base_folder / Path("bldg_containers") assert len(os.listdir(mdls_outpath)) == 9 assert any([os.path.getsize(mdls_outpath / Path(mdl_dump)) > 0 for mdl_dump in os.listdir(mdls_outpath)]) sim_manager.create_IDFs() idf_output = base_folder / Path("idfs") idf_res_files = scan_directory(idf_output, "fid_{}.idf").values() assert len(idf_res_files) == 9 assert any([os.path.getsize(idf_output / Path(idf)) > 0 for idf in idf_res_files]) assert os.path.getsize(idf_output / Path("weather_files_mapped.csvy")) > 0 assert len(os.listdir(idf_output / Path("profiles"))) == 1
def test_many_vertices_building(result_main_folder, config_many_vertices, ep_version_setup): fid = 14002 res_base_path = result_main_folder / Path("sample_case_many_vertices_95") result_idf_file_path = res_base_path / Path("idfs") / f"fid_{fid}.idf" sim_mgr = SimulationManager(res_base_path, config_many_vertices, cesarp.common.init_unit_registry(), fids_to_use=[fid]) sim_mgr.create_bldg_models() sim_mgr.create_IDFs() # if not enough vertices can be created or not enough windows can be added for windowshadingcontrol due to an error in the IDD or not adapted IDD # creation of IDF file crashes # not comparing IDF files to avoid the need to adapt this expected result file when other changes are made assert os.path.exists(result_idf_file_path)
def create_scenario(self, name, specific_config_path=None) -> None: """ Create a new scenario. In case of variability/random constructions, the assignment is not preserved from another scenario! :param name: name/key for the scneario. Has to be convertible to string (str(name)) and this string representation valid as a folder name. :param specific_config_path: If you have scenario specific configuration parameters, you can specify the config file path or a dictionary here. It overwrites properties of project configuration, if parameters are specified in both of them :param fids_to_use: the fid's of the site which are used in this scenario. Building models, IDF's and simulation is only performed for those fid's :return: nothing """ sc_config = self._merge_config(specific_config_path) sc_path = self.__get_scenario_path_for_name(name) assert not os.path.exists( sc_path ), f"cannot create new scenario named {name}, folder {sc_path} exists" simMgr = SimulationManager(sc_path, sc_config, self.ureg, fids_to_use=self._fids_to_use) simMgr.create_bldg_models() simMgr.save_bldg_containers() simMgr.create_IDFs() self._scenarios[name] = simMgr
def derive_scenario( self, base_scenario_name, new_scenario_name, change_bldg_model_method_ref: Callable[[BuildingModel], Any]) -> None: """ Generate a new scenario based on an existing one. The building models are copied from the base scenario, this means randomly assigned constructions and variable profiles are preserved. For the so copied building models, the passed method is called, thereafter the IDFs are generated. :param base_scenario_name: name of the scenario to be used as a base :param new_scenario_name: name for the new scenario :param change_bldg_model_method_ref: method to be called for each building model, modifing it's parameters to adapt to the new scenario :return: nothing, new scenario is saved """ sc_path = self.__get_scenario_path_for_name(new_scenario_name) assert not os.path.exists( sc_path ), f"cannot derive new scenario named {new_scenario_name}, folder {sc_path} exists" try: base = self._scenarios[base_scenario_name] except KeyError: raise KeyError( f"No existing scenario named {base_scenario_name} found in project manager" ) new_mgr: SimulationManager = SimulationManager.new_manager_from_template( base, sc_path) for bldg_container in new_mgr.bldg_containers.values(): bldg_container.clear_results() if bldg_container.has_bldg_model(): change_bldg_model_method_ref(bldg_container.get_bldg_model()) new_mgr.save_bldg_containers() new_mgr.create_IDFs() self._scenarios[new_scenario_name] = new_mgr
def run_sim_site(base_output_folder, main_config_path, fids=None): base_output_folder = __abs_path(base_output_folder) assert not os.path.exists( base_output_folder ), f"output folder {base_output_folder} already exists - please specify a non-existing folder for cesar-p outputs." sim_manager = SimulationManager(base_output_folder, main_config_path, cesarp.common.init_unit_registry(), fids_to_use=fids, load_from_disk=False) sim_manager.run_all_steps() zip_path = sim_manager.save_to_zip( main_script_path=__file__, save_folder_path=os.path.dirname(__file__), include_idfs=False, include_eplus_output=False, include_src_pck=True) print( f"Project has been saved to {zip_path}, including all input files so it can be transfered to another computer." ) # if you need different result parameters, you have to make sure that energy plus reports them. Do so by using the configuration parameters from eplus_adapter package, namely # "OUTPUR_METER" and "OUTPUT_VARS", see cesarp.eplus_adapter.default_config.yml. You can overwrite those parameters in your project config, in this example that would be main_config.yml. # Also make sure that the reporting frequency in the configuration and in the callect_results_in_parallel() call match. result_series_frame = sim_manager.collect_custom_results( result_keys=["DistrictHeating:HVAC", "DistrictHeating:Building"], results_frequency=ResultsFrequency.HOURLY) # you can postprocess the results as you like, e.g. save to a file result_series_frame.to_csv( __abs_path(base_output_folder) / Path("hourly_results.csv")) if sim_manager.failed_fids: logging.warning( f"Something went wrong for following FID's {sim_manager.failed_fids}" )
from cesarp.manager.SimulationManager import SimulationManager def __abs_path(path): return cesarp.common.abs_path(path, os.path.abspath(__file__)) if __name__ == "__main__": # note: expected to be run in simple_example folder - otherwise adapt the path specifications as needed logging.config.fileConfig( __abs_path("logging.conf") ) # this logging config is only for the main process, workers log to separate log files which go into a folder, configured in SimulationManager. main_config_path = __abs_path("simple_main_config.yml") output_dir = __abs_path("./results/example") shutil.rmtree(output_dir, ignore_errors=True) fids_to_use = [1, 2, 3] # set to None to simulate all buildings sim_manager = SimulationManager(output_dir, main_config_path, cesarp.common.init_unit_registry(), fids_to_use=fids_to_use) sim_manager.run_all_steps() zip_path = sim_manager.save_to_zip(main_script_path=__file__) print("\n=========PROCESS FINISHED ===========") print(f"You find the results in {output_dir}") print( f"Project has been saved to {zip_path}, including all input files so it can be transfered to another computer." )
def test_window_shading(result_main_folder): """ validated agains matlab implementation of ricardo """ cfg_file = _TESTFIXTURE_FOLDER / Path("cooling") / Path("main_config.yml") cfg = cesarp.common.load_config_full(cfg_file) cfg["OPERATION"] = { "WINDOW_SHADING_CONTROL": { "ACTIVE": True }, "NIGHT_VENTILATION": { "ACTIVE": False } } # Note: trick to debug results: remove deleting result folder in res_folder(), then run it once, then uncomment # sim_mgr.run_all_steps(), change load_from_disk=True and then debug and check the results... sim_mgr = SimulationManager(result_main_folder / Path("sim_test"), cfg, cesarp.common.init_unit_registry(), load_from_disk=False) sim_mgr.run_all_steps() results = sim_mgr.get_all_results_summary() dhw_annual_expected = pytest.approx(10351.6, rel=0.005) electricity_annual_expected = pytest.approx(71953) assert results.loc[2, "h * kiloW / year"]["Cooling Annual"] == pytest.approx( 297.6, rel=0.005) assert results.loc[2, "h * kiloW / year"]["Heating Annual"] == pytest.approx( 172524, rel=0.005) assert results.loc[2, "h * kiloW / year"]["DHW Annual"] == dhw_annual_expected assert results.loc[2, "h * kiloW / year"][ "Electricity Annual"] == electricity_annual_expected assert results.loc[7, "h * kiloW / year"]["Cooling Annual"] == pytest.approx( 13718.5, rel=0.005) assert results.loc[7, "h * kiloW / year"]["Heating Annual"] == pytest.approx( 21194.7, rel=0.005) assert results.loc[7, "h * kiloW / year"]["DHW Annual"] == dhw_annual_expected assert results.loc[7, "h * kiloW / year"][ "Electricity Annual"] == electricity_annual_expected assert results.loc[8, "h * kiloW / year"]["Cooling Annual"] == pytest.approx( 16000.9, rel=0.005) assert results.loc[8, "h * kiloW / year"]["Heating Annual"] == pytest.approx( 15840.86, rel=0.005) assert results.loc[8, "h * kiloW / year"]["DHW Annual"] == dhw_annual_expected assert results.loc[8, "h * kiloW / year"][ "Electricity Annual"] == electricity_annual_expected assert results.loc[9, "h * kiloW / year"]["Cooling Annual"] == pytest.approx( 14822.8, rel=0.005) assert results.loc[9, "h * kiloW / year"]["Heating Annual"] == pytest.approx( 14548.6, rel=0.005) assert results.loc[9, "h * kiloW / year"]["DHW Annual"] == dhw_annual_expected assert results.loc[9, "h * kiloW / year"][ "Electricity Annual"] == electricity_annual_expected
# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # # Contact: https://www.empa.ch/web/s313 # import os from pathlib import Path from cesarp.manager.SimulationManager import SimulationManager import cesarp.common # not, run simple example prior to run this script base_cesarp_output = os.path.dirname(__file__) / Path("..") / Path("simple_example") / Path("results") / Path("example") # must contain folder named bldg_containers main_cfg_path = os.path.dirname(__file__) / Path("..") / Path("simple_example") / Path("simple_main_config.yml") sim_manager = SimulationManager(base_cesarp_output, main_cfg_path, cesarp.common.init_unit_registry(), load_from_disk=True) roof_constructions = { fid: ctr.get_bldg_model().bldg_construction.roof_constr.short_name if ctr.has_bldg_model() else "bldg model is missing" for fid, ctr in sim_manager.bldg_containers.items() } print("Roof construction: " + str(roof_constructions)) neighbours_per_bldg = {fid: len(ctr.get_bldg_model().neighbours) if ctr.has_bldg_model() else 0 for fid, ctr in sim_manager.bldg_containers.items()} print("Number of neighbouring buildings: " + str(neighbours_per_bldg))
from cesarp.manager.SimulationManager import SimulationManager def __abs_path(path): return cesarp.common.abs_path(path, os.path.abspath(__file__)) if __name__ == "__main__": # this logging config is only for the main process, workers log to separate log files which go into a folder, configured in SimulationManager. logging.config.fileConfig(__abs_path("../logging.conf")) # make sure the BuildingSpecificArechtypConstrctionFactory can be found sys.path.append(os.path.dirname(__file__)) main_config_path = __abs_path("custom_constr_archetype_config.yml") output_dir = __abs_path("../results/custom_constr_archetype") shutil.rmtree(output_dir, ignore_errors=True) fids_to_use = [1, 2, 8] # set to None to simulate all buildings sim_manager = SimulationManager(output_dir, main_config_path, cesarp.common.init_unit_registry(), fids_to_use=fids_to_use) sim_manager.run_all_steps() print("====================") print(f"check out results in {output_dir}") print( "check archetype assignment in worker log files in folder TIMESTAMP-cesarp-logs. depending on logging settings it is also printed to the console." )