Source code for viiapackage.results.result_functions.viia_shear_forces

### ===================================================================================================================
###   Handle the results of the linear interfaces in the analysis
### ===================================================================================================================
# Copyright ©VIIA 2025

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

# General imports
from __future__ import annotations
import json
from warnings import warn
from typing import TYPE_CHECKING, Optional, Dict, Any, Union
from pathlib import Path

# References for functions and classes in the haskoning_structural package
from haskoning_structural.analyses import Analysis, AnalysisReference
from haskoning_structural.connections import Interface

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.connections import viia_get_line_interfaces
from viiapackage.reporting.helper_functions.get_l2_measure_results import get_l2_measure_results
from viiapackage.results.result_functions.helper_functions import viia_shear_forces_report


### ===================================================================================================================
###   2. Helper functions
### ===================================================================================================================

def _viia_create_shear_force_json(project: ViiaProject, data: Dict[Interface, Dict[str, Any]]) -> Path:
    """
    Function to store the data of the accelerations (in VIIA format) in a json-file in the current analysis folder.

    Input:
        - project (obj): VIIA project object containing collections of fem objects and project variables.
        - data (dict): Dictionary with the data of the graphs per direction.

    Output:
        - Generates a json-file in the current analysis-folder with the data of the accelerations.
        - Returns the path of the file created.
    """
    # Create json-file dump in the current analysis folder
    if project.current_analysis_folder is None:
        raise ValueError("ERROR: The analysis folder was not set correctly, please provide correct folder.")

    # Convert the data
    converted_data = {}
    for interface, interface_data in data.items():
        if isinstance(interface, Interface):
            interface_name = interface.name
        elif isinstance(interface, tuple) and all(isinstance(_interface, Interface) for _interface in interface):
            interface_name = ', '.join(_interface.name for _interface in interface)
        else:
            raise TypeError(
                f"ERROR: Interface key must be {Interface.__class__.__name__} or tuple of "
                f"{Interface.__class__.__name__} objects.")
        if interface_name in converted_data:
            raise RuntimeError(
                f"ERROR: The interface name '{interface_name}' is not unique in the shear force data, this is not "
                f"expected. Please inform the automation team with your script and 4B output.")
        new_interface_data = {}
        for item, item_data in interface_data.items():
            new_sub_data = item_data
            if isinstance(item_data, dict):
                new_sub_data = {}
                for output_item, sub_item_data in item_data.items():
                    engineering_notation = output_item.engineering_notation
                    new_sub_data[engineering_notation] = {}
                    for key, value in sub_item_data.items():
                        if isinstance(value, list):
                            if isinstance(value[0], AnalysisReference):
                                new_sub_data[engineering_notation][key] = [ar.name for ar in value]
                            else:
                                new_sub_data[engineering_notation][key] = value
                        elif isinstance(value, dict):
                            new_sub_data[engineering_notation][key] = {k.name: v for k, v in value.items()}
            elif isinstance(item_data, list) and all(isinstance(_int, Interface) for _int in item_data):
                new_sub_data = [intf.name for intf in item_data]
            new_interface_data[item] = new_sub_data

        converted_data[interface_name] = new_interface_data

    # Create json-dump file with the results
    dumpfile = project.current_analysis_folder / 'shear_forces.json'
    with open(dumpfile, 'w') as fd:
        json.dump(converted_data, fd, indent=2, sort_keys=True)
    return dumpfile


### ===================================================================================================================
###   3. Function to create shear forces report and info-json for the engineering report (TVA)
### ===================================================================================================================

[docs]def viia_shear_forces( project: ViiaProject, tb_file: Path, analysis: Analysis, signal: str, only_l2_measures: bool = True, averaging_window: Optional[Union[int, float]] = None) \ -> Optional[Path]: """ This function can be used to obtain the maximum and minimum forces in linear line interfaces. For default workflow this is implemented for the line interfaces applied as L2 strengthening measure. The output produces a detailed pdf document with the results plotted per interface. It also prepares for input in the tables of the engineering report (TVA), as a json-file. Input: - project (obj): Project object reference containing collections of fem objects and project variables. - tb_file (Path): Path to the location of the tb-file which contains the results of the stresses (tractions) and strains (relative displacements) in the linear interfaces from output 4A in the NLTH analysis. - analysis (obj): Object reference of the analysis for which the shear forces should be collected. - signal (str): Input of the signal number, to included signal in report. Can be S1-S11. - only_l2_measures (bool): Select to report on all linear interfaces, or only the linear interfaces that are applied as L2 measures. Default value is True, only reporting the results of the L2 measure linear interfaces. - averaging_window (int/float): The window size for the moving average functionality to smear out peaks over a window. If None, the default value from the viiaSettings is used. Only change this in consultation with the detail engineer. Default is None. Output: - Creates a Word document with the results per interface, including graphs that show the shear forces parallel and transverse to the interface. If possible, the Word document is converted to a pdf-file. - Returns the paths of the pdf-file. If the file could be generated. """ # Check if tb-file is present if '_OUTPUT_4B' not in tb_file.name or tb_file.suffix != '.tb' or not tb_file.exists(): project.write_log( "WARNING: Input file not recognised for shear force function, check your input. No report is generated " f"for the shear forces. Provided was {tb_file.as_posix()}") return None # Check the signal number if signal not in [f'S{i}' for i in range(1, 12)]: project.write_log( f"WARNING: Signal needs to be between S1-S11, current value {signal} is not allowed. No shear forces " f"report generated.") return None # Collect the line interfaces with a linear elastic material-model. Default workflow is to collect these for only # the L2 measures in the model interfaces = viia_get_line_interfaces(project=project, only_l2_measures=only_l2_measures, only_linear_material=True) if not interfaces: if only_l2_measures: project.write_log( f"WARNING: There are no L2 strengthening measures applied as line interfaces with a linear elastic " f"material-model in the model. No shear forces report generated.") else: project.write_log( f"WARNING: There are no line interfaces with a linear elastic material-model in the model. No shear " f"forces report generated.") return None # Raise warning that this feature is in development warn("WARNING: The feature to generate a report with the shear forces is in development. Please check the outcome " "and report any inconsistencies. Please provide feedback for the development of the contents.") # Collect the results from the DIANA tb-file project.read_diana_tbfile(file=tb_file, analysis=analysis) # Collect the data required for the report data = get_l2_measure_results(project=project, interfaces=interfaces, averaging_window=averaging_window) if not data: project.write_log( f"WARNING: No data available for shear force report. Something went wrong in the process, please check. " f"The DIANA tb-file is {tb_file.as_posix()}, the interfaces are {', '.join([i.name for i in interfaces])}.") return None # Create a json-file with the information collected for the engineering report _viia_create_shear_force_json(project=project, data=data) # Generate the report with the information of the shear forces return viia_shear_forces_report(project=project, data=data, signal=signal, analysis=analysis)
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================