Loading AutoCSM/languages/modelica/create_model_nested.py +15 −6 Original line number Diff line number Diff line Loading @@ -51,10 +51,10 @@ def sources_line(data, project_path, base_path, model_class_path, key_path, unif temp_path = pathlib.Path(project_path).parts[:-1] model_path_list = list(temp_path) + model_class_path.split('.')[0:-2] + ['Models'] + [data['ModelClass'] + '.mo'] model_path = os.path.join(*model_path_list) model_path = pathlib.Path(*model_path_list) # Find the default by searching for "redeclare replaceable Sources.* sources" default_source_class = parse_files.extract_default_class_from_model(model_path, 'Sources', 'source')[0] default_source_class = parse_files.extract_default_class_from_model(model_path.as_posix(), 'Sources', 'sources')[0] # If 'SourceClass' is not in in the input file and is not the default, redeclare if 'SourceClass' in data.keys() and default_source_class != data['SourceClass']: Loading Loading @@ -106,7 +106,7 @@ def sources_line(data, project_path, base_path, model_class_path, key_path, unif line += f'sources({temp if temp else ""})\n' return line def create_nested_lines(data, project_path, base_path, uniform=[True,True], lines=None, is_top_system=True, key_path=None, level=0): def create_nested_lines(data, project_path, base_path, uniform=[True,True], lines=None, is_top_system=True, key_path=None, level=0, last_modelClass=None): """ Creates a list of lines representing the structure of the Modelica model. Loading @@ -133,8 +133,17 @@ def create_nested_lines(data, project_path, base_path, uniform=[True,True], line else: base_path = '.'.join([base_path, 'Systems', data['Name']]) model_class_path = '.'.join([base_path, 'Models', data['ModelClass']]) model_instance_name = data['InstanceName'] if is_top_system or'ModelClass' in data.keys(): model_class_path = '.'.join([base_path, 'Models', data['ModelClass']]) else: temp_path = pathlib.Path(project_path).parts[:-1] model_path_list = list(temp_path) + base_path.split('.')[0:-2] + ['Models'] + [last_modelClass + '.mo'] model_path = pathlib.Path(*model_path_list) data['ModelClass'] = parse_files.extract_default_class_from_model(model_path.as_posix(), 'Models', model_instance_name, include_redeclare=False)[0] model_class_path = '.'.join([base_path, 'Models', data['ModelClass']]) # Append line lines.append(f'redeclare {model_class_path} {model_instance_name}(') # Current system changes Loading @@ -147,7 +156,7 @@ def create_nested_lines(data, project_path, base_path, uniform=[True,True], line # Next system changes for sub_dict in data['Systems']: if sub_dict: # Terminate if dictionary is empty lines = create_nested_lines(sub_dict, project_path, base_path, uniform, lines, False, key_path, level+1) lines = create_nested_lines(sub_dict, project_path, base_path, uniform, lines, False, key_path, level+1, data['ModelClass']) lines.append(')') return lines Loading AutoCSM/languages/modelica/parse_files.py +39 −4 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ def get_variable_by_type(file_path, dtype='parameter'): parameters = extract_variable(input_string, dtype) return parameters def extract_default_class_from_model(file_path, folder='Sources', instance='sources'): def extract_default_class_from_model(file_path, folder='Sources', instance='sources', include_redeclare=True, include_replaceable = True): """ Extracts the default class redeclaration for a given model file. Loading @@ -87,12 +87,47 @@ def extract_default_class_from_model(file_path, folder='Sources', instance='sour Returns: list: A list of matches found for redeclared replaceable classes. """ # Define the regex pattern pattern = r'redeclare\s+replaceable\s+{}.(\w+)\s+{}'.format(folder, instance) # prefixes = [] # if include_redeclare: # prefixes.append('redeclare') # pattern = r'redeclare\s+replaceable\s+.*\{}.(\w+)\\s+{}'.format(prefixes, folder, instance) # if include_replaceable: # prefixes.append('replaceable') # # Combine to string ignoring all white space between # prefixes = r'\s+'.join(prefixes) # # # Define the regex pattern # pattern = r'{}\s+.*\{}.(\w+)\\s+{}'.format(prefixes, folder, instance) if include_redeclare and include_replaceable: pattern = r'\bredeclare\b\s+\breplaceable\b\s+.*\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) elif include_redeclare: pattern = r'redeclare\s+.*\\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) elif include_replaceable: pattern = r'replaceable\s+.*\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) else: pattern = r'\s+.*\\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) with open(file_path, 'r') as file: content = file.read() # lines = file.readlines() # pattern = r'\b(?:replaceable|redeclare)\b.*\{folder}.(\w+)\s+{}'.format(folder, instance) # # Test the pattern on each line # matches = [] # for line in lines: # match = re.search(pattern, line) # if match: # matches.append(match.group(1)) # # else: # # print("No match found.") # return matches matches = re.findall(pattern, content) return matches Loading examples/data/input_specification_default_simple.json 0 → 100644 +51 −0 Original line number Diff line number Diff line { "Name": "GenericDatacenter", "InstanceName":"simulator", "Structure":{"n":1}, "ModelClass":"v0", "Systems": [ { "Name": "Datacenter", "InstanceName":"datacenter", "Structure":{"n":1}, "Systems":[ { "Name": "CoolingBlock", "InstanceName":"computeBlock", "Structure":{"n":10}, "ModelClass":"v0", "Systems":[ { "Name": "CDU", "InstanceName":"cdu", "Structure":{"n":1}, "Systems":[{}] }, { "Name": "Cabinet", "Structure":{"n":3}, "InstanceName":"cabinet", "Systems":[{}] }] }] }, { "Name": "CentralEnergyPlant", "InstanceName":"centralEnergyPlant", "Structure":{"n":1}, "Systems":[ { "Name": "IntermediateLoop", "InstanceName":"intermediateLoop", "Structure":{"n":1}, "Systems":[{}] }, { "Name": "CoolingTowerLoop", "InstanceName":"coolingTowerLoop", "Structure":{"n":1}, "ModelClass":"v0", "Systems":[{}] }] }] } No newline at end of file examples/modelica/GenericDatacenter/Systems/Datacenter/Systems/CoolingBlock/Tests/Test_steady.mo +3 −5 Original line number Diff line number Diff line within GenericDatacenter.Systems.Datacenter.Systems.CoolingBlock.Tests; model Test_steady extends TemplatesCSM.BaseClasses.Tests.PartialTest_TwoPort_across_mT_pT (n=25, redeclare Models.v0 simulator(structure(cabinet(each n=3)), cabinet(sources(each Q_flow_total=if time < 1000 then 1e3 else 1e4)))); extends TemplatesCSM.BaseClasses.Tests.PartialTest_TwoPort_across_mT_pT(n=25, redeclare Models.v0 simulator(structure(cabinet(each n=3)), cabinet( sources(each Q_flow_total=if time < 1000 then 1e3 else 1e4)))); // extends ExaDigiT_AutoCSM.BaseClasses.Tests.PartialTest_TwoPort_across(n=27, // redeclare Models.v0 simulator(cabinet(sources(Q_flow_total=if time < 1000 Loading examples/modelica/run_auto_csm.py +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ if __name__ == "__main__": # Load the JSON specification csm.input_specification = '../data/input_specification_default.json' # csm.input_specification = '../data/input_specification_default_simple.json'# This uses the default ModelClass from the parent model if not specified in the JSON. # Set the path to output created files csm.output_path = 'temp' Loading Loading
AutoCSM/languages/modelica/create_model_nested.py +15 −6 Original line number Diff line number Diff line Loading @@ -51,10 +51,10 @@ def sources_line(data, project_path, base_path, model_class_path, key_path, unif temp_path = pathlib.Path(project_path).parts[:-1] model_path_list = list(temp_path) + model_class_path.split('.')[0:-2] + ['Models'] + [data['ModelClass'] + '.mo'] model_path = os.path.join(*model_path_list) model_path = pathlib.Path(*model_path_list) # Find the default by searching for "redeclare replaceable Sources.* sources" default_source_class = parse_files.extract_default_class_from_model(model_path, 'Sources', 'source')[0] default_source_class = parse_files.extract_default_class_from_model(model_path.as_posix(), 'Sources', 'sources')[0] # If 'SourceClass' is not in in the input file and is not the default, redeclare if 'SourceClass' in data.keys() and default_source_class != data['SourceClass']: Loading Loading @@ -106,7 +106,7 @@ def sources_line(data, project_path, base_path, model_class_path, key_path, unif line += f'sources({temp if temp else ""})\n' return line def create_nested_lines(data, project_path, base_path, uniform=[True,True], lines=None, is_top_system=True, key_path=None, level=0): def create_nested_lines(data, project_path, base_path, uniform=[True,True], lines=None, is_top_system=True, key_path=None, level=0, last_modelClass=None): """ Creates a list of lines representing the structure of the Modelica model. Loading @@ -133,8 +133,17 @@ def create_nested_lines(data, project_path, base_path, uniform=[True,True], line else: base_path = '.'.join([base_path, 'Systems', data['Name']]) model_class_path = '.'.join([base_path, 'Models', data['ModelClass']]) model_instance_name = data['InstanceName'] if is_top_system or'ModelClass' in data.keys(): model_class_path = '.'.join([base_path, 'Models', data['ModelClass']]) else: temp_path = pathlib.Path(project_path).parts[:-1] model_path_list = list(temp_path) + base_path.split('.')[0:-2] + ['Models'] + [last_modelClass + '.mo'] model_path = pathlib.Path(*model_path_list) data['ModelClass'] = parse_files.extract_default_class_from_model(model_path.as_posix(), 'Models', model_instance_name, include_redeclare=False)[0] model_class_path = '.'.join([base_path, 'Models', data['ModelClass']]) # Append line lines.append(f'redeclare {model_class_path} {model_instance_name}(') # Current system changes Loading @@ -147,7 +156,7 @@ def create_nested_lines(data, project_path, base_path, uniform=[True,True], line # Next system changes for sub_dict in data['Systems']: if sub_dict: # Terminate if dictionary is empty lines = create_nested_lines(sub_dict, project_path, base_path, uniform, lines, False, key_path, level+1) lines = create_nested_lines(sub_dict, project_path, base_path, uniform, lines, False, key_path, level+1, data['ModelClass']) lines.append(')') return lines Loading
AutoCSM/languages/modelica/parse_files.py +39 −4 Original line number Diff line number Diff line Loading @@ -75,7 +75,7 @@ def get_variable_by_type(file_path, dtype='parameter'): parameters = extract_variable(input_string, dtype) return parameters def extract_default_class_from_model(file_path, folder='Sources', instance='sources'): def extract_default_class_from_model(file_path, folder='Sources', instance='sources', include_redeclare=True, include_replaceable = True): """ Extracts the default class redeclaration for a given model file. Loading @@ -87,12 +87,47 @@ def extract_default_class_from_model(file_path, folder='Sources', instance='sour Returns: list: A list of matches found for redeclared replaceable classes. """ # Define the regex pattern pattern = r'redeclare\s+replaceable\s+{}.(\w+)\s+{}'.format(folder, instance) # prefixes = [] # if include_redeclare: # prefixes.append('redeclare') # pattern = r'redeclare\s+replaceable\s+.*\{}.(\w+)\\s+{}'.format(prefixes, folder, instance) # if include_replaceable: # prefixes.append('replaceable') # # Combine to string ignoring all white space between # prefixes = r'\s+'.join(prefixes) # # # Define the regex pattern # pattern = r'{}\s+.*\{}.(\w+)\\s+{}'.format(prefixes, folder, instance) if include_redeclare and include_replaceable: pattern = r'\bredeclare\b\s+\breplaceable\b\s+.*\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) elif include_redeclare: pattern = r'redeclare\s+.*\\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) elif include_replaceable: pattern = r'replaceable\s+.*\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) else: pattern = r'\s+.*\\b{}\b.(\w+)\s+\b{}\b'.format(folder, instance) with open(file_path, 'r') as file: content = file.read() # lines = file.readlines() # pattern = r'\b(?:replaceable|redeclare)\b.*\{folder}.(\w+)\s+{}'.format(folder, instance) # # Test the pattern on each line # matches = [] # for line in lines: # match = re.search(pattern, line) # if match: # matches.append(match.group(1)) # # else: # # print("No match found.") # return matches matches = re.findall(pattern, content) return matches Loading
examples/data/input_specification_default_simple.json 0 → 100644 +51 −0 Original line number Diff line number Diff line { "Name": "GenericDatacenter", "InstanceName":"simulator", "Structure":{"n":1}, "ModelClass":"v0", "Systems": [ { "Name": "Datacenter", "InstanceName":"datacenter", "Structure":{"n":1}, "Systems":[ { "Name": "CoolingBlock", "InstanceName":"computeBlock", "Structure":{"n":10}, "ModelClass":"v0", "Systems":[ { "Name": "CDU", "InstanceName":"cdu", "Structure":{"n":1}, "Systems":[{}] }, { "Name": "Cabinet", "Structure":{"n":3}, "InstanceName":"cabinet", "Systems":[{}] }] }] }, { "Name": "CentralEnergyPlant", "InstanceName":"centralEnergyPlant", "Structure":{"n":1}, "Systems":[ { "Name": "IntermediateLoop", "InstanceName":"intermediateLoop", "Structure":{"n":1}, "Systems":[{}] }, { "Name": "CoolingTowerLoop", "InstanceName":"coolingTowerLoop", "Structure":{"n":1}, "ModelClass":"v0", "Systems":[{}] }] }] } No newline at end of file
examples/modelica/GenericDatacenter/Systems/Datacenter/Systems/CoolingBlock/Tests/Test_steady.mo +3 −5 Original line number Diff line number Diff line within GenericDatacenter.Systems.Datacenter.Systems.CoolingBlock.Tests; model Test_steady extends TemplatesCSM.BaseClasses.Tests.PartialTest_TwoPort_across_mT_pT (n=25, redeclare Models.v0 simulator(structure(cabinet(each n=3)), cabinet(sources(each Q_flow_total=if time < 1000 then 1e3 else 1e4)))); extends TemplatesCSM.BaseClasses.Tests.PartialTest_TwoPort_across_mT_pT(n=25, redeclare Models.v0 simulator(structure(cabinet(each n=3)), cabinet( sources(each Q_flow_total=if time < 1000 then 1e3 else 1e4)))); // extends ExaDigiT_AutoCSM.BaseClasses.Tests.PartialTest_TwoPort_across(n=27, // redeclare Models.v0 simulator(cabinet(sources(Q_flow_total=if time < 1000 Loading
examples/modelica/run_auto_csm.py +1 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ if __name__ == "__main__": # Load the JSON specification csm.input_specification = '../data/input_specification_default.json' # csm.input_specification = '../data/input_specification_default_simple.json'# This uses the default ModelClass from the parent model if not specified in the JSON. # Set the path to output created files csm.output_path = 'temp' Loading