Source code for viiapackage.reporting.helper_functions.get_l2_measure_results

### ===================================================================================================================
###   FUNCTION: Collect information for the inspection report
### ===================================================================================================================
# Copyright ©VIIA 2025

### ===================================================================================================================
###   1. Import modules
### ===================================================================================================================

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, List

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.connections import Interface
from rhdhv_fem.fem_math import fem_distance_coordinates
from rhdhv_fem.analyses.analysis_reference import SteppedAnalysisReference

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.connections import viia_get_line_interfaces


### ===================================================================================================================
###   2. Function get_l2_measure_results
### ===================================================================================================================

[docs]def get_l2_measure_results(project: ViiaProject, interfaces: List[Interface] = None) -> dict: """ Get the results of L2 measures. Input: - project (obj): Project object reference containing collections of fem objects and project variables. - interfaces (list of obj): List of interfaces objects that needs to be considered. When None all the interfaces will be considered. Default is None. Output: - A dict with the result information of the L2 measures """ def get_average_stress_result(project, interface, output_results, output_item, analysis_references): avg_values = [] max_values = [] min_values = [] lengths = {mesh_element: mesh_element.length for mesh_element in interface.mesh.mesh_elements} total_length = sum(lengths.values()) for analysis_reference in analysis_references: result_dict = output_results.get_result_dict( output_item=output_item, analysis_reference=analysis_reference, software=project.software).results avg_value = 0 max_value = [] min_value = [] for key, value in result_dict.items(): if not isinstance(value, dict): raise ValueError( f"ERROR: Results should be stored at the integration points. Not at the nodes. Check the " f"results of {interface.name}.") if len(value.keys()) != 2 or not all([isinstance(val, int) for val in value.keys()]): raise ValueError( f"ERROR: Results should be stored at the 2 integration points. Check the results of " f"{interface.name}.") max_value.append(max(value.values())) min_value.append(min(value.values())) avg_value += lengths[key]*sum(value.values()) / 2 avg_values.append(avg_value/total_length) max_values.append(max(max_value)) min_values.append(min(min_value)) return { 'max_avg': sum(max_values) / len(max_values), 'avg': sum(avg_values) / len(avg_values), 'min_avg': sum(min_values) / len(min_values)} def get_max_min_envelope(project, thickness, output_results, output_item, analysis_references): element_max = {} element_min = {} for analysis_reference in analysis_references: result_dictionary = output_results.get_result_dict( output_item=output_item, analysis_reference=analysis_reference, software=project.software).results for mesh_element, result_values in result_dictionary.items(): if mesh_element not in element_max: element_max[mesh_element] = {} if mesh_element not in element_min: element_min[mesh_element] = {} for integration_point, result_value in result_values.items(): if integration_point not in element_max[mesh_element]: element_max[mesh_element][integration_point] = 0 if integration_point not in element_min[mesh_element]: element_min[mesh_element][integration_point] = 0 if result_value > element_max[mesh_element][integration_point]: element_max[mesh_element][integration_point] = result_value if result_value < element_min[mesh_element][integration_point]: element_min[mesh_element][integration_point] = result_value for mesh_element, result_values in element_max.items(): for integration_point, result_value in result_values.items(): element_max[mesh_element][integration_point] = result_value * thickness for mesh_element, result_values in element_min.items(): for integration_point, result_value in result_values.items(): element_min[mesh_element][integration_point] = result_value * thickness return element_max, element_min data = {} if interfaces is None: interfaces = viia_get_line_interfaces(project=project) if not interfaces: return data # get the analysis_references for average results all_analysis_references = [ analysis_reference for analysis_reference in interfaces[0].results.get_analysis_references() if isinstance(analysis_reference, SteppedAnalysisReference)] average_analysis_references = [ analysis_reference for analysis_reference in all_analysis_references if isinstance(analysis_reference, SteppedAnalysisReference) and analysis_reference.historic_envelope is None] envelope_analysis_references = [ analysis_reference for analysis_reference in all_analysis_references if isinstance(analysis_reference, SteppedAnalysisReference) and analysis_reference.historic_envelope is not None] if average_analysis_references: average_analysis_references = sorted( average_analysis_references, key=lambda analysis_reference: analysis_reference.step_nr) if envelope_analysis_references: envelope_analysis_references = sorted( envelope_analysis_references, key=lambda analysis_reference: analysis_reference.step_nr) # Get output items stress_types = {'t_x_tot_intp': None, 't_y_tot_intp': None, 't_z_tot_intp': None} for key in stress_types.keys(): if average_analysis_references: stress_types[key] = interfaces[0].results.get_output_item( engineering_notation=key, analysis_reference=average_analysis_references[0], software=project.software) elif envelope_analysis_references: stress_types[key] = interfaces[0].results.get_output_item( engineering_notation=key, analysis_reference=envelope_analysis_references[0], software=project.software) strain_types = {'du_x_tot_intp': None, 'du_y_tot_intp': None, 'du_z_tot_intp': None} for key in strain_types.keys(): if average_analysis_references: strain_types[key] = interfaces[0].results.get_output_item( engineering_notation=key, analysis_reference=average_analysis_references[0], software=project.software) elif envelope_analysis_references: strain_types[key] = interfaces[0].results.get_output_item( engineering_notation=key, analysis_reference=envelope_analysis_references[0], software=project.software) # Loops through the interfaces and retrieves the stresses and thickness to calculate the forces for interface in interfaces: results = interface.results if results is None: continue if not results.result_collections: continue # Exclude point and surface interfaces, axis system is different if not interface.connection_type == 'line-line': continue thickness = None if hasattr(interface.geometry.geometry_model.line_interface_type, 'thickness'): thickness = interface.geometry.geometry_model.line_interface_type.thickness else: obj = interface.geometry.geometry_model.line_interface_type.line_geometry thickness = getattr(obj, 'perimeter', None) if thickness is None: thickness = getattr(obj, 'thickness', None) if thickness is None: raise AttributeError(f"ERROR: Thickness could not be retrieved for interface {interface.name}.") result_data = {} for stress_type in stress_types.keys(): # Minimum and maximum result is the min/max result on the interface over all steps minimum_result = results.get_minimum_result(outputs=stress_type) maximum_result = results.get_maximum_result(outputs=stress_type) result_data[f'min_{stress_type}'] = [minimum_result[0], minimum_result[1] * thickness] result_data[f'max_{stress_type}'] = [maximum_result[0], maximum_result[1] * thickness] if average_analysis_references: average_stress_results = get_average_stress_result( project=project, interface=interface, output_results=results, output_item=stress_type, analysis_references=average_analysis_references) result_data[f'min_avg_{stress_type}'] = average_stress_results['min_avg'] * thickness result_data[f'avg_{stress_type}'] = average_stress_results['avg'] * thickness result_data[f'max_avg_{stress_type}'] = average_stress_results['max_avg'] * thickness # Maximum/minimum envelope element_max_results, element_min_results = get_max_min_envelope( project=project, thickness=thickness, output_results=results, output_item=stress_type, analysis_references=average_analysis_references) result_data[f'element_max_{stress_type}'] = element_max_results result_data[f'element_min_{stress_type}'] = element_min_results for strain_type in strain_types.keys(): minimum_result = results.get_minimum_result(outputs=strain_type) maximum_result = results.get_maximum_result(outputs=strain_type) result_data[f'min_{strain_type}'] = [minimum_result[0], minimum_result[1]] result_data[f'max_{strain_type}'] = [maximum_result[0], maximum_result[1]] data[interface] = result_data return data
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================