Source code for viiapackage.viiaSupports

### =============================================================================================================== ###
###                                                                                                                 ###
###                                                viiaSupports.py                                                  ###
###                                                                                                                 ###
### =============================================================================================================== ###
# This module enables to model the supports of the object. It contains functions for fixedbase supports and flexbase
# supports analysis.

# 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. Shallow foundations

#   3. Pile foundations

#   4. End of script

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

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

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.shapes import Surfaces, Wall, Fstrip, Beam, Column, Floor, Points, Pile
from rhdhv_fem.supports import PointSupport

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.supports import viia_collect_supported_shapes, viia_remove_supports, \
    viia_remove_shallow_foundation_supports, viia_create_shallow_foundation_fixedbase, \
    viia_create_shallow_foundation_flexbase, viia_get_shallow_foundation_material_properties_from_file, \
    viia_create_shallow_foundation_material, viia_connect_all_piles, viia_remove_pile_foundation_supports, \
    viia_create_piles_fixedbase, viia_create_piles_flexbase, viia_calculate_standard_values, \
    viia_collect_shallow_foundation_from_myviia, viia_calculate_shallow_foundation_from_myviia, \
    viia_get_pile_properties_from_myviia


### ===================================================================================================================
###    2. Shallow foundations
### ===================================================================================================================

[docs]def viia_create_supports( project: ViiaProject, support_type: str = 'FixedBase', material_file: Optional[Union[str, Path]] = None, material_dictionary: Optional[Dict[Union[str, Path], List[Surfaces]]] = None, excluded_supported_surfaces: Optional[List[Fstrip]] = None, additional_supported_shapes: Optional[List[Union[Floor, Wall, Fstrip, Beam, Column, Points]]] = None): """ Function to create the shallow foundation supports. The shallow foundation can be modelled for fixed-base or flexbase. It will apply the supports to the foundation strips in the model. Additional supported surfaces can be supported by providing those in a list, and foundation strips can be excluded (if there is a mixed foundation for example where there are piles connecting to certain foundation strips). Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - support_type (str): Type of shallow foundation, available are 'FixedBase', 'FlexBaseGlobal' and 'FlexBaseFinal'. Default value is 'FixedBase'. - material_file (str): Name of the dat-file for the flexbase, the dat-file will be provided by the geotechnical engineer. It should be located in the workfolder and is only required in case of 'FlexBaseGlobal', or might be required for 'FlexBaseFinal'. In case of 'FlexBaseFinal' it is assumed that this material should be applied on all supported surfaces, otherwise provide the material-dictionary instead. Default value is None. Alternative (path): The full path to the file can also be provided, the file location is then not required to be in the workfolder (still this is the suggested location). - material_dictionary (dict): Dictionary with the material properties for the 'FlexBaseFinal' supports. In this case multiple material files can be provided and supported surfaces should be linked to the material that should be applied on that support. - excluded_supported_surfaces (list with obj): List with object references or names of shapes which have to be excluded from the supported shapes list (not required). Default input is None, no foundation strips are excluded. - additional_supported_shapes (list with obj): List with object references of shapes which have to be supported in addition to shapes of class 'Fstrip' (not required). Default input is None, no shapes are added. Output: - The supports are created according the requirements for the phase. """ # Collect the list of shapes that are supported by shallow foundation supported_shapes = viia_collect_supported_shapes( project=project, excluded_supported_surfaces=excluded_supported_surfaces, additional_supported_shapes=additional_supported_shapes) # Validate input for foundation type to be created if support_type.lower() not in ['fixedbase', 'flexbaseglobal', 'flexbasefinal']: raise ValueError( f"ERROR: Please select foundation type from: FixedBase, FlexBaseGlobal and FlexBaseFinal. Provided was " f"{support_type}.") # Create fixedbase shallow foundation if support_type.lower() == 'fixedbase': # Check if any support is already applied, and remove those if project.viia_settings.support_type not in [None, 'FixedBase']: viia_remove_supports(project=project) else: viia_remove_shallow_foundation_supports(project=project) # Create the fixedbase shallow foundation project.viia_settings.support_type = 'FixedBase' return viia_create_shallow_foundation_fixedbase(project=project, supported_shapes=supported_shapes) # Create flexbase shallow foundation with single default material elif support_type.lower() == 'flexbaseglobal': # Check if any support is already applied, and remove those if project.viia_settings.support_type in ['FixedBase', 'FlexBaseFinal', None]: viia_remove_supports(project=project) else: viia_remove_shallow_foundation_supports(project=project) # Calculate the material properties standard values material_name, material_properties = viia_calculate_standard_values(project=project) # Create the material for flexbase shallow foundation material = viia_create_shallow_foundation_material( project=project, material_name=material_name, properties=material_properties) # Create the flexbase supports for shallow foundations project.viia_settings.support_type = 'FlexBaseGlobal' support_set = project.create_supportset('FlexBaseGlobal') # Create the flexbase global shallow foundation return viia_create_shallow_foundation_flexbase( project=project, supported_shapes=supported_shapes, material=material, support_set=support_set) # Create flexbase shallow foundation with materials from MYVIIA elif support_type.lower() == 'flexbasefinal' and material_file is None and material_dictionary is None: # Check if any support is already applied, and remove those if project.viia_settings.support_type in ['FixedBase', 'FlexBaseGlobal', None]: viia_remove_supports(project=project) else: viia_remove_shallow_foundation_supports(project=project) # Get the material properties from MYVIIA materials = viia_collect_shallow_foundation_from_myviia(project=project) material_name, material_properties = None, None if not materials: raise ValueError( "ERROR: No shallow foundation material has been found on MYVIIA. Please contact your geotechnical " "advisor.") elif len(materials) == 1: # In MYVIIA one shallow foundation material is provided, this is applied on all supported shapes material_name, material_properties = \ viia_calculate_shallow_foundation_from_myviia(project=project, data=materials[0]) elif len(materials) > 1: raise NotImplementedError( "ERROR: Multiple shallow foundation materials from MYVIIA has not been implemented yet. " "Please contact automating team.") material = viia_create_shallow_foundation_material( project=project, material_name=material_name, properties=material_properties) # Create the flexbase supports for shallow foundations if support_type.lower() == 'flexbaseglobal': project.viia_settings.support_type = 'FlexBaseGlobal' support_set = project.create_supportset('FlexBaseGlobal') else: project.viia_settings.support_type = 'FlexBaseFinal' support_set = project.create_supportset('FlexBaseFinal') return viia_create_shallow_foundation_flexbase( project=project, supported_shapes=supported_shapes, material=material, support_set=support_set) # Create flexbase shallow foundation with single material elif support_type.lower() == 'flexbasefinal' and material_file: # Check if material file is provided for flexbase if material_file is None: raise ValueError("ERROR: Please provide material-file for flexbase shallow foundation.") # Check if any support is already applied, and remove those if project.viia_settings.support_type in ['FixedBase', None] or ( support_type.lower() == 'flexbasefinal' and project.viia_settings.support_type == 'FlexBaseGlobal'): viia_remove_supports(project=project) else: viia_remove_shallow_foundation_supports(project=project) # Create the material for flexbase shallow foundation material_name, material_properties = viia_get_shallow_foundation_material_properties_from_file( project=project, material_file=material_file) material = viia_create_shallow_foundation_material( project=project, material_name=material_name, properties=material_properties) # Create the flexbase supports for shallow foundations if support_type.lower() == 'flexbaseglobal': project.viia_settings.support_type = 'FlexBaseGlobal' support_set = project.create_supportset('FlexBaseGlobal') else: project.viia_settings.support_type = 'FlexBaseFinal' support_set = project.create_supportset('FlexBaseFinal') return viia_create_shallow_foundation_flexbase( project=project, supported_shapes=supported_shapes, material=material, support_set=support_set) elif support_type.lower() == 'flexbasefinal': if material_dictionary is None: raise ValueError("ERROR: Please provide materials dictionary for flexbase shallow foundation.") # Check if any support is already applied, and remove those if project.viia_settings.support_type not in ['FlexBaseFinal']: viia_remove_supports(project=project) else: viia_remove_shallow_foundation_supports(project=project) project.viia_settings.support_type = 'FlexBaseFinal' support_set = project.create_supportset('FlexBaseFinal') collected = [] counter = 1 # Check the completeness for the shapes provided check_shapes = [] for dat, shapes in material_dictionary.items(): for i, shape in enumerate(shapes): if isinstance(shape, str): conv_shape = project.find(description=shape, collection='shapes') if conv_shape is None: raise ValueError(f"ERROR: Shape {shape} could not be found in the surface shape collection.") material_dictionary[dat][i] = conv_shape check_shapes.append(conv_shape) elif not isinstance(shape, Surfaces): raise ValueError(f"ERROR: Shape {shape} could not be found in the surface shape collection.") else: check_shapes.append(shape) for shape in check_shapes: if shape not in supported_shapes: raise ValueError( f"ERROR: Shape {shape.name} is not part of the supported shapes for shallow foundation, " f"make sure to add it first.") if list(set(supported_shapes).difference(set(check_shapes))): raise KeyError( "ERROR: Some of the supported surfaces were not provided in the material dictionary, please make sure " "to provide a material for all supported shapes before applying the flexbase supports. Differences: " f"{list(set(supported_shapes).difference(set(check_shapes)))}.") # Create the flexbase supports per material for material_file, shapes in material_dictionary.items(): material_name, material_properties = viia_get_shallow_foundation_material_properties_from_file( project=project, material_file=material_file) material = viia_create_shallow_foundation_material( project=project, material_name=material_name, properties=material_properties) # Create the flexbase supports for shallow foundations collected += viia_create_shallow_foundation_flexbase( project=project, supported_shapes=shapes, material=material, support_set=support_set, counter=counter) counter = int(len(collected) / 2) + 1 return collected
### =================================================================================================================== ### 3. Pile foundations ### ===================================================================================================================
[docs]def viia_create_piles( project: ViiaProject, coordinates: List[List[float]], support_type: str = 'FixedBase', pile_dimension: Optional[float] = None, pile_shape: Optional[str] = None, cross_section: Optional[str] = None, pile_group: Optional[str] = None, new_pile_foundation: bool = True, is_linear: bool = False, pile_numbers: Optional[List[Union[int, str]]] = None, plot_diagram: bool = False, horizontal_stiffness_factor: float = 1.0) -> List[Union[Pile, PointSupport]]: """ Function to create the pile foundation supports. The pile foundation can be modelled for fixed-base or flexbase. It will apply the supports for piles in the model. The pile will be connected to the foundation strip surface at that location (surface shape in Fstrip class). .. note:: If piles are located at the positions where there are several strips overlapping the same area at different height, the piles will be created under the lowest strip. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - coordinates (list of lists 2 floats): The x- and y-coordinate of the positions of the piles. The z-coordinate should not be provided. - support_type (str): Type of shallow foundation, available are 'FixedBase', 'FlexBaseGlobal' and 'FlexBaseFinal'. Default value 'FixedBase'. - pile_dimension (float): Dimension used for the pile, can be diameter or width/height of the cross-section. Implementation based on the pile_shape, in [m]. This input is only used in FixedBase. Default value None. - pile_shape (str): Type of shape of the pile. If 'circular' is selected a circular cross-section is created otherwise a square cross-section. Default value is 'square'. The shape should relate to the selected rebar configuration. This input is only used in FixedBase. Default value None. - cross_section (str): Alternative input for pile shape and dimension. The geometry of the pile cross-section, can be provided, following VIIA geometry name convention (e.g. 'D200' for circular cross-section with 200 mm diameter, '200x200' for rectangular cross-section with 200 mm width). Note that only square piles are allowed. This input is only used in FixedBase and will only be used if pile_shape and pile_dimension are None. Default value None. - pile_group (str): Name of the pile group (e.g. A, B, C...), to retrieve pile data from MYVIIA. - new_pile_foundation (bool): Select to remove all piles if foundation type is not changed (you should set to False if you are adding multiple pile-groups for all next pile-groups). Default value is True, removing any existing piles. - is_linear (bool): The piles can be modelled with linear material properties. This entails no failure criteria for the springs and linear concrete, without rebar modelling. Default value is False, normal non-linear behaviour is modelled. - pile_numbers (list): List of pile numbers that is used to number the piles. The user can overrule the auto-numbering by providing this list. The list should be of equal length as the list of coordinates. Default value is None, in which case the piles are numbered regularly (based on order of creation). It is also possible to provide a list of strings. - plot_diagram (bool): Option to create plot of the force-elongation diagram for the pile group. It will create an image in a folder 'Pile properties' in the working folder. Default value is False. Only applicable for flexbase piles, value ignored in other situations. - horizontal_stiffness_factor (float): Specifies the factor to adjust the horizontal stiffness of the piles. Default value is 1.0. Only applicable for flexbase piles, value ignored in other situations. Output: - Returns list of created piles and point supports. """ # Check inputs if pile_numbers is not None: if not isinstance(pile_numbers, list): raise TypeError( f"ERROR: Input for the viia_create_piles function is incorrect. Please provide the pile-numbers for " f"the piles as list, provided was {pile_numbers}.") if not all([isinstance(item, (int, str)) for item in pile_numbers]): raise TypeError( f"ERROR: Input for the viia_create_piles function is incorrect. Please provide the pile-numbers for " f"the piles as list of integers (or strings), provided was {pile_numbers}.") if len(pile_numbers) != len(coordinates): raise ValueError( f"ERROR: Input for the viia_create_piles function is incorrect. The length of the list with " f"pile-numbers ({len(pile_numbers)} pile-numbers) should be equal as the list of coordinates " f"({len(coordinates)} coordinates).") project.write_log("## Pile function started, adding piles. ##") # Create fixed-base pile foundation if support_type.lower() == 'fixedbase': # Check if any support is already applied, and remove those if project.viia_settings.support_type not in [None, 'FixedBase']: viia_remove_supports(project=project) elif new_pile_foundation: viia_remove_pile_foundation_supports(project=project) # Collect the location for the piles connecting_nodes = viia_connect_all_piles(project=project, coordinates=coordinates) # Check input for pile dimensions if pile_dimension is None and pile_shape is None and cross_section is None: # No dimensions provided, check if pile properties are available on MYVIIA pile_properties = viia_get_pile_properties_from_myviia( project=project, pile_group=pile_group, fixed_base=True) if pile_properties: pile_dimension = pile_properties['pile_dim'] pile_shape = 'square' if pile_properties['pile_shape'] == 'CIRCULAR': pile_shape = 'circular' else: raise ValueError("ERROR: No pile dimensions provided, and they could not be retrieved from MYVIIA.") elif pile_dimension is None and pile_shape is None and cross_section is not None: # Conversion for alternative input of cross-section for pile if cross_section.upper().startswith('D'): pile_dimension = int(cross_section[1:]) / 1000 pile_shape = 'circular' elif 'x' in cross_section.lower(): pile_dimension = int(cross_section.lower().split('x')[0]) / 1000 pile_shape = 'square' if pile_dimension != int(cross_section.lower().split('x')[-1]) / 1000: raise NotImplementedError("ERROR: Only square pile cross-sections are allowed.") else: raise ValueError(f"ERROR: The cross-section for the pile {cross_section} is not recognised.") if pile_dimension is None or pile_shape is None: raise ValueError("ERROR: The input for the pile dimensions was not correct, please check.") # Create the fixed-base pile foundation project.viia_settings.support_type = 'FixedBase' if new_pile_foundation: counter = 1 else: counter = len(project.collections.piles) + 1 return viia_create_piles_fixedbase( project=project, connecting_nodes=connecting_nodes, pile_group=pile_group, pile_dimension=pile_dimension, pile_shape=pile_shape, counter=counter, pile_numbers=pile_numbers) # Create flexbase shallow foundation with single material elif support_type.lower() in ['flexbaseglobal', 'flexbasefinal']: # Check if any support is already applied, and remove those if project.viia_settings.support_type is None or project.viia_settings.support_type.lower() not in \ ['flexbaseglobal', 'flexbasefinal']: viia_remove_supports(project=project) elif new_pile_foundation: viia_remove_pile_foundation_supports(project=project) # Collect the location for the piles connecting_nodes = viia_connect_all_piles(project=project, coordinates=coordinates) # Create the flexbase pile foundation if support_type.lower() == 'flexbaseglobal': project.viia_settings.support_type = 'FlexBaseGlobal' else: project.viia_settings.support_type = 'FlexBaseFinal' if new_pile_foundation: counter = 1 else: counter = len(project.collections.piles) + 1 return viia_create_piles_flexbase( project=project, connecting_nodes=connecting_nodes, pile_group=pile_group, counter=counter, is_linear=is_linear, pile_numbers=pile_numbers, plot_diagram=plot_diagram, horizontal_stiffness_factor=horizontal_stiffness_factor) # Unknown support-type else: raise ValueError( f"ERROR: Foundation-type input {support_type} unclear, select from 'FixedBase', 'FlexBaseGlobal' or " f"'FlexBaseFinal'. Default value is the 'FixedBase'.")
### =================================================================================================================== ### 4. End of script ### ===================================================================================================================