### ===================================================================================================================
### Find 3 reference nodes for walls
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, List, Tuple, Optional, Dict
# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_smaller, fem_greater
from rhdhv_fem.shapes import Wall
from rhdhv_fem.mesh import MeshNode
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
### ===================================================================================================================
### 2. Function to find 3 mesh-nodes for all walls
### ===================================================================================================================
[docs]def viia_find_wall_reference_nodes(
project: ViiaProject, return_dict: bool = False) -> Optional[List[MeshNode], Dict[Wall, List[MeshNode]]]:
"""
This function will determine for all walls in the model the reference mesh-nodes. It will collect the center bottom,
center and center top mesh-nodes. For these nodes the displacements are collected in the analysis and plotted in the
result handling.
.. warning:: The model must be meshed! For DIANA the dat-file should have been created and read.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- return_dict (bool): Adding an option to return a mapping between the shapes and nodes. By default, return_dict
is set to False.
Output:
- Returns a string with the requested nodes (when debug = False) or node list (when debug = True).
"""
# Loop through all walls in the model
shape_mesh_node = {}
mesh_node_list = []
for wall in project.collections.walls:
if wall.mesh is not None:
nodes, _ = viia_find_3_mesh_nodes_on_wall(project=project, wall=wall)
mesh_node_list.extend(nodes)
shape_mesh_node[wall] = nodes
# Check how the output is requested
if return_dict:
return shape_mesh_node
return mesh_node_list
### ===================================================================================================================
### 3. Function to find 3 mesh-nodes for single wall
### ===================================================================================================================
[docs]def viia_find_3_mesh_nodes_on_wall(project: ViiaProject, wall: Wall) -> Tuple[List[MeshNode], List[List[float]]]:
"""
This function will look for the closest node in the mesh to the point in the bottom center, the center and the top
center. The center is determined to be the average x- and y-coordinate between the biggest and smallest x- and
y-coordinate of the contour of the wall. The point at the bottom is equal to the lowest z-coordinate, the top point
the maximum z-coordinate of the contour of the wall and one in between those two.
.. warning:: The model must be meshed, the dat-file should have been created and the dat-file should have been read.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- wall (obj): Object reference of Wall.
Output:
- Two variables are returned: A list with three MeshNode objects and a list with the coordinates of three center
locations (bottom, middle, top) at the wall.
"""
if wall.mesh is None:
raise ValueError(f"ERROR: Mesh is not present for {wall.name}. Reference mesh-nodes could not be retrieved.")
mesh_nodes = wall.mesh.get_meshnodes()
# Find min and max coordinates of wall
x_max = -1000
x_min = 1000
y_max = -1000
y_min = 1000
z_max = -1000
z_min = 1000
for mesh_node in mesh_nodes:
if fem_smaller(x_max, mesh_node.coordinates[0]):
x_max = mesh_node.coordinates[0]
if fem_greater(x_min, mesh_node.coordinates[0]):
x_min = mesh_node.coordinates[0]
if fem_smaller(y_max, mesh_node.coordinates[1]):
y_max = mesh_node.coordinates[1]
if fem_greater(y_min, mesh_node.coordinates[1]):
y_min = mesh_node.coordinates[1]
if fem_smaller(z_max, mesh_node.coordinates[2]):
z_max = mesh_node.coordinates[2]
if fem_greater(z_min, mesh_node.coordinates[2]):
z_min = mesh_node.coordinates[2]
# Determine the center by averaging the x-, y- and z-coordinates
x_average = x_min + (x_max - x_min) / 2
y_average = y_min + (y_max - y_min) / 2
z_average = z_min + (z_max - z_min) / 2
# Target points
goals = [[x_average, y_average, z_min], [x_average, y_average, z_average], [x_average, y_average, z_max]]
goal_node = list()
# Determine the closest node by the coordinates
for goal in goals:
goal_node.append(wall.mesh.get_closest_mesh_node(point=goal))
# Return the mesh-nodes and the goal points
return goal_node, goals
### ===================================================================================================================
### 4. End of script
### ===================================================================================================================