def update_results_files_xdb(self, results_txt_file): self.logger.info("Calling update_results_files_xdb()") status = True g_component_list = ComputedMetricsSummary.ParseMetaDataFile( self.meta_data_file, None, None) parse_out_file(results_txt_file, g_component_list, self.logger) req_metrics = ComputedMetricsSummary.ParseReqMetricsFile( self.requested_metrics, g_component_list) for component in g_component_list.values(): recurse_list(component, g_component_list) for component in g_component_list.values(): for comp in g_component_list.values(): if component.ComponentID in comp.Children and not comp.IsConfigurationID: # component is actually a child, so parent's metric data # should be updated - provided that child metrics are larger self.logger.debug(comp) if 'FactorOfSafety' in component.MetricsInfo: component.MetricsInfo[ 'FactorOfSafety'] = comp.MetricsInfo[ 'FactorOfSafety'] if 'VonMisesStress' in component.MetricsInfo: component.MetricsInfo[ 'VonMisesStress'] = comp.MetricsInfo[ 'VonMisesStress'] break if component.CadType == "PART": self.logger.info(str(len(component.FEAResults))) for name in component.FEAResults.keys(): self.logger.info("the key name is " + name) fos = float(component.Allowables.mechanical__strength_tensile ) / component.FEAResults["VM"] #fos = float(component.MaterialProperty['Mises']) / component.FEAResults["VM"] component.FEAResults['FOS'] = fos if 'FactorOfSafety' in component.MetricsInfo: component.MetricsOutput[ component.MetricsInfo['FactorOfSafety']] = fos if 'VonMisesStress' in component.MetricsInfo: component.MetricsOutput[component.MetricsInfo[ 'VonMisesStress']] = component.FEAResults["VM"] ################ CSV ############################### with open(self.filename + '.csv', 'wb') as f: writer = csv.writer(f) writer.writerow([ "Unique ID", "Allowable Stress", "Maximum Stress", "Factor of Safety" ]) for component in g_component_list.values(): if component.CadType == "PART": writer.writerow([ component.ComponentID, str(component.Allowables.mechanical__strength_tensile), str(component.FEAResults["VM"]), str(component.FEAResults["FOS"]) ]) ################ Populate Assembly Results ######### for component in g_component_list.values(): self.logger.info('ComponentID: %s' % component.ComponentID) self.logger.info(component) self.logger.info('') if component.CadType == "ASSEMBLY" and not component.IsConfigurationID: FOS = [] VM = [] for part in component.Children: FOS.append(g_component_list[part].FEAResults["FOS"]) VM.append(g_component_list[part].FEAResults["VM"]) component.FEAResults["FOS"] = min(FOS) component.FEAResults["VM"] = max(VM) component.MetricsOutput[ component.MetricsInfo['FactorOfSafety']] = min(FOS) component.MetricsOutput[ component.MetricsInfo['VonMisesStress']] = max(VM) ################ Populate Metrics ################# computed_values_xml = ComputedMetricsSummary.WriteXMLFile( g_component_list) ################ Update Results Json ############## if os.path.exists(self.results_json): UpdateReportJson_CAD.update_manifest(self.results_json, computed_values_xml) else: self.logger.error("Could not update file: " + self.results_json + ", file does not exist.") status = False self.logger.info( "Post Processing Complete, CSV and metrics updated") return status
def update_results_files_xdb_op2(self, result_txt_file): self.logger.info("Enter update_results_files_op2()") check_failure_criterion = False # Open Nastran_mod_out_v2.txt and read line by line self.logger.info("Working with {}".format(result_txt_file)) comp_id_to_value = {} globalMetrics = {} with open('Nastran_mod_out_v2.txt', 'r') as tb_file: # TODO: Need to see if it has Failure_Criteria, or VM or ??? # TODO: and handle all those cases for line in tb_file.readlines(): # line example: "FailureIndex,d44a4d66-1560-4634-9d20-c83c063be51d,1.0381887E-005" split_line = line.strip('\n').split(',') # Note if split_line[1] == this means that it is a global field (e.g. TotalVolume/TotalMass), which # does not have a comp_id_to_value if (len(split_line[1].strip()) != 0): comp_id_to_value[split_line[1]] = split_line[2] # The first entry will always be 'FailureIndex' ...? if split_line[0] == 'FailureIndex': check_failure_criterion = True else: # The following was added to support metrics such as TotalVolume/TotalMass globalMetrics[split_line[0].lower()] = split_line[2] if check_failure_criterion: # this is Failure_Criteria territory; all new code. # Open CADAssembly.xml (two directories up), and get ComponentID/MetricID map self.logger.info( "Getting Component/Metric IDs from CADAssembly.xml") metric_id_to_comp_id = {} cad_assembly_path = os.path.join('..', '..', 'CADAssembly.xml') if os.path.exists(cad_assembly_path): cad_assm_tree = letree.parse(cad_assembly_path) cad_assm_root = cad_assm_tree.getroot() metric_path = "Assembly/Analyses/FEA/Metrics/Metric" self.logger.info( "Searching for {} in update_results_files_op2()".format( metric_path)) metrics = cad_assm_root.findall(metric_path) for metric in metrics: metric_id = metric.attrib.get('MetricID') comp_id = metric.attrib.get('ComponentID') metric_id_to_comp_id[metric_id] = comp_id # Open TB manifest.json and put the value from component_id_to_value_map into the appropriate Metric self.logger.info("Updating Metrics in testbench_manifest.json") tb_metrics = None tb_manifest_json = None with open(self.results_json, 'r') as tb_file: tb_manifest_json = json.load(tb_file) tb_metrics = tb_manifest_json.get('Metrics') for metric in tb_metrics: metric_id = metric['ID'] metrid_name = metric['Name'] print metrid_name print globalMetrics if (metrid_name.lower() == "fea_total_volume" or metrid_name.lower() == "fea_total_mass"): if (metrid_name.lower() == "fea_total_volume"): metric_value = globalMetrics.get("TotalVolume".lower()) else: metric_value = globalMetrics.get("TotalMass".lower()) if metric_value is None: msg = "{} did not contain a Value for metric name for FEA_Total_Volume/FEA_Total_Mass {}.".format( ) self.write_failed_and_exit() else: associated_comp_id = metric_id_to_comp_id.get(metric_id) metric_value = comp_id_to_value.get(associated_comp_id) if metric_value is None: msg = "{} did not contain a Value for Component ID {}.".format( ) self.write_failed_and_exit() metric['Value'] = metric_value tb_manifest_json['Metrics'] = tb_metrics with open(self.results_json, 'w') as tb_file: json.dump(tb_manifest_json, tb_file, indent=4) return True else: # this is essentially the old method, except that the Nastran_mod_out_v2 allows us to skip a step. # TODO This is hacky, but I don't have the time to do it properly. JK 8/19/2016 g_component_list = ComputedMetricsSummary.ParseMetaDataFile( self.meta_data_file, None, None) parse_out_file_v2(result_txt_file, g_component_list, self.logger) # new method, skipping a step req_metrics = ComputedMetricsSummary.ParseReqMetricsFile( self.requested_metrics, g_component_list) for component in g_component_list.values(): recurse_list(component, g_component_list) for component in g_component_list.values(): for comp in g_component_list.values(): if component.ComponentID in comp.Children and not comp.IsConfigurationID: # component is actually a child, so parent's metric data # should be updated - provided that child metrics are larger self.logger.debug(comp) if 'FactorOfSafety' in component.MetricsInfo: component.MetricsInfo[ 'FactorOfSafety'] = comp.MetricsInfo[ 'FactorOfSafety'] if 'VonMisesStress' in component.MetricsInfo: component.MetricsInfo[ 'VonMisesStress'] = comp.MetricsInfo[ 'VonMisesStress'] break if component.CadType == "PART": self.logger.info(str(len(component.FEAResults))) for name in component.FEAResults.keys(): self.logger.info("the key name is " + name) fos = float( component.Allowables.mechanical__strength_tensile ) / component.FEAResults["VM"] #fos = float(component.MaterialProperty['Mises']) / component.FEAResults["VM"] component.FEAResults['FOS'] = fos if 'FactorOfSafety' in component.MetricsInfo: component.MetricsOutput[ component.MetricsInfo['FactorOfSafety']] = fos if 'VonMisesStress' in component.MetricsInfo: component.MetricsOutput[component.MetricsInfo[ 'VonMisesStress']] = component.FEAResults["VM"] ################ CSV ############################### with open(self.filename + '.csv', 'wb') as f: writer = csv.writer(f) writer.writerow([ "Unique ID", "Allowable Stress", "Maximum Stress", "Factor of Safety" ]) for component in g_component_list.values(): if component.CadType == "PART": writer.writerow([ component.ComponentID, str(component.Allowables. mechanical__strength_tensile), str(component.FEAResults["VM"]), str(component.FEAResults["FOS"]) ]) ################ Populate Assembly Results ######### for component in g_component_list.values(): self.logger.info('ComponentID: %s' % component.ComponentID) self.logger.info(component) self.logger.info('') if component.CadType == "ASSEMBLY" and not component.IsConfigurationID: FOS = [] VM = [] for part in component.Children: FOS.append(g_component_list[part].FEAResults["FOS"]) VM.append(g_component_list[part].FEAResults["VM"]) component.FEAResults["FOS"] = min(FOS) component.FEAResults["VM"] = max(VM) component.MetricsOutput[ component.MetricsInfo['FactorOfSafety']] = min(FOS) component.MetricsOutput[ component.MetricsInfo['VonMisesStress']] = max(VM) ################ Populate Metrics ################# computed_values_xml = ComputedMetricsSummary.WriteXMLFile( g_component_list) ################ Update Results Json ############## if os.path.exists(self.results_json): UpdateReportJson_CAD.update_manifest(self.results_json, computed_values_xml) else: msg = "Could not update file: {}, file does not exist.".format( self.results_json) self.logger.error(msg) self.write_failed_and_exit(msg) ################################################################################# # Update tb_manifest_json with fea_total_volume and fea_total_mass, if specified ################################################################################# tb_metrics = None tb_manifest_json = None with open(self.results_json, 'r') as tb_file: tb_manifest_json = json.load(tb_file) tb_metrics = tb_manifest_json.get('Metrics') found_mass_or_volume = False for metric in tb_metrics: metric_id = metric['ID'] metrid_name = metric['Name'] print metrid_name print globalMetrics if (metrid_name.lower() == "fea_total_volume" or metrid_name.lower() == "fea_total_mass"): found_mass_or_volume = True if (metrid_name.lower() == "fea_total_volume"): metric_value = globalMetrics.get("TotalVolume".lower()) else: metric_value = globalMetrics.get("TotalMass".lower()) metric['Value'] = metric_value if found_mass_or_volume: tb_manifest_json['Metrics'] = tb_metrics with open(self.results_json, 'w') as tb_file: json.dump(tb_manifest_json, tb_file, indent=4) return True
exit(1) return odb, metaDataFile, reqMetricsFile, resultsJson, adamsrun # =================================================================================================== # =================================================================================================== # START # if __name__ == '__main__': global gVersion if not os.path.isdir('log'): os.makedirs('log') gLogger = cad_library.setuplogger('ABQ_CompletePostProcess') odbName, metaDataFilePath, reqMetricsFilePath, resultsJsonPath, adams = ParseArgs( ) componentList = ComputedMetricsSummary.ParseMetaDataFile( metaDataFilePath, odbName, adams) reqMetrics = ComputedMetricsSummary.ParseReqMetricsFile( reqMetricsFilePath, componentList) CalculateMetrics(odbName, componentList, reqMetrics) computedValuesXml = ComputedMetricsSummary.WriteXMLFile(componentList) ComputedMetricsSummary.WriteMetric2File(componentList) UpdateReportJson_CAD.update_manifest(resultsJsonPath, computedValuesXml) if adams: utility_functions.CopyOrDeleteResults(odbName, resultsJsonPath, True) else: utility_functions.CopyOrDeleteResults(odbName, resultsJsonPath)
i += 1 if not any([odb, metaDataFile, reqMetricsFile, resultsJson]): exit(1) return odb, metaDataFile, reqMetricsFile, resultsJson, adamsrun # =================================================================================================== # =================================================================================================== # START # if __name__ == '__main__': global gVersion if not os.path.isdir('log'): os.makedirs('log') gLogger = cad_library.setuplogger('ABQ_CompletePostProcess') odbName, metaDataFilePath, reqMetricsFilePath, resultsJsonPath, adams = ParseArgs() componentList = ComputedMetricsSummary.ParseMetaDataFile(metaDataFilePath, odbName, adams) reqMetrics = ComputedMetricsSummary.ParseReqMetricsFile(reqMetricsFilePath, componentList) CalculateMetrics(odbName, componentList, reqMetrics) computedValuesXml = ComputedMetricsSummary.WriteXMLFile(componentList) ComputedMetricsSummary.WriteMetric2File(componentList) UpdateReportJson_CAD.update_manifest(resultsJsonPath, computedValuesXml) if adams: utility_functions.CopyOrDeleteResults(odbName, resultsJsonPath, True) else: utility_functions.CopyOrDeleteResults(odbName, resultsJsonPath)
for component in gComponentList.values(): print component.ComponentID print vars(component) print '' if component.CadType == "ASSEMBLY" and not component.IsConfigurationID: FOS = [] VM = [] for part in component.Children: FOS.append(gComponentList[part].FEAResults["FOS"]) VM.append(gComponentList[part].FEAResults["VM"]) component.FEAResults["FOS"] = min(FOS) component.FEAResults["VM"] = max(VM) component.MetricsOutput[component.MetricsInfo['FactorOfSafety']] = min(FOS) component.MetricsOutput[component.MetricsInfo['VonMisesStress']] = max(VM) ################ Populate Metrics ################# computedValuesXml = ComputedMetricsSummary.WriteXMLFile(gComponentList) ################ Update Results Json ############## if (os.path.exists(args.ResultsJson)): UpdateReportJson_CAD.update_manifest(args.ResultsJson, computedValuesXml) else: print "ERROR: Could not update file: " + args.ResultsJson + ", file does not exist." print "Post Processing Complete, CSV and metrics updated" sys.exit(0)
def update_results_files_op2(self, result_txt_file): self.logger.info("Enter update_results_files_op2()") check_failure_criterion = False # Open Nastran_mod_out_v2.txt and read line by line self.logger.info("Working with {}".format(result_txt_file)) comp_id_to_value = {} globalMetrics = {} with open('Nastran_mod_out_v2.txt', 'r') as tb_file: # TODO: Need to see if it has Failure_Criteria, or VM or ??? # TODO: and handle all those cases for line in tb_file.readlines(): # line example: "FailureIndex,d44a4d66-1560-4634-9d20-c83c063be51d,1.0381887E-005" split_line = line.strip('\n').split(',') # Note if split_line[1] == this means that it is a global field (e.g. TotalVolume/TotalMass), which # does not have a comp_id_to_value if ( len(split_line[1].strip()) != 0 ): comp_id_to_value[split_line[1]] = split_line[2] # The first entry will always be 'FailureIndex' ...? if split_line[0] == 'FailureIndex': check_failure_criterion = True else: # The following was added to support metrics such as TotalVolume/TotalMass globalMetrics[split_line[0].lower()] = split_line[2] if check_failure_criterion: # this is Failure_Criteria territory; all new code. # Open CADAssembly.xml (two directories up), and get ComponentID/MetricID map self.logger.info("Getting Component/Metric IDs from CADAssembly.xml") metric_id_to_comp_id = {} cad_assembly_path = os.path.join('..', '..', 'CADAssembly.xml') if os.path.exists(cad_assembly_path): cad_assm_tree = letree.parse(cad_assembly_path) cad_assm_root = cad_assm_tree.getroot() metric_path = "Assembly/Analyses/FEA/Metrics/Metric" self.logger.info("Searching for {} in update_results_files_op2()".format(metric_path)) metrics = cad_assm_root.findall(metric_path) for metric in metrics: metric_id = metric.attrib.get('MetricID') comp_id = metric.attrib.get('ComponentID') metric_id_to_comp_id[metric_id] = comp_id # Open TB manifest.json and put the value from component_id_to_value_map into the appropriate Metric self.logger.info("Updating Metrics in testbench_manifest.json") tb_metrics = None tb_manifest_json = None with open(self.results_json, 'r') as tb_file: tb_manifest_json = json.load(tb_file) tb_metrics = tb_manifest_json.get('Metrics') for metric in tb_metrics: metric_id = metric['ID'] metrid_name = metric['Name'] print metrid_name print globalMetrics if ( metrid_name.lower() == "fea_total_volume" or metrid_name.lower() == "fea_total_mass" ): if ( metrid_name.lower() == "fea_total_volume" ): metric_value = globalMetrics.get("TotalVolume".lower()) else: metric_value = globalMetrics.get("TotalMass".lower()) if metric_value is None: msg = "{} did not contain a Value for metric name for FEA_Total_Volume/FEA_Total_Mass {}.".format() self.write_failed_and_exit() else: associated_comp_id = metric_id_to_comp_id.get(metric_id) metric_value = comp_id_to_value.get(associated_comp_id) if metric_value is None: msg = "{} did not contain a Value for Component ID {}.".format() self.write_failed_and_exit() metric['Value'] = metric_value tb_manifest_json['Metrics'] = tb_metrics with open(self.results_json, 'w') as tb_file: json.dump(tb_manifest_json, tb_file, indent=4) return True else: # this is essentially the old method, except that the Nastran_mod_out_v2 allows us to skip a step. # TODO This is hacky, but I don't have the time to do it properly. JK 8/19/2016 g_component_list = ComputedMetricsSummary.ParseMetaDataFile(self.meta_data_file, None, None) parse_out_file_v2(result_txt_file, g_component_list, self.logger) # new method, skipping a step req_metrics = ComputedMetricsSummary.ParseReqMetricsFile(self.requested_metrics, g_component_list) for component in g_component_list.values(): recurse_list(component, g_component_list) for component in g_component_list.values(): for comp in g_component_list.values(): if component.ComponentID in comp.Children and not comp.IsConfigurationID: # component is actually a child, so parent's metric data # should be updated - provided that child metrics are larger self.logger.debug(comp) if 'FactorOfSafety' in component.MetricsInfo: component.MetricsInfo['FactorOfSafety'] = comp.MetricsInfo['FactorOfSafety'] if 'VonMisesStress' in component.MetricsInfo: component.MetricsInfo['VonMisesStress'] = comp.MetricsInfo['VonMisesStress'] break if component.CadType == "PART": self.logger.info(str(len(component.FEAResults))) for name in component.FEAResults.keys(): self.logger.info("the key name is " + name) fos = float(component.Allowables.mechanical__strength_tensile) / component.FEAResults["VM"] #fos = float(component.MaterialProperty['Mises']) / component.FEAResults["VM"] component.FEAResults['FOS'] = fos if 'FactorOfSafety' in component.MetricsInfo: component.MetricsOutput[component.MetricsInfo['FactorOfSafety']] = fos if 'VonMisesStress' in component.MetricsInfo: component.MetricsOutput[component.MetricsInfo['VonMisesStress']] = component.FEAResults["VM"] ################ CSV ############################### with open(self.filename + '.csv', 'wb') as f: writer = csv.writer(f) writer.writerow(["Unique ID", "Allowable Stress", "Maximum Stress", "Factor of Safety"]) for component in g_component_list.values(): if component.CadType == "PART": writer.writerow([component.ComponentID, str(component.Allowables.mechanical__strength_tensile), str(component.FEAResults["VM"]), str(component.FEAResults["FOS"])]) ################ Populate Assembly Results ######### for component in g_component_list.values(): self.logger.info('ComponentID: %s' % component.ComponentID) self.logger.info(component) self.logger.info('') if component.CadType == "ASSEMBLY" and not component.IsConfigurationID: FOS = [] VM = [] for part in component.Children: FOS.append(g_component_list[part].FEAResults["FOS"]) VM.append(g_component_list[part].FEAResults["VM"]) component.FEAResults["FOS"] = min(FOS) component.FEAResults["VM"] = max(VM) component.MetricsOutput[component.MetricsInfo['FactorOfSafety']] = min(FOS) component.MetricsOutput[component.MetricsInfo['VonMisesStress']] = max(VM) ################ Populate Metrics ################# computed_values_xml = ComputedMetricsSummary.WriteXMLFile(g_component_list) ################ Update Results Json ############## if os.path.exists(self.results_json): UpdateReportJson_CAD.update_manifest(self.results_json, computed_values_xml) else: msg = "Could not update file: {}, file does not exist.".format(self.results_json) self.logger.error(msg) self.write_failed_and_exit(msg) return True
def update_results_files_xdb(self, results_txt_file): self.logger.info("Calling update_results_files_xdb()") status = True g_component_list = ComputedMetricsSummary.ParseMetaDataFile(self.meta_data_file, None, None) parse_out_file(results_txt_file, g_component_list, self.logger) req_metrics = ComputedMetricsSummary.ParseReqMetricsFile(self.requested_metrics, g_component_list) for component in g_component_list.values(): recurse_list(component, g_component_list) for component in g_component_list.values(): for comp in g_component_list.values(): if component.ComponentID in comp.Children and not comp.IsConfigurationID: # component is actually a child, so parent's metric data # should be updated - provided that child metrics are larger self.logger.debug(comp) if 'FactorOfSafety' in component.MetricsInfo: component.MetricsInfo['FactorOfSafety'] = comp.MetricsInfo['FactorOfSafety'] if 'VonMisesStress' in component.MetricsInfo: component.MetricsInfo['VonMisesStress'] = comp.MetricsInfo['VonMisesStress'] break if component.CadType == "PART": self.logger.info(str(len(component.FEAResults))) for name in component.FEAResults.keys(): self.logger.info("the key name is " + name) fos = float(component.Allowables.mechanical__strength_tensile) / component.FEAResults["VM"] #fos = float(component.MaterialProperty['Mises']) / component.FEAResults["VM"] component.FEAResults['FOS'] = fos if 'FactorOfSafety' in component.MetricsInfo: component.MetricsOutput[component.MetricsInfo['FactorOfSafety']] = fos if 'VonMisesStress' in component.MetricsInfo: component.MetricsOutput[component.MetricsInfo['VonMisesStress']] = component.FEAResults["VM"] ################ CSV ############################### with open(self.filename + '.csv', 'wb') as f: writer = csv.writer(f) writer.writerow(["Unique ID", "Allowable Stress", "Maximum Stress", "Factor of Safety"]) for component in g_component_list.values(): if component.CadType == "PART": writer.writerow([component.ComponentID, str(component.Allowables.mechanical__strength_tensile), str(component.FEAResults["VM"]), str(component.FEAResults["FOS"])]) ################ Populate Assembly Results ######### for component in g_component_list.values(): self.logger.info('ComponentID: %s' % component.ComponentID) self.logger.info(component) self.logger.info('') if component.CadType == "ASSEMBLY" and not component.IsConfigurationID: FOS = [] VM = [] for part in component.Children: FOS.append(g_component_list[part].FEAResults["FOS"]) VM.append(g_component_list[part].FEAResults["VM"]) component.FEAResults["FOS"] = min(FOS) component.FEAResults["VM"] = max(VM) component.MetricsOutput[component.MetricsInfo['FactorOfSafety']] = min(FOS) component.MetricsOutput[component.MetricsInfo['VonMisesStress']] = max(VM) ################ Populate Metrics ################# computed_values_xml = ComputedMetricsSummary.WriteXMLFile(g_component_list) ################ Update Results Json ############## if os.path.exists(self.results_json): UpdateReportJson_CAD.update_manifest(self.results_json, computed_values_xml) else: self.logger.error("Could not update file: " + self.results_json + ", file does not exist.") status = False self.logger.info("Post Processing Complete, CSV and metrics updated") return status