### ===================================================================================================================
### FUNTION: Collect information for the inspection report
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, List
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.reporting.helper_functions.get_l2_interfaces import get_l2_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 = []
mesh_elements = interface.mesh.mesh_elements
lengths = {}
for mesh_element in mesh_elements:
# lengths[mesh_element] = mesh_element.length # TODO this should be used when new mesh architecture is in place
lengths[mesh_element] = fem_distance_coordinates(
coordinate1=mesh_element.mesh_nodes[0].coordinates, coordinate2=mesh_element.mesh_nodes[1].coordinates)
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}.")
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}.")
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)
}
data = {}
if interfaces is None:
interfaces = get_l2_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': None, 't_y': None, 't_z': 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': None, 'du_y': None, 'du_z': 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
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("ERROR: Thickness could not be retrieved for interface {name}.")
result_data = {}
for stress_type in stress_types.keys():
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
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
### ===================================================================================================================