Source code for viiapackage.viiaMaterials

### =============================================================================================================== ###
###                                                                                                                 ###
###                                                 viiaMaterials.py                                                ###
###                                                                                                                 ###
### =============================================================================================================== ###
# This module ``viiaMaterials`` contains the functions that handle the material properties of the shapes and
# connections. It contains available functionality to create the material instances, based on VIIA conventions.

# Module is based on:
# VIIA_QE_R376 Basis of Design Retrofit Advice NLTH, v11.0, d.d. 29 August 2024
# VIIA_QE_R376 Basis of Design Step-by-Step MRS, v1.0, d.d. 21 January 2022
# VIIA_QE_R1674 Uitgangspuntenrapport engineering NLPO, v1.0, d.d. 1 August 2019

# This script was based upon the Constitution For Python At VIIA
# For use by VIIA
# Copyright RHDHV

### ===================================================================================================================
###    Contents
### ===================================================================================================================

#   1. Import modules

#   2. Function to create instance of Material class for VIIA

#   3. Functions for material conversions

#   4. End of script

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

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

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.shapes import Shapes
from rhdhv_fem.connections import Connections, Interface
from rhdhv_fem.materials import Material

# References for functions and classes in the viiaPackage
from viiapackage.materials import viia_create_material_model, viia_get_material_group, \
    viia_get_material_model_properties, viia_check_material_name, viia_get_material_group_constants, \
    viia_get_material_class
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject


### ===================================================================================================================
###   2. Function to create instance of Material class for VIIA
### ===================================================================================================================

[docs]def viia_create_materials( project: ViiaProject, material_name: str, hbv_span: Optional[float] = None, hbv_width: Optional[float] = None): """ This function will collect the arguments for the creation of an object based on the name of the element material. The VIIA naming convention is applied in this function and sub-functions it uses. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - material_name(str): Name of the element geometry. - hbv_span (float): Span of the floor for timber floors and roofs, in [m]. - hbv_width (float): Width of the floor, perpendicular to the span, for timber floors and roofs, in [m]. Output: - Returns the object reference to the 'Material' object that is created based on the input arguments. """ # Check if the material is already present (check on name) for material in project.collections.materials: if material.name == material_name: return material # Get the material-group material_group = viia_get_material_group( project=project, material_name=material_name) # Check if input is correct viia_check_material_name(project=project, material_name=material_name, material_group=material_group) # Set material group properties if material_group == 'USRDEF': material_group_properties = { 'class': 'user supplied', 'model': 'user supplied subroutine', 'aspects': []} else: material_group_properties = viia_get_material_group_constants(project=project, material_group=material_group) # Collect the material parameters in a dictionary and create the material model object material_model_properties = viia_get_material_model_properties( project=project, material_name=material_name, material_group=material_group, hbv_span=hbv_span, hbv_width=hbv_width) material_model = viia_create_material_model( project=project, material_group=material_group, material_group_properties=material_group_properties, material_name=material_name, material_model_properties=material_model_properties) # Get the material subclass material_subclass = viia_get_material_class(material_group=material_group, material_name=material_name) if material_subclass == 'Concrete': return project.create_user_defined_concrete( name=material_name, material_model=material_model, mass_density=material_model_properties['mass density']) elif material_subclass == 'Steel': return project.create_user_defined_steel( name=material_name, material_model=material_model, mass_density=material_model_properties['mass density']) elif material_subclass == 'Masonry': return project.create_user_defined_masonry( name=material_name, material_model=material_model, mass_density=material_model_properties['mass density']) elif material_subclass == 'Timber': return project.create_user_defined_timber( name=material_name, material_model=material_model, mass_density=material_model_properties['mass density']) elif material_subclass == 'ReinforcementSteel': return project.create_user_defined_reinforcement_steel( name=material_name, material_model=material_model, mass_density=material_model_properties.get('mass density')) elif material_subclass == 'Interface': return project.create_user_defined_interface_behaviour( name=material_name, material_model=material_model) elif material_subclass == 'DiscreteMass': return project.create_user_defined_discrete_mass( name=material_name, material_model=material_model) elif material_subclass == 'Spring': return project.create_user_defined_spring_behaviour( name=material_name, material_model=material_model) # The material subclass could not be found or is not recognised raise NotImplementedError( f"ERROR: Material with group '{material_group}' and name '{material_name}' are not implemented yet.")
### =================================================================================================================== ### 3. Functions for material conversions ### ===================================================================================================================
[docs]def viia_convert_material_to_linear(project: ViiaProject, material: Material) -> Material: """ Sub-function to convert material to linear material.""" # Check if material is already linear (VIIA naming convention) if 'LIN-' in material.name: return material # Create the new name for the material new_material_name = f'LIN-{material.name}' # Remove the mesh-dependency for masonry name_parts = ['-0.25x0.25', '-0.5x0.5', '-0.1x0.1'] for name_part in name_parts: if name_part in new_material_name: new_material_name = new_material_name.replace(name_part, '') # Check if the material already exists (complying to VIIA naming convention) for material_object in project.collections.materials: if material_object.name == new_material_name: return material_object # Create the new material new_material = project.viia_materials(new_material_name) # Update added mass if hasattr(material, "added_mass") and material.added_mass is not None: new_material.added_mass = material.added_mass new_material.mass_density = new_material.mass_density - material.added_mass return new_material
[docs]def viia_linear_properties(project: ViiaProject, shapes: List[Union[str, Shapes, Connections]] = None): """ This function removes all non-linear materials and replaces them for the linear version of it. It does not affect the soil, the soil-structure interaction (SSI) interface and the piles (which can be set linear separately). Function can operate before and after creating model in DIANA. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - shapes (list with obj): List with shape and/or connection object references, of which the properties must be adjusted. If 'None', all non-linear materials will be replaced, except for the above-mentioned materials. Alternative (list with str): List with shape and/or connection names, of which the properties must be adjusted. Output: - All non-linear materials of shape objects that are given, are replaced with the linear version. - If model is created the materials will be updated in DIANA. - A list is saved with references to original non-linear material that was assigned, this list can be found in project.project_specific['lists']['nonlinear shapes original']. - The object of the non-linear material is not removed when it is not used anymore. In DIANA the materials are removed when they are not used anymore (if model has been created). """ # Argument handling for input argument shapes if shapes: shapes = [project.viia_get_shape(name=shape) if isinstance(shape, str) else shape for shape in shapes] if not all([isinstance(shape, (Shapes, Connections)) for shape in shapes]): raise ValueError( "ERROR: The input for shapes in 'viia_linear_properties' should be a list of shapes and/or " "connections. Incorrect inputs are: " f"{', '.join([shape for shape in shapes if not isinstance(shape, (Shapes, Connections))])}.") else: shapes = project.collections.shapes + project.collections.connections # Create dictionary with all non-linear materials with shapes they are applied on in the original situation for shape_object in shapes: if hasattr(shape_object, 'material') and shape_object.material is not None: if not shape_object.material.is_linear: if 'GROND' not in shape_object.material.name and 'USRDEF' not in shape_object.material.name and \ 'PAAL' not in shape_object.material.name: if shape_object.material.name not in project.project_specific['lists']['nonlinear shapes original']: project.project_specific['lists']['nonlinear shapes original'][shape_object.material.name] = \ {'original material reference': shape_object.material, 'shapes': [shape_object]} else: project.project_specific['lists']['nonlinear shapes original'][shape_object.material.name][ 'shapes'].append(shape_object) # Create new linear materials based on the non-linear version # Apply new linear material for material_name in project.project_specific['lists']['nonlinear shapes original']: material_object = viia_convert_material_to_linear( project=project, material=project.project_specific['lists']['nonlinear shapes original'][ material_name]['original material reference']) # Update the dictionary with the new material object reference project.project_specific['lists']['nonlinear shapes original'][material_name]['new material reference'] = \ material_object # Update the shapes and connections with the new linear material for shape_object in project.project_specific['lists']['nonlinear shapes original'][material_name]['shapes']: # set properties to Linear for shapes (works for Interface, Spring and Shape objects) shape_object.material = material_object # Warning message in case Interfaces are being set to linear while running A4. if isinstance(shape_object, Interface): project.write_log( f"WARNING: Material for Interface: {shape_object} set to linear. If you are running A4" f" LTH analysis, please note that you don't need interfaces during A4. Remove interfaces" f"and re-run A4.") # Notify user shapes = [ shape.name for shape in project.project_specific['lists']['nonlinear shapes original'][material_name]['shapes']] project.write_log( f"Material {material_name} is replaced by {material_object.name} for elements: {', '.join(shapes)}.")
[docs]def viia_non_linear_properties(project: ViiaProject): """ This function replaces all linear materials created with viia_linear_properties with the original material. Function only works if viia_linear_properties has been executed. .. note:: The function viia_linear_properties must have been executed previously. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. Output: - All shapes and connections with originally non-linear materials are reset. """ # Reset to the original materials for material_name in project.project_specific['lists']['nonlinear shapes original']: # Add the original material to project again and create in DIANA if required original_material = \ project.project_specific['lists']['nonlinear shapes original'][material_name]['original material reference'] project.add(original_material) # Update the shapes and connections with the new linear material for shape_object in project.project_specific['lists']['nonlinear shapes original'][material_name]['shapes']: shape_object.material = project.project_specific['lists']['nonlinear shapes original'][material_name][ 'original material reference'] # Notify user shapes = \ [shape.name for shape in project.project_specific['lists']['nonlinear shapes original'][material_name]['shapes']] new_material_ref = \ project.project_specific['lists']['nonlinear shapes original'][material_name]['new material reference'] project.write_log( f"Material {new_material_ref.name} is reset to {material_name} for elements: {', '.join(shapes)}.") # Reset the 'project' attribute for non-linear shapes project.project_specific['lists']['nonlinear shapes original'] = {}
### =================================================================================================================== ### 4. End of script ### ===================================================================================================================