From 3aef57c83527b9ca1330bd1b0010102172f20052 Mon Sep 17 00:00:00 2001 From: Tiago Pires Date: Fri, 31 May 2024 18:05:06 +0100 Subject: [PATCH] Removed job_name from the input file and make the comparison case insensitive. --- .../abaqus_solver_fitting/description.md | 2 - examples/abaqus_solver_fitting/config.yaml | 1 - .../config_composite.yaml | 1 - piglot/solver/abaqus/fields.py | 27 +++-- piglot/solver/abaqus/reader.py | 102 ++++++++++++++++-- piglot/solver/abaqus/solver.py | 6 +- 6 files changed, 118 insertions(+), 21 deletions(-) diff --git a/docs/source/examples/abaqus_solver_fitting/description.md b/docs/source/examples/abaqus_solver_fitting/description.md index a3f5a01..053e2d5 100644 --- a/docs/source/examples/abaqus_solver_fitting/description.md +++ b/docs/source/examples/abaqus_solver_fitting/description.md @@ -38,7 +38,6 @@ objective: cases: 'sample.inp': - job_name: Job-1 # optional field for this case step_name: Step-1 # optional field for this case instance_name: Part-1-1 # optional field for this case fields: @@ -137,7 +136,6 @@ objective: cases: 'sample.inp': - job_name: Job-1 # optional field for this case step_name: Step-1 # optional field for this case instance_name: Part-1-1 # optional field for this case fields: diff --git a/examples/abaqus_solver_fitting/config.yaml b/examples/abaqus_solver_fitting/config.yaml index 24af04c..7e51008 100644 --- a/examples/abaqus_solver_fitting/config.yaml +++ b/examples/abaqus_solver_fitting/config.yaml @@ -19,7 +19,6 @@ objective: cases: 'sample.inp': - job_name: Job-1 # optional field for this case step_name: Step-1 # optional field for this case instance_name: Part-1-1 # optional field for this case fields: diff --git a/examples/abaqus_solver_fitting/config_composite.yaml b/examples/abaqus_solver_fitting/config_composite.yaml index 9edc144..5a3a04a 100644 --- a/examples/abaqus_solver_fitting/config_composite.yaml +++ b/examples/abaqus_solver_fitting/config_composite.yaml @@ -20,7 +20,6 @@ objective: cases: 'sample.inp': - job_name: Job-1 # optional field for this case step_name: Step-1 # optional field for this case instance_name: Part-1-1 # optional field for this case fields: diff --git a/piglot/solver/abaqus/fields.py b/piglot/solver/abaqus/fields.py index 066705b..7f8f17d 100644 --- a/piglot/solver/abaqus/fields.py +++ b/piglot/solver/abaqus/fields.py @@ -13,12 +13,18 @@ class AbaqusInputData(InputData): """Container for Abaqus input data.""" - def __init__(self, input_file: str, job_name: str, step_name: str, instance_name: str) -> None: + def __init__( + self, + input_file: str, + step_name: str, + instance_name: str, + job_name: str = None, + ) -> None: super().__init__() self.input_file = input_file - self.job_name = job_name self.step_name = step_name self.instance_name = instance_name + self.job_name = job_name def prepare( self, @@ -42,10 +48,20 @@ def prepare( AbaqusInputData Input data prepared for the simulation. """ + # Sanitize job_name + if self.job_name is None: + raise ValueError("Job name not specified. Call the 'check' method first.") + # Copy file and write out the parameters dest_file = os.path.join(tmp_dir, os.path.basename(self.input_file)) write_parameters(parameters.to_dict(values), self.input_file, dest_file) - return AbaqusInputData(dest_file, self.job_name, self.step_name, self.instance_name) + + return AbaqusInputData( + dest_file, + self.step_name, + self.instance_name, + job_name=self.job_name, + ) @staticmethod def __sanitize_field(field_name: str, field_list: List[str], keyword: str) -> str: @@ -106,7 +122,7 @@ def check(self, parameters: ParameterSet) -> None: data = file.read() job_list = re.findall(r'\*\* Job name: ([^M]+)', data) - job_list = [job.strip() for job in job_list] # Remove trailing whitespace + job_list = [job.strip() for job in job_list] self.job_name = self.__sanitize_field(self.job_name, job_list, "job") instance_list = re.findall(r'\*Instance, name=([^,]+)', data) @@ -140,8 +156,7 @@ def get_current(self, target_dir: str) -> AbaqusInputData: AbaqusInputData Current input data. """ - return AbaqusInputData(os.path.join(target_dir, os.path.basename(self.input_file)), - self.job_name, self.step_name, self.instance_name) + raise RuntimeError("Abaqus does not support extracting current results.") class FieldsOutput(OutputField): diff --git a/piglot/solver/abaqus/reader.py b/piglot/solver/abaqus/reader.py index f2e09be..f7ad1c3 100644 --- a/piglot/solver/abaqus/reader.py +++ b/piglot/solver/abaqus/reader.py @@ -32,7 +32,7 @@ def input_variables(): for var_name in variable_names: var_list = [a for a in args if a.startswith(var_name + "=")] - variables[var_name] = var_list[0].replace(var_name + '=', '') if var_list else None + variables[var_name] = var_list[0].replace(var_name + '=', '') return variables @@ -200,15 +200,101 @@ def write_output_file(i, variables_array, variable, step, location, file_name): output_file.write(" ") output_file.write("\n") +def get_step(odb, variables): + """Create a variable that refers to the respective step. + + Parameters + ---------- + odb : Odb + An instance of the Odb class from the Abaqus scripting interface, representing the output + database. + variables : dict + A dictionary containing the step name under the key "step_name". + + Returns + ------- + step : Step + The step from the output database that matches the name provided in the variables + dictionary. + + Raises + ------ + ValueError + Raises an error if the step name is not found in the output database. + """ + step_names_list = list(odb.steps.keys()) + step_names_list_upper = [stepName.upper() for stepName in step_names_list] + step_name_upper = variables["step_name"].upper() + if step_name_upper not in step_names_list_upper: + raise ValueError("Step name not found in the output database.") + + return step_names_list[step_names_list_upper.index(step_name_upper)] + +def get_instance(odb, variables): + """Create a variable that refers to the respective instance. + + Parameters + ---------- + odb : Odb + An instance of the Odb class from the Abaqus scripting interface, representing the output + database. + variables : dict + A dictionary containing the instance name under the key "instance_name". + + Returns + ------- + instance : str + The instance from the output database that matches the name provided in the variables + dictionary. + + Raises + ------ + ValueError + Raises an error if the instance name is not found in the output database. + """ + instance_names_list = list(odb.rootAssembly.instances.keys()) + instance_names_list_upper = [instanceName.upper() for instanceName in instance_names_list] + instance_name_upper = variables["instance_name"].upper() + if instance_name_upper not in instance_names_list_upper: + raise ValueError("Instance name not found in the output database.") + + return instance_names_list[instance_names_list_upper.index(instance_name_upper)] + +def get_set(odb, variables, instance): + """Create a variable that refers to the respective set. + + Parameters + ---------- + odb : Odb + An instance of the Odb class from the Abaqus scripting interface, representing the output + database. + variables : dict + A dictionary containing the set name under the key "set_name". + + Returns + ------- + set : str + The set from the output database that matches the name provided in the variables + dictionary. + + Raises + ------ + ValueError + Raises an error if the set name is not found in the output database. + """ + set_names_list = list(odb.rootAssembly.instances[instance].nodeSets.keys()) + set_names_list_upper = [setName.upper() for setName in set_names_list] + set_name_upper = variables["set_name"].upper() + if set_name_upper not in set_names_list_upper: + raise ValueError("Set name not found in the output database.") + + return set_names_list[set_names_list_upper.index(set_name_upper)] + def main(): """Main function to extract the nodal data from the output database (.odb) file. """ variables = input_variables() - instance_name = variables["instance_name"] - if instance_name is not None: - instance_name = variables["instance_name"].upper() - nlgeom = get_nlgeom_setting(variables["input_file"]) check_nlgeom(nlgeom, variables["field"], variables["x_field"]) @@ -219,12 +305,14 @@ def main(): odb = openOdb(path=odb_name) # Create a variable that refers to the respective step - step = odb.steps[variables["step_name"]] + step = get_step(odb, variables) + instance_name = get_instance(odb, variables) + set_name = get_set(odb, variables, instance_name) for i, var in enumerate(variables_array): node_sets = get_node_sets(instance_name, odb) for set_name, location in node_sets: - if set_name == str(variables["set_name"]): + if set_name == str(set_name): file_name = file_name_func(set_name, var, variables["input_file"]) write_output_file(i, variables_array, var, step, location, file_name) diff --git a/piglot/solver/abaqus/solver.py b/piglot/solver/abaqus/solver.py index a6e8369..fb6cc60 100644 --- a/piglot/solver/abaqus/solver.py +++ b/piglot/solver/abaqus/solver.py @@ -248,12 +248,10 @@ def read(config: Dict[str, Any], parameters: ParameterSet, output_dir: str) -> S for field_name, field_config in case_config['fields'].items() } # If job_name, step_name and instance_name are not indicated, the default value is None - job_name = case_config.get('job_name', None) step_name = case_config.get('step_name', None) instance_name = case_config.get('instance_name', None) - cases.append(Case(AbaqusInputData(case_name, job_name, - step_name, - instance_name), fields)) + cases.append(Case(AbaqusInputData(case_name, step_name, instance_name), fields)) + # Return the solver return AbaqusSolver( cases,