### ===================================================================================================================
### Function to create an Excel file with an overview of the connections
### ===================================================================================================================
# Copyright ©VIIA 2021
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from warnings import warn
from typing import TYPE_CHECKING, Union
from pathlib import Path
# References for functions and classes in the rhdhv_fem
from rhdhv_fem.analyses import SteppedAnalysisReference
from rhdhv_fem.tools.fem_get_historic_envelope_results import fem_get_historic_envelope_results
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
# Import module openpyxl for excel output of function
from openpyxl import Workbook
from openpyxl.worksheet.table import Table, TableStyleInfo
### ===================================================================================================================
### 2. Function viia_interface_extreme_results
### ===================================================================================================================
[docs]def viia_historic_extreme_envelope_interface_results(project: ViiaProject):
"""
Function to retrieve the historic extreme envelope results for point and line interfaces
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
Output:
- Four dictionaries with the extreme results for stress and relative displacement for point and line interfaces
"""
# Find output items
strain_output_items = [None, None, None]
for output_item in project.collections.strain_models:
if output_item.output_type == 'total' and \
output_item.theoretical_formulation == 'relative displacement' and \
output_item.operation == 'local':
if output_item.component == 'x':
strain_output_items[0] = output_item
elif output_item.component == 'y':
strain_output_items[1] = output_item
elif output_item.component == 'z':
strain_output_items[2] = output_item
if None in strain_output_items:
raise ValueError(
f"ERROR: Not all right strain_output_items are present in the python memory. "
f"Found are {strain_output_items}.")
stress_output_items = [None, None, None]
for output_item in project.collections.stress_models:
if output_item.output_type == 'total' and \
output_item.theoretical_formulation == 'traction' and \
output_item.operation == 'local':
if output_item.component == 'x':
stress_output_items[0] = output_item
elif output_item.component == 'y':
stress_output_items[1] = output_item
elif output_item.component == 'z':
stress_output_items[2] = output_item
if None in stress_output_items:
raise ValueError(
f"ERROR: Not all right stress_output_items are present in the python memory. "
f"Found are {stress_output_items}.")
# Find analysis references
analysis_references = project.collections.interfaces[0].results.get_analysis_references(
output_item=strain_output_items[0])
min_analysis_reference, max_analysis_reference, max_step = None, None, 0
for analysis_reference in analysis_references:
if isinstance(analysis_reference, SteppedAnalysisReference):
if analysis_reference.step_nr >= max_step:
max_step = analysis_reference.step_nr
if analysis_reference.historic_envelope == 'minimum':
min_analysis_reference = analysis_reference
elif analysis_reference.historic_envelope == 'maximum':
max_analysis_reference = analysis_reference
if min_analysis_reference is None:
raise LookupError("ERROR: Analysis reference for minimal extremes is not found.")
if max_analysis_reference is None:
raise LookupError("ERROR: Analysis reference for maximal extremes is not found.")
point_interfaces, line_interfaces, surface_interfaces = [], [], []
for interface in project.collections.interfaces:
if interface.connection_type == 'point-point':
point_interfaces.append(interface)
elif interface.connection_type == 'line-line':
line_interfaces.append(interface)
elif interface.connection_type == 'surface-surface':
surface_interfaces.append(interface)
else:
raise TypeError(f"ERROR: Unknown type of interface {interface}.")
if surface_interfaces:
warn("WARNING: Surfaces interfaces are not considered when retrieving the extreme results")
line_stress = fem_get_historic_envelope_results(
items=line_interfaces, output_items=stress_output_items, min_analysis_reference=min_analysis_reference,
max_analysis_reference=max_analysis_reference)
line_strain = fem_get_historic_envelope_results(
items=line_interfaces, output_items=strain_output_items, min_analysis_reference=min_analysis_reference,
max_analysis_reference=max_analysis_reference)
point_strain = fem_get_historic_envelope_results(
items=point_interfaces, output_items=strain_output_items, min_analysis_reference=min_analysis_reference,
max_analysis_reference=max_analysis_reference)
point_stress = fem_get_historic_envelope_results(
items=point_interfaces, output_items=stress_output_items, min_analysis_reference=min_analysis_reference,
max_analysis_reference=max_analysis_reference)
return point_stress, point_strain, line_stress, line_strain
### ===================================================================================================================
### 3. Function to create overview Excel file of the connections
### ===================================================================================================================
[docs]def viia_create_connection_overview_xls(project: ViiaProject, xls_location: Union[str, Path]) -> Path:
"""
Function to create an Excel file with information about the connections.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- xls_location (str or obj): Folder location where the Excel file should be made. Could be given as string or
Path object.
Output:
- An Excel file will be created at the give location with all the information about the connections.
"""
if isinstance(xls_location, str):
xls_location = Path(xls_location)
if not xls_location.is_dir():
raise ValueError(
f"ERROR: The given xls_location is not an existing folder. Please check the input location "
f"{xls_location.as_posix()}.")
xls_location = xls_location / 'connection_overview.xlsx'
# Get extreme results for interfaces
point_stress, point_strain, line_stress, line_strain = \
viia_historic_extreme_envelope_interface_results(project=project)
# Make printable lists for interfaces
new_lists = [None, None, None, None]
for i, _dicts in enumerate([point_stress, point_strain, line_stress, line_strain]):
new_list = []
for interface, value in _dicts.items():
for output_item, value_2 in value.items():
output_item_name = f'{output_item.get_diana_abbreviation(item=interface)} in [{output_item.unit}]'
new_list.append([
interface.name, output_item_name, value_2['minimum'], value_2['maximum'],
interface.connecting_shapes['source_connecting_shape'].name,
interface.connecting_shapes['target_connecting_shape'].name])
new_lists[i] = new_list.copy()
interface_specifics = {
'point_interface_stress': new_lists[0],
'point_interface_rel_disp': new_lists[1],
'line_interface_stress': new_lists[2],
'line_interface_rel_disp': new_lists[3]}
interface_header = ['Interface', 'Output item', 'Minimum', 'Maximum', 'Source', 'Target']
# Initialise workbook
wb = Workbook()
# Remove default sheet
wb.remove(worksheet=wb['Sheet'])
# Add a default style with striped rows and banded columns
style = TableStyleInfo(
name="TableStyleMedium1", showFirstColumn=False, showLastColumn=False, showRowStripes=True,
showColumnStripes=False)
# Add interface info to xls
for key, value in interface_specifics.items():
# Create new worksheet for interfaces
ws = wb.create_sheet(title=key)
# Add headers for interface
ws.append(interface_header)
# Add results to worksheet
for row in value:
ws.append(row)
# Set range as table to make the results searchable
tab = Table(displayName=key, ref=f"A1:F{len(value) + 1}")
# # Set the table style
tab.tableStyleInfo = style
# Add table to the worksheet
ws.add_table(tab)
for row, width in {'A': 35, 'B': 15, 'C': 15, 'D': 15, 'E': 65, 'F': 65}.items():
ws.column_dimensions[row].width = width
# Get all hinges
point_hinges = []
line_hinges = []
other_hinges = []
for hinge in project.collections.hinges:
if hinge.connection_type == 'point-point':
point_hinges.append(hinge)
elif hinge.connection_type == 'line-line':
line_hinges.append(hinge)
else:
other_hinges.append(hinge)
# Get processed connections
processed_connections = point_hinges + line_hinges + other_hinges
for interfaces in [point_stress, point_strain, line_stress, line_strain]:
processed_connections.extend(interfaces.keys())
# Get all other connections
other_connections = []
for connection in project.collections.connections:
if connection not in processed_connections:
other_connections.append(connection)
if other_connections:
other_connections = sorted(other_connections, key=lambda x: x.__class__.__name__)
connections_specifics = {
'point_hinges': point_hinges,
'line_hinges': line_hinges,
'other_hinges': other_hinges,
'other_connections': other_connections}
connection_headers = ['Connection', 'Type', 'Connection type', 'Source', 'Target']
for key, value in connections_specifics.items():
if not value:
project.write_log(
message=f"{key} are not found during executing {viia_create_connection_overview_xls.__name__}, for "
f"these connection not worksheet will be made in the xlsx file.", print_message=False)
continue
# Create new worksheet for connections
ws = wb.create_sheet(title=key)
# Add headers for interface
ws.append(connection_headers)
# Add results to worksheet
for connection in value:
_row = [
connection.name,
connection.__class__.__name__,
connection.connection_type,
connection.connecting_shapes['source_connecting_shape'].name,
connection.connecting_shapes['target_connecting_shape'].name]
ws.append(_row)
# Set range as table to make the results searchable
tab = Table(displayName=key, ref=f"A1:E{len(value) + 1}")
# # Set the table style
tab.tableStyleInfo = style
# Add table to the worksheet
ws.add_table(tab)
# Adjust columns
for row, width in {'A': 35, 'B': 15, 'C': 15, 'D': 65, 'E': 65}.items():
ws.column_dimensions[row].width = width
wb.save(xls_location)
if not xls_location.is_file():
raise FileExistsError(
f"ERROR: An Excel file with an overview of the connections is not created. Please report the issue.")
project.write_log(
f"An Excel file with an overview of the connections is created. The file location is {xls_location}.")
return xls_location
### ===================================================================================================================
### 4. End of script
### ===================================================================================================================