def update_manifest(tbmanifest, computedValuesXml): logger = logging.getLogger(__name__) logger.info('\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~') logger.info('FUNCTION: UpdateReportJson_CAD()\n') if os.path.exists(tbmanifest): # read current summary report, which contains the metrics with open(tbmanifest, 'r') as file_in: result_json = json.load(file_in) # update analysis status if 'Status' in result_json: if os.path.exists('_FAILED.txt'): result_json['Status'] = 'FAILED' else: result_json['Status'] = 'OK' else: logger.debug('%s does not contain Status' % tbmanifest) if os.path.exists(computedValuesXml): ComputedMetricsSummary.ParseReqMetricsFile(computedValuesXml) if 'Metrics' in result_json: for metric in result_json['Metrics']: if 'Name' in metric and 'Value' in metric and 'GMEID' in metric: # key = metric['GMEID'] # JK 8/19/2016 How did this ever work? key = metric['ID'] if key not in ComputedMetricsSummary.gMetricSummary: key = metric['GMEID'] if key in ComputedMetricsSummary.gMetricSummary: # update metric's value to the last value in # time series metric['Value'] = None if metric.get('Unit') is not None and metric['Unit'] != '': metric['Value'] = convert_pp_metric(key, ComputedMetricsSummary.gMetricSummary[key][1], ComputedMetricsSummary.gMetricSummary[key][0], metric['Unit']) if metric['Value'] is None: metric['Value'] = ComputedMetricsSummary.gMetricSummary[key][1] metric['Unit'] = ComputedMetricsSummary.gMetricSummary[key][0] logger.debug('Metric: {0} {1} {2} was updated.'.format(metric['Name'], metric['Value'], metric['Unit'])) else: # metric was not found in results logger.debug('{1} key error: {0}'.format(key, computedValuesXml)) else: # create warning message logger.debug('% does not contain Metrics' % tbmanifest) else: logger.error('Given result file does not exist: {0}'.format(computedValuesXml)) # update json file with the new values with open(tbmanifest, 'wb') as file_out: json.dump(result_json, file_out, indent=4) logger.debug('Finished updating %s file.' % tbmanifest) else: logger.error('%s does not exist!' % tbmanifest)
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
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
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)
if __name__ == '__main__': try: feaName = None paramFile = None argList = sys.argv argc = len(argList) i = 0 while (i < argc): if (argList[i][:2] == '-i'): i += 1 feaName = utility_functions.right_trim(argList[i], '.dat') elif (argList[i][:2] == '-p'): i += 1 paramFile = argList[i] i += 1 if not feaName or not paramFile: exit(1) ComputedMetricsSummary.ParseXMLFile(paramFile) ComputedMetricsSummary.PrintComponentList( ComputedMetricsSummary.gComponentList) ParseCalculixOutputFile(feaName) ComputedMetricsSummary.WriteXMLFile( ComputedMetricsSummary.gComponentList) except Exception as e: print e print type(e) # prints the type of exception print type(e).__name__ # prints the type's name except ZeroDivisionError: print "division by zero!"