Source code for viiapackage.pictures.result_pictures.helper_functions.result_pictures_and_plots

### ===================================================================================================================
###   Result pictures and plots for analysis
### ===================================================================================================================
# Copyright ©VIIA 2024

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

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, List, Union, Optional
from pathlib import Path

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.analyses import Analysis
from rhdhv_fem.shapes import Reinforcements
from rhdhv_fem.pictures import ResultPicture, View
from rhdhv_fem.output_items import StrainOutputItem, StressOutputItem

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.pictures.result_pictures.helper_functions import viia_load_result_picture_yaml, \
    viia_get_resultcase_info, viia_get_output_item, viia_get_scope_shape_sets, viia_get_result_picture_name, \
    viia_set_model_and_analysis_diana, viia_get_limits, viia_get_legend_values, viia_get_legend_colours


### ===================================================================================================================
###   2. Function to create the result pictures or plots
### ===================================================================================================================

[docs]def viia_create_result_pictures_plots( project: ViiaProject, analysis: Analysis = None, pictures: bool = True, view: Optional[View] = None) -> \ Union[List[ResultPicture], List[Path]]: """ Function to create the analysis result pictures or plots. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - analysis (obj): Object reference of analysis, to retrieve the result case, result items, result file and relevant information. If None is provided it will be checked if there is only one analysis and that one will be taken. Default is None. - pictures (bool): Indicates if pictures (to be made in the software gui) of plots (from python memory) should be made. - view (obj): View that should be used for the pictures. When None the default view will be used. Default is None. Output: - Returns the result pictures created for nonlinear time-history analysis. """ if pictures and (not (project.software == 'abaqus' or project.rhdhvDIANA.run_diana)) and \ not project.rhdhvDIANA.debug: project.write_log( "ERROR: Result pictures can only be made in DianaIE or for Abaqus. The creation of result pictures is " "aborted.") return [] if analysis is None: if len(project.collections.analyses) != 1: project.write_log( "WARNING: No analysis was given and number of analyses is not equal to 1. The function will be " "aborted.") return [] analysis = project.collections.analyses[0] if analysis.name in [ 'A4 - Lineair seismische analyse met fixed base', 'A12 - Niet-lineair seismische analyse met flexbase', 'A15 - Niet-lineair seismische analyse met flexbase met versterkingen' ]: analysis_type = 'nlth' elif analysis.name in [ 'A10 - Niet-lineair statische analyse met flexbase', 'A13 - Non-linear static flex base strengthening' ]: analysis_type = 'nls' elif analysis.name in ['A7 - Eigenwaarde analyse met flex base']: analysis_type = 'eigen' else: raise ValueError("ERROR: Analysis name is not recognised.") # Get the result picture dictionary picture_data = viia_load_result_picture_yaml(project=project) # Find the result scope result_scopes = picture_data['result_scope'][analysis.name] # Create defaults render, result_file = None, None # Not all plots are available yet available_plots = ['Dynamic-ShearNxy-Max', 'Dynamic-ShearNxy-Min'] # Create render and view if pictures: # The model is created if not project.rhdhvDIANA.model_created: if not project.diana_settings.latest_dat_file: project.diana_settings.latest_dat_file = project.viia_get_file( path=project.current_analysis_folder, suffix='.dat') if project.rhdhvDIANA.run_diana: viia_set_model_and_analysis_diana(project=project, analysis=analysis) if view is None: if project.rhdhvDIANA.model_created and project.rhdhvDIANA.run_diana: project.rhdhvDIANA.showAll('SHAPE') project.rhdhvDIANA.setViewPoint('ISO1') diana_view_point = list(project.rhdhvDIANA.currentViewPoint()).copy() view = project.create_view_from_diana_view_point(name='User_defined', diana_view_point=diana_view_point) else: view = project.create_view(name='ISO1') render = project.create_render( name=f'Render_{analysis.name.split(" - ")[0]}', geometry=None, mesh='solid shading with free face edge') # Loop through result scope and picture type pictures_plots = [] pictures_save_folders = [] tb_files_read = [] for pic_type_key, scopes in result_scopes.items(): # Not all plots are available yet if not pictures and pic_type_key not in available_plots: project.write_log( f"WARNING: Picture type {pic_type_key} is not yet available for plots.") continue picture_type = picture_data['picture_type'][pic_type_key] # Collect the output-block for the requested picture-type and set up the pasth of the result file output_block_pic = None if pictures: for output_block in analysis.calculation_blocks[-1].output_blocks: if output_block.name == picture_type['output_filename'].replace('SXXX_', ''): output_block_pic = output_block if output_block_pic is None: raise ValueError(f"ERROR: The output-block for {analysis.name} is not recognised.") result_file = project.current_analysis_folder / (output_block_pic.output_filename + '.dnb') else: for output_block in analysis.calculation_blocks[-1].output_blocks: if output_block.name == picture_type['output_filename'].replace('SXXX_', '') + '_TB': output_block_pic = output_block if output_block_pic is None: raise ValueError(f"ERROR: The output-block for {analysis.name} is not recognised.") result_file = project.current_analysis_folder / (output_block_pic.output_filename + '.tb') if result_file not in tb_files_read: project.read_diana_tbfile(file=result_file) tb_files_read.append(result_file) # Set units for the result picture unit_setting = None if picture_type.get('unit_type'): unit_setting = {} for unit_type, units in zip(picture_type.get('unit_type'), picture_type.get('units')): unit_setting[unit_type] = units # Get the step and execute block step, execute = viia_get_resultcase_info( analysis=analysis, analysis_block=analysis.calculation_blocks[-1], case=picture_type['case'], eigenfrequencies=None) # Loop through scopes, defining the shapes visible for scope in scopes: shapes_sets = viia_get_scope_shape_sets(project=project, scope=scope, pic_type=pic_type_key) # Defining the components, defining for example the directions for component in picture_type['components']: # Collect the output-item required for the result picture output_item = viia_get_output_item( project=project, picture_type=picture_type, output_item_lst=output_block_pic.output_items, component=component) if not output_item: continue # Interface results need an item to get the proper abbreviation, but others don't abbreviation = None if not ('Interfaces-storey' in scope and ('Line' in scope or 'Point' in scope)): if 'reinforcements' in scope.lower() and \ isinstance(output_item, (StrainOutputItem, StressOutputItem)): abbreviation = \ output_item.diana_result_picture( plot_type=picture_type['plot_type'], result_component=component, is_reinforcement_result=True)['component'] else: abbreviation = \ output_item.diana_result_picture( plot_type=picture_type['plot_type'], result_component=component)['component'] for layer, shapes in shapes_sets.items(): if not shapes: project.write_log( f"No picture created for {scope} for layer {layer} because there are no shapes present for " f"this picture. Picture for component {component} and picture key: {pic_type_key}.", print_message=False) continue if not isinstance(shapes, dict): # Make dict so same functionality can be used. shapes = {None: shapes} for property_item, property_shapes in shapes.items(): shapes = [shape for shape in property_shapes if not isinstance(shape, Reinforcements)] reinforcements = None if 'reinforcements' in scope.lower(): reinforcements = [shape for shape in property_shapes if isinstance(shape, Reinforcements)] # Log to logfile the process for pictures if not shapes and not reinforcements: project.write_log( f"No picture created for {scope} for layer {layer} because there are no shapes or " f"reinforcements present for this picture (in {property_item}). Picture for component " f"{component} and picture key: {pic_type_key}.", print_message=False) continue if not reinforcements and 'reinforcements' in scope.lower(): # No pictures created for reinforcements if they are not present continue shapes_as_str = [shape.name if hasattr(shape, 'name') else shape for shape in property_shapes] project.write_log( f"Creating picture {scope} for {property_item} ({', '.join(shapes_as_str)}) in " f"layer {layer}. Picture for component {component} and picture key: {pic_type_key}.", print_message=False) # Interface results need an item to get the proper abbreviation if 'Interfaces-storey' in scope and ('Line' in scope or 'Point' in scope): abbreviation = \ output_item.diana_result_picture( plot_type=picture_type['plot_type'], result_component=component, item=property_shapes[0])['component'] # Get the limits for criterion checks max_value, min_value, limit_found = viia_get_limits( project=project, shape_set=property_shapes, scope=scope, component=component, pic_type=pic_type_key, material=property_item, output_item=output_item) # if max and min value are None, save in a sub-folder save_folder = None if not limit_found: save_folder = project.current_analysis_folder / 'Non-standard materials result pictures' if not save_folder.exists(): save_folder.mkdir() # Decide the legend levels level_values = None upper_bound_colour = None lower_bound_colour = None if max_value or min_value: level_values = viia_get_legend_values( max_value=max_value, min_value=min_value, pic_type=pic_type_key, fraction_digits=5) upper_bound_colour, lower_bound_colour = viia_get_legend_colours(pic_type=pic_type_key) max_value = max(level_values) min_value = min(level_values) # Set the maximum and minimum value in the legend for the result picture type contour_legend = project.create_contour_legend( unit_settings=unit_setting, max_value=max_value, min_value=min_value, upper_bound_colour=upper_bound_colour, lower_bound_colour=lower_bound_colour, level_values=level_values, legend_size=[0.015, 0.8]) # Create the picture name pic_name = viia_get_result_picture_name( diana_component_abbreviation=abbreviation, scope=scope, pic_type_key=pic_type_key, layer=layer, material_type=property_item, analysis_type=analysis_type) if pictures: pictures_save_folders.append(save_folder) # Create the picture pictures_plots.append(project.create_result_picture( name=pic_name, analysis=analysis, render=render, shapes=shapes, reinforcements=reinforcements, view=view, output_block=output_block_pic, execute_block=execute, output_item=output_item, legend=contour_legend, result_layer=picture_type.get('result_layer'), step=step, plot_type=picture_type.get('plot_type'), result_file=result_file.as_posix())) else: historic_envelope = None if pic_type_key.split('-')[-1] in ['Max', '1', '4', '7']: historic_envelope = 'maximum' elif pic_type_key.split('-')[-1] in ['Min']: historic_envelope = 'minimum' if not save_folder: save_file = project.current_analysis_folder / (pic_name+'.png') else: save_file = save_folder / (pic_name+'.png') analysis_reference = project.get_analysis_reference( analysis=analysis, calculation_block=analysis.calculation_blocks[-1], execute_block=execute, step_nr=step, historic_envelope=historic_envelope) # Compute the maximum and minimum values of the plot contour for index, shape in enumerate(property_shapes): # Check if there are any results for the shape present, otherwise if not shape.results: continue # Collect the requested results result_collections = shape.results.get_result_collections( output_item=output_item, analysis_reference=analysis_reference) if index == 0: max_value_plot = max(result_collections[0].node_results) min_value_plot = min(result_collections[0].node_results) else: if max(result_collections[0].node_results) > max_value_plot: max_value_plot = max(result_collections[0].node_results) if min(result_collections[0].node_results) < min_value_plot: min_value_plot = min(result_collections[0].node_results) if analysis_reference: title_text = ( f'<b>{analysis_reference.analysis.name}<br>' f'Extreme {analysis_reference.historic_envelope} upto step ' f'{analysis_reference.step_nr}<br>' f'{output_item.theoretical_formulation}, {output_item.engineering_notation}</br>' f'min: {min_value_plot} {output_item.units}, ' f'max: {max_value_plot} {output_item.units}</b>') else: title_text = None project.plot_results_3d(output_item=output_item, node_averaging=False, legend=contour_legend, shapes=property_shapes, analysis_reference=analysis_reference, show_plot=False, show_mesh=False, save_file=save_file, title=title_text) # Create the result pictures when running in DIANA if pictures: if project.rhdhvDIANA.run_diana: # Getting result picture from existing result files current_dnb_file = None for picture in pictures_plots: picture.to_diana( current_dnb_file=current_dnb_file, folder=pictures_save_folders[pictures_plots.index(picture)]) current_dnb_file = picture.result_file elif project.software == 'abaqus': # Create the images in ABAQUS for picture in pictures_plots: picture.to_abaqus() # Notifications for user and return the created result pictures project.write_log(f"{len(pictures_plots)} result pictures for {analysis.name.split(' - ')[0]} are created.") else: # Notifications for user and return the created result plots project.write_log(f"{len(pictures_plots)} result plots for {analysis.name.split(' - ')[0]} are created.") return pictures_plots
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================