From 5c7ca81338aa0d7154c17a35100fdb8797152094 Mon Sep 17 00:00:00 2001 From: dsanchez-garcia Date: Wed, 5 Jun 2024 16:34:24 +0200 Subject: [PATCH] 0.7.5 - optimisation and parametric simulation --- WIP_outputs_optimisation_custom.xlsx | Bin 6827 -> 6057 bytes accim/parametric_and_optimisation/main.py | 381 ++++++++++++++---- ...mulation_usage_v00_accim_custom_testing.py | 10 +- ...simulation_usage_v00_accim_custom_works.py | 15 +- ...etric_simulation_usage_v00_accim_custom.py | 8 +- ...etric_simulation_usage_v00_accim_predef.py | 11 +- parametric_simulation_usage_v00_apmv.py | 8 +- 7 files changed, 327 insertions(+), 106 deletions(-) diff --git a/WIP_outputs_optimisation_custom.xlsx b/WIP_outputs_optimisation_custom.xlsx index c481d648a4414037b980cab4c30f6d26a3e26ad6..4500327132452008dfdbec4f996b48235a1886d1 100644 GIT binary patch delta 1351 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 list[Union[dict[str, Union[str, None, list[str]]], dict[str, Union[str, None, list[str]]]]]: + """ + Returns a list of the objects in the .mtd file from the test simulation. + + :return: a list of the objects in the .mtd file from the test simulation + """ + meter_list = [] + with open('available_outputs/eplusout.mtd', 'r') as file: + lines = file.readlines() + + meter_id, description = None, None + on_meters = [] + + for line in lines: + line = line.strip() + if line.startswith('Meters for'): + if meter_id is not None: + meter_list.append({ + 'meter_id': meter_id, + 'description': description, + 'on_meters': on_meters + }) + match = re.match(r'Meters for (\d+),(.+)', line) + if match: + meter_id = match.group(1) + description = match.group(2) + on_meters = [] + elif line.startswith('OnMeter'): + on_meters.append(line.split('=')[1].strip()) + + # Add the last meter + if meter_id is not None: + meter_list.append({ + 'meter_id': meter_id, + 'description': description, + 'on_meters': on_meters + }) + + return meter_list + + +def get_mdd_file_as_df(): + """ + Returns the .mdd file from the test simulation as a pandas DataFrame + + :return: a pandas DataFrame containing the .mdd file from the test simulation + """ + mdd_df = pd.read_csv( + filepath_or_buffer='available_outputs/eplusout.mdd', + sep=',|;', + skiprows=2, + names=['object', 'meter_name', 'frequency', 'units'] + ) + return mdd_df class OptimParamSimulation: def __init__( self, - building: besos.IDF_class, - parameters_type: str, - output_type: str = 'standard', + building: IDF_class, + parameters_type: Literal['accim custom model', 'accim predefined model', 'apmv setpoints'], + output_type: Literal['standard', 'custom', 'detailed', 'simplified'] = 'standard', output_keep_existing: bool = False, - output_freqs: list = ['hourly'], - ScriptType: str = 'vrf_mm', - SupplyAirTempInputMethod: str = 'temperature difference', + output_freqs: List[allowed_output_freqs] = ['hourly'], + ScriptType: Literal['vrf_mm', 'vrf_ac', 'ex_ac'] = 'vrf_mm', + SupplyAirTempInputMethod: Literal['temperature difference', 'supply air temperature'] = 'temperature difference', debugging: bool = False, ): + """ + Creates a class instance to run parametric simulations and optimisation. + + :param building: the besos.IDF_class returned from method get_building(idfpath) + :param parameters_type: to specify the type of parameters that should be used: + can be 'accim custom model', 'accim predefined model', or 'apmv setpoints' + :param output_type: to specify the outputs that are going to be requested; + only used in accim predefined and custom models + :param output_keep_existing: to keep or remove existing outputs; + only used in accim predefined and custom models + :param output_freqs: to specify the frequency or frequencies for the outputs; must be a list containing any of + the following strings: 'timestep', 'hourly', 'daily', 'monthly', 'runperiod' + :param ScriptType: to specify the ScriptType; must one of the following strings: 'vrf_mm', 'vrf_ac', 'ex_ac'; + for more information, please refer to addAccis() + :param SupplyAirTempInputMethod: in case 'vrf_mm' or 'vrf_ac' ScriptTypes are used, specifies the supply air + temperature input method for the VRF systems + :param debugging: True to generate the .EDD file + """ is_accim_predef_model = False is_accim_custom_model = False is_apmv_setpoints = False @@ -65,9 +158,25 @@ def __init__( raise KeyError(f'String {parameters_type} entered in argument parametric_simulation_type ' f'is not supported. Valid strings are: ' f'"accim custom model", "accim predefined model" or "apmv setpoints".') + + #todo not working + # if not all(freq in allowed_output_freqs for freq in output_freqs): + # raise ValueError(f"Invalid output frequencies: {output_freqs}. Allowed values are: {allowed_output_freqs}") + + allowed_ScriptType = ['vrf_mm', 'vrf_ac', 'ex_ac'] + if ScriptType not in allowed_ScriptType: + raise ValueError(f"Invalid ScriptType: {ScriptType}. Allowed values are: {allowed_ScriptType}") + + allowed_SupplyAirTempInputMethod = ['temperature difference', 'supply air temperature'] + if SupplyAirTempInputMethod not in allowed_SupplyAirTempInputMethod: + raise ValueError(f"Invalid ScriptType: {SupplyAirTempInputMethod}. Allowed values are: {allowed_SupplyAirTempInputMethod}") + + allowed_output_type = ['standard', 'custom', 'detailed', 'simplified'] + if output_type not in allowed_output_type: + raise ValueError(f"Invalid output_type: {output_type}. Allowed values are: {allowed_output_type}") + if is_accim_custom_model or is_accim_predef_model: self.ScriptType = ScriptType - self.parametric_simulation_type = parameters_type self.temp_ctrl = temp_ctrl self.SupplyAirTempInputMethod = SupplyAirTempInputMethod self.output_keep_existing = output_keep_existing @@ -90,21 +199,25 @@ def __init__( ) elif is_apmv_setpoints: apmv.apply_apmv_setpoints(building=building, outputs_freq=output_freqs) + print('Arguments output_type, output_keep_existing, ScriptType, and SupplyAirTempInputMethod ' + 'are only used in accim predefined and custom models, ' + 'therefore these will not have any effect in this case.') self.building = building self.output_freqs = output_freqs + self.parameters_type = parameters_type self.is_accim_custom_model = is_accim_custom_model self.is_accim_predef_model = is_accim_predef_model self.is_apmv_setpoints = is_apmv_setpoints - def get_output_var_df_from_idf(self): + def get_output_var_df_from_idf(self) -> pd.DataFrame: """ Gets a pandas DataFrame which contains the Output:Variable objects from the idf. Therefore, it may contain wildcards such as '*', which means the variable is requested for all zones. - :return: + :return: a pandas DataFrame which contains the Output:Variable objects from the idf """ if self.is_accim_custom_model or self.is_accim_predef_model: output_variable_df = accis.gen_outputs_df( @@ -126,11 +239,11 @@ def get_output_var_df_from_idf(self): return output_variable_df - def get_output_meter_df_from_idf(self): + def get_output_meter_df_from_idf(self) -> pd.DataFrame: """ Gets a pandas DataFrame which contains the Output:Meter objects from the idf. - :return: + :return: a pandas DataFrame which contains the Output:Meter objects from the idf """ output_meter_dict = { 'key_name': [i.Key_Name for i in self.building.idfobjects['Output:Meter']], @@ -184,7 +297,14 @@ def set_output_var_df_to_idf(self, outputs_df: pd.DataFrame = None): # '"accim predefined model" types.') - def set_output_met_objects_to_idf(self, output_meters): + def set_output_met_objects_to_idf(self, output_meters: list): + """ + Adds the Output:Meter objects from the output_meters argument. + + :type output_meters: list + :param output_meters: a list containing Output:Meter objects to be added + :return: + """ for meter in output_meters: for freq in self.output_freqs: self.building.newidfobject( @@ -193,12 +313,12 @@ def set_output_met_objects_to_idf(self, output_meters): Reporting_Frequency=freq ) - def get_outputs_df_from_testsim(self): + def get_outputs_df_from_testsim(self) -> tuple[pd.DataFrame, pd.DataFrame]: """ - Gets a pandas DataFrame which contains the Output:Variable objects from a test simulation. + Gets two pandas DataFrames which contain the Output:Variable and Output:Meter objects from a test simulation. Therefore, it won't contain wildcards such as '*'. - :return: + :return: a tuple containing the DataFrames containing Output:Variable and Output:Meter """ available_outputs = print_available_outputs_mod(self.building) df_outputmeters = pd.DataFrame( @@ -212,66 +332,23 @@ def get_outputs_df_from_testsim(self): return df_outputmeters, df_outputvariables - def get_rdd_file_as_df(self): - rdd_df = pd.read_csv( - filepath_or_buffer='available_outputs/eplusout.rdd', - sep=',|;', - skiprows=2, - names=['object', 'key_value', 'variable_name', 'frequency', 'units'] - ) - return rdd_df - - def get_mdd_file_as_df(self): - mdd_df = pd.read_csv( - filepath_or_buffer='available_outputs/eplusout.mdd', - sep=',|;', - skiprows=2, - names=['object', 'meter_name', 'frequency', 'units'] - ) - return mdd_df - - def parse_mtd_file(self): - meter_list = [] - with open('available_outputs/eplusout.mtd', 'r') as file: - lines = file.readlines() - - meter_id, description = None, None - on_meters = [] - - for line in lines: - line = line.strip() - if line.startswith('Meters for'): - if meter_id is not None: - meter_list.append({ - 'meter_id': meter_id, - 'description': description, - 'on_meters': on_meters - }) - match = re.match(r'Meters for (\d+),(.+)', line) - if match: - meter_id = match.group(1) - description = match.group(2) - on_meters = [] - elif line.startswith('OnMeter'): - on_meters.append(line.split('=')[1].strip()) - - # Add the last meter - if meter_id is not None: - meter_list.append({ - 'meter_id': meter_id, - 'description': description, - 'on_meters': on_meters - }) - - return meter_list - - - def set_outputs_for_parametric_simulation( + def set_outputs_for_simulation( self, df_output_variable: pd.DataFrame = None, df_output_meter: pd.DataFrame = None, ): - # objs_meters = [MeterReader(key_name=i, name=i) for i in output_meters] + """ + Sets the outputs for the parametric analysis or optimisation based on the input pandas DataFrames + for Output:Variable and/or Output:Meter objects. These DataFrames can include columns for the output name + and the aggregation function (see the 'func' argument of MeterReader and VariableReader classes in besos), + respectively named 'name' and 'func'. If no 'name' and/or 'func' columns are provided, + the names will be the variable and meter names, and the hourly values will be summed. + + :param df_output_variable: a pandas DataFrame containing the Output:Variable objects, similar to that one + returned from method get_outputs_df_from_testsim() + :param df_output_meter: a pandas DataFrame containing the Output:Meter objects, similar to that one + returned from method get_outputs_df_from_testsim() + """ if df_output_variable is not None: df_output_variable['output_name'] = 'temp' if 'name' in df_output_variable.columns: @@ -330,9 +407,14 @@ def set_outputs_for_parametric_simulation( ) ) - self.param_sim_outputs = objs_meters + objs_variables + self.sim_outputs = objs_meters + objs_variables + + def get_available_parameters(self) -> list: + """ + Returns a list containing the available parameters depending on the parameters_type argument previously input. - def get_available_parameters(self): + :return: a list containing the available parameters depending on the parameters_type argument previously input + """ if self.is_accim_predef_model: available_params = [i for i in params_dicts.accim_predef_model_params.keys()] elif self.is_accim_custom_model: @@ -343,11 +425,23 @@ def get_available_parameters(self): def set_parameters( self, - accis_params_dict, + accis_params_dict: dict, additional_params: list = None, - HVACmode: int = 2, - VentCtrl: int = 0, + HVACmode: Literal[0, 1, 2] = 2, + VentCtrl: Literal[0, 1, 2, 3] = 0, ): + """ + Sets the parameters for the parametric analysis or optimisation. + + :param accis_params_dict: a dictionary containing the parameters names in the keys, + and in the values, the options or range of values using respectively + a list or tuple with min and max values. + :param additional_params: any other additional parameter, as it would be added in besos + :param HVACmode: only used in accim predefined and custom models; sets the HVACmode argument; + for more information, refer to addAccis + :param VentCtrl: only used in accim predefined and custom models; sets the VentCtrl argument; + for more information, refer to addAccis + """ accis_descriptors_has_options = False add_descriptors_has_options = False descriptors_has_options = False @@ -381,6 +475,17 @@ def set_parameters( if descriptors_has_options is False and descriptors_has_range is False: raise TypeError('All Descriptors are not CategoryParameters or RangeParameters.') + parameters = [k for k in accis_params_dict.keys()] + available_parameters = self.get_available_parameters() + + not_allowed_parameters = [] + for p in parameters: + if p not in available_parameters: + not_allowed_parameters.append(p) + if len(not_allowed_parameters) > 0: + raise ValueError(f'The following parameters are not allowed in ' + f'parameters_type {self.parameters_type}: {not_allowed_parameters}') + if self.is_accim_custom_model: accis.modifyAccis( idf=self.building, @@ -409,15 +514,26 @@ def set_problem( constraints: list = None, constraint_bounds: list = None, ): + """ + Sets the besos EPProblem class instance, using for inputs the parameters previously set in the set_parameters + method, and for outputs, those set using the set_outputs_for_simulation method. + + :param minimize_outputs: only used in optimisation; a list containing booleans to specify if the outputs must + be minimized (True), maximized (False), or just show the output (None). + :param constraints: only used in optimisation; + a list containing the Output:Meter key names to be considered as constraints + :param constraint_bounds: only used in optimisation; + a list containing the logical expressions for the constraints + """ # if type == 'parametric_and_optimisation simulation': # problem = EPProblem( # inputs=self.parameters_list, - # outputs=self.param_sim_outputs + # outputs=self.sim_outputs # ) # elif type == 'optimisation': problem = EPProblem( inputs=self.parameters_list, - outputs=self.param_sim_outputs, + outputs=self.sim_outputs, minimize_outputs=minimize_outputs, constraints=constraints, constraint_bounds=constraint_bounds @@ -425,6 +541,10 @@ def set_problem( self.problem = problem def sampling_full_set(self): + """ + Combines all values from all parameters and saves it into a pandas DataFrame, stored in an internal variable + named parameters_values_df. + """ if self.descriptors_has_options: num_samples = 1 parameters_values = {} @@ -445,6 +565,13 @@ def sampling_full_set(self): self.parameters_values_df = parameters_values_df def sampling_full_factorial(self, level: int): + """ + Split the range of every parameter in the number of parts specified in argument level, + and saves it into a pandas DataFrame, stored in an internal variable named parameters_values_df. + For more information, see besos.sampling.dist_sampler and besos.sampling.full_factorial + + :param level: an integer; represents the number of parts to split each parameter's range + """ if self.descriptors_has_range: parameters_values_df = sampling.dist_sampler( sampling.full_factorial, @@ -458,6 +585,13 @@ def sampling_full_factorial(self, level: int): def sampling_lhs(self, num_samples: int): + """ + Uses Latin Hypercube Sampling to make samples, where the total number is specified in the num_samples argument, + and saves it into a pandas DataFrame, stored in an internal variable named parameters_values_df. + For more information, see besos.sampling.dist_sampler and besos.sampling.lhs + + :param num_samples: an integer; represents the total number of samples + """ if self.descriptors_has_range: parameters_values_df = sampling.dist_sampler( sampling.lhs, @@ -473,7 +607,14 @@ def set_evaluator( self, epw: str, out_dir: str, - ): + ) -> besos.evaluator.EvaluatorEP: + """ + Used internally for setting the evaluator in run_parametric_simulation and run_optimisation methods. + + :param epw: The epw file name + :param out_dir: The name of the output directory to save the results. + :return: the besos.evaluator.EvaluatorEP class instance + """ evaluator = EvaluatorEP( problem=self.problem, building=self.building, @@ -491,7 +632,18 @@ def run_parametric_simulation( processes: int = 2, keep_input: bool = True, keep_dirs: bool = True, - ): + ) -> pd.DataFrame: + """ + Runs the parametric simulation. + + :param epws: a list of .epw filenames + :param out_dir: the name of the directory to store the outputs + :param df: a pandas DataFrame which contains the values of the parameters to simulate + :param processes: the number of CPUs to be used in simulation + :param keep_input: True to keep the input DataFrame in the results + :param keep_dirs: True to keep the simulation results + :return: a pandas DataFrame + """ outputs_dict = {} for epw in epws: epwname = epw.split('.epw')[0] @@ -523,12 +675,77 @@ def run_optimisation( out_dir: str, evaluations: int, population_size: int, - ): + algorithm: str = 'NSGAII', + ) -> pd.DataFrame: + """ + Runs the optimisation using + + :param epw: The epw filename + :param out_dir: the directory name to save the outputs + :param evaluations: The algorithm will be stopped once it uses more than this many evaluations. + For more information, refer to besos.optimizer.platypus_alg + :param population_size: The number of simulations to run + + :return: a pandas DataFrame + """ evaluator = self.set_evaluator( epw=epw, out_dir=out_dir ) - results = NSGAII(evaluator, evaluations=evaluations, population_size=population_size) + available_algorithms = [ + 'GeneticAlgorithm', + 'EvolutionaryStrategy', + 'NSGAII', + 'EpsMOEA', + 'GDE3', + 'SPEA2', + 'MOEAD', + 'NSGAIII', + 'ParticleSwarm', + 'OMOPSO', + 'SMPSO', + 'CMAES', + 'IBEA', + 'PAES', + 'PESA2', + 'EpsNSGAII', + ] + # results = NSGAII(evaluator, evaluations=evaluations, population_size=population_size) + if algorithm == 'GeneticAlgorithm': + results = optimizer.GeneticAlgorithm(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'EvolutionaryStrategy': + results = optimizer.EvolutionaryStrategy(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'NSGAII': + results = optimizer.NSGAII(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'EpsMOEA': + results = optimizer.EpsMOEA(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'GDE3': + results = optimizer.GDE3(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'SPEA2': + results = optimizer.SPEA2(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'MOEAD': + results = optimizer.MOEAD(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'NSGAIII': + results = optimizer.NSGAIII(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'ParticleSwarm': + results = optimizer.ParticleSwarm(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'OMOPSO': + results = optimizer.OMOPSO(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'SMPSO': + results = optimizer.SMPSO(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'CMAES': + results = optimizer.CMAES(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'IBEA': + results = optimizer.IBEA(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'PAES': + results = optimizer.PAES(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'PESA2': + results = optimizer.PESA2(evaluator, evaluations=evaluations, population_size=population_size) + elif algorithm == 'EpsNSGAII': + results = optimizer.EpsNSGAII(evaluator, evaluations=evaluations, population_size=population_size) + else: + raise KeyError(f'Input algorithm {algorithm} not found. Available algorithms are: {available_algorithms}') + return results class AccimPredefModelsParamSim(OptimParamSimulation): diff --git a/optimisation_simulation_usage_v00_accim_custom_testing.py b/optimisation_simulation_usage_v00_accim_custom_testing.py index f7ec278..25314dc 100644 --- a/optimisation_simulation_usage_v00_accim_custom_testing.py +++ b/optimisation_simulation_usage_v00_accim_custom_testing.py @@ -83,9 +83,9 @@ df_outputmeters_2, df_outputvariables_2 = test_class_instance.get_outputs_df_from_testsim() #Other variables could be reported. These can be read in the rdd, mdd and mtd files -df_rdd = test_class_instance.get_rdd_file_as_df() -df_mdd = test_class_instance.get_mdd_file_as_df() -meter_list = test_class_instance.parse_mtd_file() +df_rdd = get_rdd_file_as_df() +df_mdd = get_mdd_file_as_df() +meter_list = parse_mtd_file() # To end with outputs, let's set the objective outputs (outputs for the Problem object), which are those displayed by BESOS in case of parametric_and_optimisation analysis, or used in case of optimisation @@ -105,7 +105,7 @@ def return_time_series(result): df_outputvariables_3 = df_outputvariables_3.drop(index=[2, 4]) df_outputvariables_3['name'] = df_outputvariables_3['variable_name'] + '_time series' -test_class_instance.set_outputs_for_parametric_simulation( +test_class_instance.set_outputs_for_simulation( df_output_meter=df_outputmeters_2, df_output_variable=df_outputvariables_3, ) @@ -155,7 +155,7 @@ def return_time_series(result): [i for i in building.idfobjects['EnergyManagementSystem:Program'] if i.Name.lower() == 'applycat'] -[i.name for i in test_class_instance.param_sim_outputs] +[i.name for i in test_class_instance.sim_outputs] # Let's set the problem test_class_instance.set_problem( diff --git a/optimisation_simulation_usage_v00_accim_custom_works.py b/optimisation_simulation_usage_v00_accim_custom_works.py index 2d26ee4..6451421 100644 --- a/optimisation_simulation_usage_v00_accim_custom_works.py +++ b/optimisation_simulation_usage_v00_accim_custom_works.py @@ -24,7 +24,7 @@ import accim.parametric_and_optimisation.funcs_for_besos.param_accis as bf import accim.parametric_and_optimisation.parameters as params -from accim.parametric_and_optimisation.main import OptimParamSimulation +from accim.parametric_and_optimisation.main import OptimParamSimulation, get_mdd_file_as_df, get_rdd_file_as_df, parse_mtd_file # 1. check output data # 2. check input dataframe @@ -83,9 +83,9 @@ df_outputmeters_2, df_outputvariables_2 = test_class_instance.get_outputs_df_from_testsim() #Other variables could be reported. These can be read in the rdd, mdd and mtd files -df_rdd = test_class_instance.get_rdd_file_as_df() -df_mdd = test_class_instance.get_mdd_file_as_df() -meter_list = test_class_instance.parse_mtd_file() +df_rdd = get_rdd_file_as_df() +df_mdd = get_mdd_file_as_df() +meter_list = parse_mtd_file() # To end with outputs, let's set the objective outputs (outputs for the Problem object), which are those displayed by BESOS in case of parametric_and_optimisation analysis, or used in case of optimisation @@ -105,7 +105,7 @@ # df_outputvariables_3 = df_outputvariables_3.drop(index=[2, 4]) # df_outputvariables_3['name'] = df_outputvariables_3['variable_name'] + '_time series' -test_class_instance.set_outputs_for_parametric_simulation( +test_class_instance.set_outputs_for_simulation( df_output_meter=df_outputmeters_2, # df_output_variable=df_outputvariables_3, ) @@ -183,10 +183,11 @@ # ) outputs = test_class_instance.run_optimisation( + algorithm='NSGAII', epw='Sydney.epw', out_dir='WIP_testing optimisation', - evaluations=5, - population_size=10 + evaluations=2, + population_size=4 ) diff --git a/parametric_simulation_usage_v00_accim_custom.py b/parametric_simulation_usage_v00_accim_custom.py index 9eb09b1..0633fef 100644 --- a/parametric_simulation_usage_v00_accim_custom.py +++ b/parametric_simulation_usage_v00_accim_custom.py @@ -83,9 +83,9 @@ df_outputmeters_2, df_outputvariables_2 = test_class_instance.get_outputs_df_from_testsim() #Other variables could be reported. These can be read in the rdd, mdd and mtd files -df_rdd = test_class_instance.get_rdd_file_as_df() -df_mdd = test_class_instance.get_mdd_file_as_df() -meter_list = test_class_instance.parse_mtd_file() +df_rdd = get_rdd_file_as_df() +df_mdd = get_mdd_file_as_df() +meter_list = parse_mtd_file() # To end with outputs, let's set the objective outputs (outputs for the Problem object), which are those displayed by BESOS in case of parametric_and_optimisation analysis, or used in case of optimisation @@ -105,7 +105,7 @@ def return_time_series(result): df_outputvariables_3 = df_outputvariables_3.drop(index=[2, 4]) df_outputvariables_3['name'] = df_outputvariables_3['variable_name'] + '_time series' -test_class_instance.set_outputs_for_parametric_simulation( +test_class_instance.set_outputs_for_simulation( df_output_meter=df_outputmeters_3, # df_output_variable=df_outputvariables_3, df_output_variable=df_outputvariables_3, diff --git a/parametric_simulation_usage_v00_accim_predef.py b/parametric_simulation_usage_v00_accim_predef.py index f01c8bf..0a0b0be 100644 --- a/parametric_simulation_usage_v00_accim_predef.py +++ b/parametric_simulation_usage_v00_accim_predef.py @@ -40,6 +40,8 @@ accim.utils.set_occupancy_to_always(idf_object=building) +new_test = OptimParamSimulation() + test_class_instance = OptimParamSimulation( building=building, parameters_type='accim predefined model' @@ -83,9 +85,9 @@ df_outputmeters_2, df_outputvariables_2 = test_class_instance.get_outputs_df_from_testsim() #Other variables could be reported. These can be read in the rdd, mdd and mtd files -df_rdd = test_class_instance.get_rdd_file_as_df() -df_mdd = test_class_instance.get_mdd_file_as_df() -meter_list = test_class_instance.parse_mtd_file() +df_rdd = get_rdd_file_as_df() +df_mdd = get_mdd_file_as_df() +meter_list = parse_mtd_file() # To end with outputs, let's set the objective outputs (outputs for the Problem object), which are those displayed by BESOS in case of parametric_and_optimisation analysis, or used in case of optimisation @@ -105,7 +107,7 @@ def return_time_series(result): df_outputvariables_3 = df_outputvariables_3.drop(index=[2, 4]) df_outputvariables_3['name'] = df_outputvariables_3['variable_name'] + '_time series' -test_class_instance.set_outputs_for_parametric_simulation( +test_class_instance.set_outputs_for_simulation( df_output_meter=df_outputmeters_3, # df_output_variable=df_outputvariables_3, df_output_variable=df_outputvariables_3, @@ -245,4 +247,5 @@ def return_time_series(result): +## diff --git a/parametric_simulation_usage_v00_apmv.py b/parametric_simulation_usage_v00_apmv.py index 3c93bdf..6f294ad 100644 --- a/parametric_simulation_usage_v00_apmv.py +++ b/parametric_simulation_usage_v00_apmv.py @@ -84,9 +84,9 @@ df_outputmeters_2, df_outputvariables_2 = test_class_instance.get_outputs_df_from_testsim() #Other variables could be reported. These can be read in the rdd, mdd and mtd files -df_rdd = test_class_instance.get_rdd_file_as_df() -df_mdd = test_class_instance.get_mdd_file_as_df() -meter_list = test_class_instance.parse_mtd_file() +df_rdd = get_rdd_file_as_df() +df_mdd = get_mdd_file_as_df() +meter_list = parse_mtd_file() # To end with outputs, let's set the objective outputs (outputs for the Problem object), which are those displayed by BESOS in case of parametric_and_optimisation analysis, or used in case of optimisation @@ -106,7 +106,7 @@ # df_outputvariables_3 = df_outputvariables_3.drop(index=[2, 4]) df_outputvariables_3['name'] = df_outputvariables_3['variable_name'] + '_time series' -test_class_instance.set_outputs_for_parametric_simulation( +test_class_instance.set_outputs_for_simulation( df_output_meter=df_outputmeters_2, # df_output_variable=df_outputvariables_3, df_output_variable=df_outputvariables_3,