### ===================================================================================================================
### Collect from MYVIIA and calculate pile properties
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING
# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_smaller
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
from viiapackage.database import myviia_get_pile
from viiapackage.pile_properties import shape_dict, pile_damping_ratio_map, pile_density_map, huan_beam_integration_map
from viiapackage.supports.pile_foundation.pile_properties import viia_calculate_pile_reinforcement, \
viia_calculate_spring_values, viia_calculate_huan_beam_properties, viia_plot_force_elongation_diagram
### ===================================================================================================================
### 2. Function to get the pile properties from MYVIIA and calculate all required values
### ===================================================================================================================
[docs]def viia_get_pile_properties_from_myviia(
project: ViiaProject, pile_group: str, fixed_base: bool = False, plot: bool = False) -> dict:
"""
Function to calculate and convert pile properties for the modelling in DIANA. Function is used when creating piles
with flex base.
Formulas used here are referred to excel tool 'VIIA_SXXX_Paalgegevens_NLTH_v1.12.xlsm' version v1.12 (Excel sheet
is only used for validation, not as a production tool).
Find the Excel here: https://royalhaskoningdhv.box.com/s/8wfzkhyfvdldwn7fj3hh5j31q3ieaync
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- pile group (str): Name of the pile group, choosing from A, B, C, etc. (only single letter is allowed). Make
sure to use the same name as specified in MYVIIA.
- fixed_base (bool): Select if the pile properties for only fixed base are required. Default value is False,
collecting all pile-properties for flexbase.
- plot (bool): Option to create the force-elongation diagrams for the pile group. It will create the diagram
in a folder 'Pile properties' in the working folder. Default value is False, not generating the pictures.
Output:
- Returns a dictionary that contains all pile properties for the chosen pile group.
"""
# Get all pile data based on the object-part ID
piles = myviia_get_pile(project.get_myviia_object_deel_id())
# Check pile group
data = None
for pile_data in piles:
if pile_data['pile_group'] == pile_group:
data = pile_data
break
# Validate the data of the pile group
if data is None:
if pile_group is None:
raise ValueError(
f"ERROR: No pile-group specified. You can select from "
f"{', '.join([str(pile_data['pile_group']) for pile_data in piles ])}, which are uploaded to MYVIIA.")
raise ValueError(
f"ERROR: Data for pile group '{pile_group}' is not present in MYVIIA database. Only data for pile group"
f" {', '.join([str(pile_data['pile_group']) for pile_data in piles ])} are present for "
f"object: {project.project_information['objectnummer_viia']}, "
f"object part: {project.project_information['objectdeel']}.")
if not fixed_base:
# Check if geotechnical advisor provided the information
missing_data = [
key
for key in [
'avg_soil_velocity', 'avg_soil_density', 'pile_cross_section_dimension', 'stiffness_length',
'effective_length', 'soil_poisson_ratio', 'soil_damping_ratio', 'spring_stiffness_z_geo',
'tensile_capacity_geo', 'compressive_capacity_geo'] if data[key] is None]
if missing_data:
raise ValueError(
f"ERROR: Geotechnical engineer did not provide all analysis results for pile group '{pile_group}' in "
f"MYVIIA database. Please check with geotechnical engineer. Missing data is {missing_data}.")
# Check the input required from geotechnical advisor for flexbase
missing_data = [
key
for key in [
'avg_soil_velocity', 'avg_soil_density', 'pile_cross_section_dimension', 'stiffness_length',
'effective_length', 'soil_poisson_ratio', 'soil_damping_ratio', 'spring_stiffness_z_geo',
'tensile_capacity_geo', 'compressive_capacity_geo'] if data[key] == 0]
if missing_data:
raise ValueError(
f"ERROR: Geotechnical results are 0 (empty) for pile group '{pile_group}' in MYVIIA database. "
f"Please check with geotechnical engineer. Results equal to 0 are {missing_data}.")
elif data['force_elongation_diagram'] is {}:
raise ValueError(
f"ERROR: The geotechnical engineer has not provided the force-elongation diagram for pile group "
f"'{pile_group}' in MYVIIA database. Please check with geotechnical engineer.")
else:
project.write_log(f"Data for pile group '{pile_group}' for flexbase is retrieved from MYVIIA database.")
else:
project.write_log(
f"Data for pile group '{pile_group}' for fixed base analysis is retrieved from MYVIIA database.")
# Convert basic data to pile properties
pile_param = {
'pile_type': data['pile_type'],
'pile_tip_level': data['pile_tip_level'],
'pile_dim': data['pile_cross_section_dimension'],
'pile_shape': shape_dict[data['pile_cross_section_shape']]}
# Return the data for fixed base, for flexbase additional items are added
if fixed_base:
return pile_param
# Reform some data items
elongation_list = []
force_lst = []
for i in range(1, 14):
elongation_key = 'elongation_' + str(i)
force_key = 'force_' + str(i)
if elongation_key in data['force_elongation_diagram'] and force_key in data['force_elongation_diagram']:
if (data['force_elongation_diagram'][elongation_key] is not None)\
and (data['force_elongation_diagram'][force_key] is not None):
elongation_list.append(data['force_elongation_diagram'][elongation_key])
force_lst.append(data['force_elongation_diagram'][force_key])
else:
# If one of the value is missing, continue with the next item.
continue
if elongation_list and force_lst and len(elongation_list) == len(force_lst):
if elongation_list[0] != force_lst[0] != 0:
if len(elongation_list) < 13:
elongation_list.insert(0, 0)
force_lst.insert(0, 0)
project.write_log(
f"Data set (0, 0) is added to force-elongation diagram for pile group '{pile_group}'.")
else:
elongation_list[0] = 0
force_lst[0] = 0
project.write_log(
f"WARNING: The first data set of force-elongation diagram from geo engineer is "
f"replaced by (0, 0) for pile group '{pile_group}'.")
else:
raise ValueError(
f"ERROR: Force-elongation diagram data for '{pile_group}' is not in correct format. Please check it with "
f"geo engineer.")
# Check for correctness input geotechnical advisor last value in force-elongation diagram
if not all(i < j for i, j in zip(elongation_list, elongation_list[1:])):
raise ValueError("ERROR: Incorrect input for force-elongation diagram by geotechnical advisor in MYVIIA.")
# Collect some data
data['force_elongation_diagram'] = {'elongation': elongation_list, 'force': force_lst}
data['pile_damping_ratio'] = pile_damping_ratio_map[data['pile_type'].lower()]
data['pile_density'] = pile_density_map[data['pile_type'].lower()]
# Set the number of integration points for the Huan beam
pile_param['huan_beam_intergration'] = huan_beam_integration_map[data['pile_cross_section_shape']]
# Convert reinforcement properties
pile_param['pile_reinforcement'] = viia_calculate_pile_reinforcement(data=data)
# Convert spring properties
pile_param['spring_values'] = viia_calculate_spring_values(project=project, data=data)
# Convert Huan-beam properties
pile_param['huan_beam_properties'] = viia_calculate_huan_beam_properties(project=project, data=data)
# Find pile's effective length
if fem_smaller(data['effective_length'], 0) or \
not fem_smaller(data['effective_length'], data['pile_head_level'] - data['pile_tip_level']):
raise ValueError(
f"ERROR: Incorrect pile head/tip level input for pile group {pile_group}. The effective length should be "
f"between 0 and length of the pile.")
# Calculate the pile unloading stiffness
# Knowledgeteam: use average pile stiffness of top of pile
stiff_unload = 1 / (data['effective_length'] ** 3 / (3 * data['flexural_stiffness']))
# Calculate two points to define the force elongation diagram for the unloading behaviour
force_list_elastic = [0.00000E+00, stiff_unload]
elongation_list_elastic = [0.00000E+00, 1.00000E+00]
n_elastic = len(force_list_elastic)
# Find the force difference between the backbone (input force elongation diagram of the geotechnical advisor) and
# linear elastic (i.e. from the unloading stiffness) curves
force_list_plastic = \
[max(force_lst[i] - stiff_unload * elongation_list[i], 0.0) for i in range(len(elongation_list))]
elongation_list_plastic = elongation_list
n_plastic = len(force_list_plastic)
# Create plot of the pile properties
if plot:
viia_plot_force_elongation_diagram(
project=project, pile_group=pile_group, x_backbone=elongation_list, y_backbone=force_lst,
x_elastic=elongation_list_elastic, y_elastic=force_list_elastic, x_plastic=elongation_list_plastic,
y_plastic=force_list_plastic)
# Find the initial stiffness, not considering unloading
k_init = force_list_plastic[1] / elongation_list_plastic[1]
# Find dashpot material damping coefficient (this is different from the damping coefficient calculated by
# _calculate_spring_values(), which includes hysteric damping)
damping_coefficient = pile_param['spring_values']['spring_damping_x']
# Instantiate sub-dictionary for holding information specific to the user defined subroutine
pile_param['subroutine_data'] = {}
# Assemble the list with the material properties to be used in the user defined subroutine
# Arbitrarily use x-dir stiffness for this, y-dir would work as well
pile_param['subroutine_data']['material_parameters'] = [
k_init, damping_coefficient, n_elastic, n_plastic]
# Input the elastic unloading stiffness diagram
for i in range(len(force_list_elastic)):
pile_param['subroutine_data']['material_parameters'].append(force_list_elastic[i])
pile_param['subroutine_data']['material_parameters'].append(elongation_list_elastic[i])
# Input the plastic diagram
for i in range(len(force_list_plastic)):
pile_param['subroutine_data']['material_parameters'].append(force_list_plastic[i])
pile_param['subroutine_data']['material_parameters'].append(elongation_list_plastic[i])
# Transform material parameters to float
pile_param['subroutine_data']['material_parameters'] = [
float(v) for v in pile_param['subroutine_data']['material_parameters']]
# Record the initial state values, which are zeros
pile_param['subroutine_data']['initial_state_values'] = [0.0] * 4
# Record the initial value, which is zero
pile_param['subroutine_data']['initial_values'] = 0
return pile_param
### ===================================================================================================================
### 3. End of script
### ===================================================================================================================