### ===================================================================================================================
### CLASS: GeoOutput
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, List
from collections import namedtuple
from pathlib import Path
import json
# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_compare_values, fem_min_max_point_list, fem_angle_between_2_vectors
from rhdhv_fem.analyses import SteppedAnalysisReference, Analysis
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
from viiapackage.geometry import viia_get_fstrip_width, get_fstrip_average_length, get_fstrip_direction, \
get_fstrip_placement_point_for_geo
### ===================================================================================================================
### 2. Base-class for geo-output
### ===================================================================================================================
[docs]class GeoOutput:
""" This is the super-class for the output for the geotechnical assessment. It contains the general methods and sets
the general attributes."""
def __init__(self, foundation_type: str, support_type: str = 'FlexBaseFinal'):
"""
Input:
- foundation_type (str): The foundation type modelled in the model. The allowed values are 'mixed', 'strips'
or 'piles'.
- support_type (str): The support type modelled in the model. The default value is 'FlexBaseFinal'. The
allowed values are 'FixedBase', 'FlexBaseGlobal', 'FlexBaseFinal'.
"""
# When the instance of GeoOutput class is initialised, the project needs is assigned
self.project = None
# Element data from the .dat file
self.element_data = {}
# Foundation element data
self.foundation_elements = {
'fstrips': [],
'piles': []}
# Forces in the foundation elements
self.forces_foundation_elements = {
'fstrips': [],
'piles': []}
# Displacement in the pile foundation elements
self.displacements_foundation_elements = {
'piles': []}
# Set up the foundation type of the geo output
self.foundation_type = foundation_type
# Set up the support type of the geo output
self.support_type = support_type
@property
def foundation_type(self):
return self.__foundation_type
@foundation_type.setter
def foundation_type(self, foundation_type: str):
if foundation_type not in ['mixed', 'piles', 'strips']:
raise NotImplementedError(
f"ERROR: The provided {foundation_type} is not supported yet by the geo output class.")
self.__foundation_type = foundation_type
@property
def support_type(self):
return self.__support_type
@support_type.setter
def support_type(self, support_type: str):
if support_type not in ['FixedBase', 'FlexBaseGlobal', 'FlexBaseFinal']:
raise NotImplementedError(f"ERROR: The support type {support_type} is not implemented yet for geo-output.")
self.__support_type = support_type
[docs] @classmethod
def check_foundation_type(cls, project: ViiaProject):
"""Get the foundation type"""
foundation_type = None
support_types = set([support_set.name for support_set in project.collections.supportsets])
if any([support in support_types for support in ['FixedBase', 'FlexBaseGlobal', 'FlexBaseFinal']]):
foundation_type = 'strips'
if 'PileSupport' in support_types:
foundation_type = 'piles'
if any([support in support_types for support in
['FixedBase', 'FlexBaseGlobal', 'FlexBaseFinal']]):
foundation_type = 'mixed'
if not foundation_type:
raise NotImplementedError(
f"The foundation type in the dat file of project {project.name} could not be identified,"
f"please check the name convention of the foundations and the inputs.")
return foundation_type
[docs] def get_fstrip_elements(self):
""" Get the foundation strip elements."""
if self.foundation_elements['fstrips']:
return self.foundation_elements['fstrips']
for shape in [item.fstrip for item in self.forces_foundation_elements['fstrips']]:
info = dict()
info['object'] = shape
info['material'] = shape.material.name
info['thickness'] = shape.geometry.geometry_model.thickness
info['forces'] = []
# Set the minimum and maximum coordinates
min_max = fem_min_max_point_list(shape.get_points())
for key, value in min_max.items():
# min_max returns keys like 'min-x', while they should be 'min_x' here.
info[key.replace('-', '_')] = value
# Set the center point of the strip
info['x_coord'], info['y_coord'] = get_fstrip_placement_point_for_geo(shape)
# Get the width of the strip
info['width'] = viia_get_fstrip_width(fstrip=shape)
# Determine angle between fstrip and x axis
fstrip_direction = get_fstrip_direction(shape)
angle = fem_angle_between_2_vectors(fstrip_direction, [1, 0, 0], degrees=True)
info['angle'] = angle if not fem_compare_values(angle, 180) else 0 # Set angle to 0 if horizontal
# Get average length, in case it's not symmetrical
average_length = get_fstrip_average_length(fstrip=shape)
info['length'] = average_length
# add to foundation elements
self.foundation_elements['fstrips'].append(info)
return self.foundation_elements['fstrips']
[docs] def get_pile_elements(self):
""" Get the foundation pile elements."""
if self.foundation_elements['piles']:
return self.foundation_elements['piles']
for pile in self.project.collections.piles:
info = dict()
info["object"] = pile
info['material'] = pile.material.name
info["forces"] = []
part = pile.parent
if part is not None:
for connection in part.connections:
if "FCRITZ" in connection.name:
info["vertical spring"] = connection
break
# Set the minimum and maximum coordinates
min_max = fem_min_max_point_list(pile.get_points())
for key, value in min_max.items():
# min_max returns keys like 'min-x', while they should be 'min_x' here.
info[key.replace('-', '_')] = value
# Set the center point of the strip
info["x_coord"] = (min_max['x-max'] + min_max['x-min']) / 2.0
info["y_coord"] = (min_max['y-max'] + min_max['y-min']) / 2.0
# The pile naming convention is different for FixedBase and for FlexBase
# For FixedBase, the pile naming convention is 'PAAL-LIN-BETON-290x290-TYPE-A-1'
if self.project.viia_settings.support_type == 'FixedBase':
group_code = info['object'].name.split('-')[-2]
else:
# For FlexBase, the pile naming convention is 'PAAL-290x290-TYPE-Prefab-Paal-A-HUAN-1'
group_code = info['object'].name.split('-')[-3]
if group_code not in [chr(x) for x in range(ord('A'), ord('Z')+1)]:
raise ValueError(
f"ERROR: The naming convention is incorrect [{info['name']}]. The group code {group_code} could "
f"not be retrieved. Please select from 'A' to 'Z'.")
else:
info['group_nr'] = ord(group_code) - 64
self.foundation_elements['piles'].append(info)
return self.foundation_elements['piles']
[docs] def get_fstrip_pairs(self) -> namedtuple:
""" Method of 'GeoOutput' class to obtain the fstrips and the corresponding boundary interfaces from the
dat-file."""
# Container for name mapping
Fstrip_pair = namedtuple('Fstrip_pair', ['fstrip_obj', 'fstrip_itf'])
fstrip_pairs = []
# All boundary interface names
fstrips_boundary_itfs = [
fstrip for fstrip in self.project.collections.boundary_interfaces if 'VLAK-IF' in fstrip.name]
# All fstrip names
fstrips_lst = [
fstrip for fstrip in self.project.collections.fstrips if 'STROKEN' in fstrip.name]
# Since the coordinate should be the same, the node should be exactly the same
for fstrip_itf in fstrips_boundary_itfs:
fstrip_itf_nodes = fstrip_itf.mesh.get_meshnodes()
# Loop through all fstrips and find the corresponding fstrip
for fstrip in fstrips_lst:
fstrip_nodes = fstrip.mesh.get_meshnodes()
# The fstrip node is a subset of interface node
if all(i in fstrip_itf_nodes for i in fstrip_nodes):
# Create the mapping : 'F-STROKEN-LIN-MW-KLEI<1945-100-20' <-> 'F-VLAK-IF-FOS-20'
fstrip_pairs.append(Fstrip_pair(fstrip_obj=fstrip, fstrip_itf=fstrip_itf))
break
# Check if the boundary interface connects to floor shape
else:
# Loop through all floors and find the corresponding floor
for floor in self.project.collections.floors:
floor_nodes = floor.mesh.get_meshnodes()
# The floor node is a subset of interface node
if all(i in fstrip_itf_nodes for i in floor_nodes):
# Create the mapping : 'F-STROKEN-LIN-MW-KLEI<1945-100-20' <-> 'F-VLAK-IF-FOS-20'
fstrip_pairs.append(Fstrip_pair(fstrip_obj=floor, fstrip_itf=fstrip_itf))
break
# Raise an exception if there is no corresponding fstrip
else:
raise Exception(
f"ERROR: There is no corresponding shape for {fstrip_itf}, please check your model.")
return fstrip_pairs
[docs] def get_pile_pairs(self) -> namedtuple:
""" Method of 'GeoOutput' class to match the pile name and its nodes."""
Pile_pair = namedtuple(
'Pile_pair', ['pile_obj', 'pile_mesh_node', 'vertical_spring', 'spring_top_node'])
pile_pairs = []
pile_list = [
element for element in self.get_pile_elements()
if 'FCRIT' not in element['object'].name and 'ROT' not in element['object'].name]
for pile in pile_list:
pile_mesh_node = None
vertical_spring = None
spring_top_node = None
for node in pile['object'].mesh.get_meshnodes():
if fem_compare_values(node.coordinates[2], pile['z_max']):
pile_mesh_node = node
break
if pile['vertical spring'] is not None:
vertical_spring = pile['vertical spring']
spring_top_node = sorted(
pile['vertical spring'].mesh.get_meshnodes(), key=lambda x: x.coordinates[2])[-1]
pile_pairs.append(Pile_pair(
pile_obj=pile['object'], pile_mesh_node=pile_mesh_node,
vertical_spring=vertical_spring, spring_top_node=spring_top_node))
# Raise an exception if looped through and cannot find nodes
if pile_mesh_node is None:
raise Exception(
f"There is no corresponding node for pile {pile['object'].name}, please check your model")
return pile_pairs
[docs] def get_forces_from_abaqus(self, results_file: Path):
"""
Method to load forces per strip or per pile from a ABAQUS results json-file into the GeoOutput class.
Input:
results_file (Path): Path to json-file containing force output.
"""
# Type should be immutable, avoid nested dictionary
Fstrip_data = namedtuple('Fstrip_data', ['fstrip', 'forces'])
Pile_data = namedtuple('Pile_data', ['pile', 'forces'])
with open(results_file, 'r') as f:
data = json.load(f)
force_output = data.get('section_force_requests', None)
if not force_output:
self.project.write_log(f"ERROR: Section force requests were not found in file '{results_file.as_posix()}'.")
return self.forces_foundation_elements['piles'], self.forces_foundation_elements['fstrips']
for item in force_output['items']:
forces_per_phase = []
result_keys = item['force']['3']
for phase in result_keys:
forces_per_load_step = {'x': {}, 'y': {}, 'z': {}, 'time': {}}
for time, n in zip(result_keys[phase], range(len(list(result_keys[phase])))):
forces_per_load_step['x'][n] = list(item['force']['1'][phase][time].values())
forces_per_load_step['y'][n] = list(item['force']['2'][phase][time].values())
forces_per_load_step['z'][n] = list(item['force']['3'][phase][time].values())
forces_per_load_step['time'][n] = time
forces_per_phase.append(forces_per_load_step)
# Write to the namedtuple
if 'PAAL' in item['rhdhv_fem']['shape_name']:
shape_type = 'piles'
self.forces_foundation_elements[shape_type].append(Pile_data(
pile=self.project.viia_get(name=item['rhdhv_fem']['shape_name']),
forces=forces_per_phase))
else:
shape_type = 'fstrips'
self.forces_foundation_elements[shape_type].append(Fstrip_data(
fstrip=self.project.viia_get(name=item['rhdhv_fem']['shape_name']),
forces=forces_per_phase))
return self.forces_foundation_elements['piles'], self.forces_foundation_elements['fstrips']
[docs] def get_pile_displacements_from_abaqus(self, results_file: Path):
"""
Method to load displacements per pile from a ABAQUS results json-file into the GeoOutput class.
Input:
- results_file (Path): Path to json-file containing pile displacements.
"""
# Type should be immutable, avoid nested dictionary
Pile_data = namedtuple('Pile_data', ['pile', 'displacements'])
with open(results_file, 'r') as f:
data = json.load(f)
pile_displacement_output = data.get('displacement_requests', None)
if not pile_displacement_output:
self.project.write_log(f"ERROR: Displacement requests were not found in file '{results_file.as_posix()}'.")
return self.displacements_foundation_elements['piles']
for item in pile_displacement_output['items']:
displacement_per_phase = []
result_keys = item['displacement']['3']
for phase in result_keys:
displacement_per_load_step = {'x': {}, 'y': {}, 'z': {}, 'time': {}}
for time, n in zip(result_keys[phase], range(len(list(result_keys[phase])))):
displacement_per_load_step['x'][n] = list(item['displacement']['1'][phase][time].values())
displacement_per_load_step['y'][n] = list(item['displacement']['2'][phase][time].values())
displacement_per_load_step['z'][n] = list(item['displacement']['3'][phase][time].values())
displacement_per_load_step['time'][n] = time
displacement_per_phase.append(displacement_per_load_step)
# Write to the namedtuple
if 'PAAL' in item['rhdhv_fem']['shape_name']:
shape_type = 'piles'
else:
raise ValueError("ERROR: The foundation type is not piles.")
self.displacements_foundation_elements[shape_type].append(Pile_data(
pile=self.project.viia_get(name=item['rhdhv_fem']['shape_name']),
displacements=displacement_per_phase))
return self.displacements_foundation_elements['piles']
[docs] def get_forces_from_diana(self, tb_file: Path, data_type: str, analysis: Analysis):
"""
Method to load forces per strip or per pile from a DIANA tb-file into the GeoOutput class.
Input:
- tb_file (Path): Path to tb-file containing force output results.
- analysis (obj): Object reference of analysis of the results in the tb-file.
"""
def check_analysis_references(analysis_references_1, analysis_references_2, analysis_references_3):
""" Check the analysis_references """
def sort_analysis_references(analysis_references_list: List[SteppedAnalysisReference]):
analysis_references = []
for calculation_block in analysis_references_list[0].analysis.calculation_blocks:
analysis_reference_per_block = []
for analysis_reference in analysis_references_list:
if analysis_reference.calculation_block == calculation_block:
analysis_reference_per_block.append(analysis_reference)
analysis_references.extend(sorted(analysis_reference_per_block, key=lambda x: x.step_nr))
return analysis_references
if not (len(analysis_references_1) == len(analysis_references_2) == len(analysis_references_3)) or \
not all([analysis_references in analysis_references_1
for analysis_references in analysis_references_2]) or \
not all(analysis_references in analysis_references_1
for analysis_references in analysis_references_3) or \
not all(analysis_references in analysis_references_2
for analysis_references in analysis_references_1) or \
not all(analysis_references in analysis_references_2
for analysis_references in analysis_references_3) or \
not all(analysis_references in analysis_references_3
for analysis_references in analysis_references_1) or \
not all(analysis_references in analysis_references_3
for analysis_references in analysis_references_2):
raise ValueError("ERROR: Ambigous analysis references")
if all(isinstance(analysis_reference, SteppedAnalysisReference)
for analysis_reference in analysis_references_1):
analysis_references_1 = sort_analysis_references(analysis_references_list=analysis_references_1)
if all(isinstance(analysis_reference, SteppedAnalysisReference)
for analysis_reference in analysis_references_2):
analysis_references_2 = sort_analysis_references(analysis_references_list=analysis_references_2)
if all(isinstance(analysis_reference, SteppedAnalysisReference)
for analysis_reference in analysis_references_3):
analysis_references_3 = sort_analysis_references(analysis_references_list=analysis_references_3)
return analysis_references_1, analysis_references_2, analysis_references_3
def get_forces_from_diana_piles():
pile_pairs = self.get_pile_pairs()
Pile_data = namedtuple('Pile_data', ['pile', 'forces'])
software = pile_pairs[0].pile_obj.results.get_softwares()[0]
output_items = pile_pairs[0].pile_obj.results.get_output_items()
FNTX, FNTY, FNTZ = None, None, None
for output_item in output_items:
diana_abbreviation = output_item.get_diana_abbreviation(item=pile_pairs[0].pile_obj)
if 'FNTX' == diana_abbreviation:
FNTX = output_item
elif 'FNTY' == diana_abbreviation:
FNTY = output_item
elif 'FNTZ' == diana_abbreviation:
FNTZ = output_item
if FNTX is None or FNTY is None or FNTZ is None:
raise ValueError("ERROR: Output items are not found.")
analysis_references_1 = pile_pairs[0].pile_obj.results.get_analysis_references(output_item=FNTX)
analysis_references_2 = pile_pairs[0].pile_obj.results.get_analysis_references(output_item=FNTY)
analysis_references_3 = pile_pairs[0].pile_obj.results.get_analysis_references(output_item=FNTZ)
analysis_references_1, analysis_references_2, analysis_references_3 = \
check_analysis_references(analysis_references_1, analysis_references_2, analysis_references_3)
# Get sorted phases
for pile_pair in pile_pairs:
# Get results per phase per time step
forces_per_phase = []
forces_per_load_step = {'x': {}, 'y': {}, 'z': {}, 'time': {}}
for index in range(len(analysis_references_1)):
# Only consider last phase
if analysis_references_1[index].analysis.calculation_blocks[-1] != \
analysis_references_1[index].calculation_block:
continue
result_location = pile_pair.pile_obj
forces_per_load_step['x'][analysis_references_1[index].step_nr] = \
result_location.results.get_result_value(
output_item=FNTX, analysis_reference=analysis_references_1[index], software=software,
mesh_element=result_location.mesh.mesh_elements[0], mesh_node=pile_pair.pile_mesh_node)
forces_per_load_step['y'][analysis_references_1[index].step_nr] = \
result_location.results.get_result_value(
output_item=FNTY, analysis_reference=analysis_references_1[index], software=software,
mesh_element=result_location.mesh.mesh_elements[0], mesh_node=pile_pair.pile_mesh_node)
forces_per_load_step['z'][analysis_references_1[index].step_nr] = \
result_location.results.get_result_value(
output_item=FNTZ, analysis_reference=analysis_references_1[index], software=software,
mesh_element=result_location.mesh.mesh_elements[0], mesh_node=pile_pair.pile_mesh_node)
if analysis_references_1[index].meta_data is not None:
forces_per_load_step['time'][analysis_references_1[index].step_nr] = \
analysis_references_1[index].meta_data.get('time', None)
else:
forces_per_load_step['time'][analysis_references_1[index].step_nr] = None
forces_per_phase.append(forces_per_load_step)
# Write to the namedtuple
self.forces_foundation_elements["piles"].append(Pile_data(pile=pile_pair.pile_obj,
forces=forces_per_phase))
def get_forces_from_diana_fstrips():
# Loop through all the fstrips
fstrip_pairs = self.get_fstrip_pairs()
# Type should be immutable, avoid nested dictionary
Fstrip_data = namedtuple('Fstrip_data', ['fstrip', 'forces'])
# Get the output by type
software = fstrip_pairs[0].fstrip_itf.results.get_softwares()[0]
output_items = fstrip_pairs[0].fstrip_itf.results.get_output_items()
STSx, STSy, STNz = None, None, None
for output_item in output_items:
if output_item.engineering_notation == 't_x_tot_intp':
STSx = output_item
elif output_item.engineering_notation == 't_y_tot_intp':
STSy = output_item
elif output_item.engineering_notation == 't_z_tot_intp':
STNz = output_item
if STSx is None or STSy is None or STNz is None:
raise ValueError("ERROR: Output-items for the geo-output could not be found.")
analysis_references_1 = fstrip_pairs[0].fstrip_itf.results.get_analysis_references(output_item=STSx)
analysis_references_2 = fstrip_pairs[0].fstrip_itf.results.get_analysis_references(output_item=STSy)
analysis_references_3 = fstrip_pairs[0].fstrip_itf.results.get_analysis_references(output_item=STNz)
analysis_references_1, analysis_references_2, analysis_references_3 = \
check_analysis_references(analysis_references_1, analysis_references_2, analysis_references_3)
# Loop through fstrips
for fstrip_pair in fstrip_pairs:
result_location = fstrip_pair.fstrip_itf
forces_per_phase = []
forces_per_load_step = {'x': {}, 'y': {}, 'z': {}, 'time': {}}
for index in range(len(analysis_references_1)):
# Only consider last phase
if analysis_references_1[index].analysis.calculation_blocks[-1] != \
analysis_references_1[index].calculation_block:
continue
forces_per_load_step['x'][analysis_references_1[index].step_nr] = 0
forces_per_load_step['y'][analysis_references_1[index].step_nr] = 0
forces_per_load_step['z'][analysis_references_1[index].step_nr] = 0
# Loop through all mesh elements of the interfaces
for mesh_element in result_location.mesh.get_meshelements():
element_area = mesh_element.get_area()
x = result_location.results.get_result_value(
output_item=STSx, analysis_reference=analysis_references_1[index], software=software,
mesh_element=mesh_element)
y = result_location.results.get_result_value(
output_item=STSy, analysis_reference=analysis_references_1[index], software=software,
mesh_element=mesh_element)
z = result_location.results.get_result_value(
output_item=STNz, analysis_reference=analysis_references_1[index], software=software,
mesh_element=mesh_element)
if len(x) not in [3, 4] or len(y) not in [3, 4] or len(z) not in [3, 4]:
raise ValueError(
f"ERROR: Only linear triangular or quadrilateral elements can be processed.")
# Add force of mesh element to step
forces_per_load_step['x'][analysis_references_1[index].step_nr] += \
element_area * sum(x.values()) / len(x)
forces_per_load_step['y'][analysis_references_1[index].step_nr] += \
element_area * sum(y.values()) / len(y)
forces_per_load_step['z'][analysis_references_1[index].step_nr] += \
element_area * sum(z.values()) / len(z)
if analysis_references_1[index].meta_data is not None:
forces_per_load_step['time'][analysis_references_1[index].step_nr] = \
analysis_references_1[index].meta_data.get('time', None)
else:
forces_per_load_step['time'][analysis_references_1[index].step_nr] = None
forces_per_phase.append(forces_per_load_step)
# Write to the namedtuple
self.forces_foundation_elements['fstrips'].append(Fstrip_data(
fstrip=fstrip_pair.fstrip_obj, forces=forces_per_phase))
# Read result
self.project.read_diana_tbfile(file=tb_file, analysis=analysis)
# Retrieve fstrip data
if data_type == 'fstrips':
get_forces_from_diana_fstrips()
# Retrieve pile data
elif data_type == 'piles':
get_forces_from_diana_piles()
return self.forces_foundation_elements['piles'], self.forces_foundation_elements['fstrips']
[docs] def get_pile_displacements_from_diana(self, tb_file: Optional[Path] = None):
"""
Method to load displacement per pile from a DIANA tb-file into the GeoOutput class.
Input:
- tb_file (Path): path to tb file containing force output. If tb-file is already read somewhere else None
should be given so the reading is skipped.
Output:
- Returns the displacement for each pile for all the time steps.
"""
pile_pairs = self.get_pile_pairs()
Pile_displacement = namedtuple('Pile_displacement', ['pile', 'x', 'y', 'z', 'time_step'])
# Read result
if tb_file is not None:
tb_file_diana = self.project.read_diana_tbfile(file=tb_file)
software = pile_pairs[0].pile_obj.results.get_softwares()[0]
if pile_pairs[0].vertical_spring:
output_items = pile_pairs[0].vertical_spring.results.get_output_items()
else:
output_items = pile_pairs[0].pile_obj.results.get_output_items()
TDtX, TDtY, TDtZ = None, None, None
for output_item in output_items:
diana_abbreviation = output_item.get_diana_abbreviation(item=pile_pairs[0].pile_obj)
if 'TDtX' == diana_abbreviation:
TDtX = output_item
elif 'TDtY' == diana_abbreviation:
TDtY = output_item
elif 'TDtZ' == diana_abbreviation:
TDtZ = output_item
if TDtX is None or TDtY is None or TDtZ is None:
raise ValueError("ERROR: Output items are not found.")
analysis_references = []
vertical_spring = False
if pile_pairs[0].vertical_spring:
vertical_spring = True
analysis_references = pile_pairs[0].vertical_spring.results.get_analysis_references(
output_item=TDtX, software=software)
else:
analysis_references = pile_pairs[0].pile_obj.results.get_analysis_references(
output_item=TDtX, software=software)
if not analysis_references:
raise ValueError("ERROR: Analysis references are not found.")
if not all(isinstance(analysis_reference, SteppedAnalysisReference)
for analysis_reference in analysis_references):
raise TypeError("ERROR: Not all analysis_references are of type SteppedAnalysisReference.")
analysis_references = sorted(analysis_references, key=lambda x: x.step_nr)
for pile_pair in pile_pairs:
disp_x = []
disp_y = []
disp_z = []
time_step = []
for analysis_reference in analysis_references:
if vertical_spring:
# take difference
disp_x.append(pile_pair.vertical_spring.results.get_result_value(
output_item=TDtX, analysis_reference=analysis_reference, software=software,
mesh_element=pile_pair.vertical_spring.mesh.mesh_elements[0], mesh_node=pile_pair.pile_mesh_node) -
pile_pair.vertical_spring.results.get_result_value(
output_item=TDtX, analysis_reference=analysis_reference, software=software,
mesh_element=pile_pair.vertical_spring.mesh.mesh_elements[0], mesh_node=pile_pair.spring_top_node))
disp_y.append(pile_pair.vertical_spring.results.get_result_value(
output_item=TDtY, analysis_reference=analysis_reference, software=software,
mesh_element=pile_pair.vertical_spring.mesh.mesh_elements[0], mesh_node=pile_pair.pile_mesh_node) -
pile_pair.vertical_spring.results.get_result_value(
output_item=TDtY, analysis_reference=analysis_reference, software=software,
mesh_element=pile_pair.vertical_spring.mesh.mesh_elements[0],
mesh_node=pile_pair.spring_top_node))
disp_z.append(pile_pair.vertical_spring.results.get_result_value(
output_item=TDtZ, analysis_reference=analysis_reference, software=software,
mesh_element=pile_pair.vertical_spring.mesh.mesh_elements[0], mesh_node=pile_pair.pile_mesh_node) -
pile_pair.vertical_spring.results.get_result_value(
output_item=TDtZ, analysis_reference=analysis_reference, software=software,
mesh_element=pile_pair.vertical_spring.mesh.mesh_elements[0],
mesh_node=pile_pair.spring_top_node))
if analysis_reference.meta_data is not None:
time_step.append(analysis_reference.meta_data['time'])
else:
time_step.append(None)
else:
raise NotImplementedError("ERROR: 5B output with only displacements ar top node of pile are not "
"implemented anymore. Displacements at top and bottom of pile springs "
"should be present.")
self.displacements_foundation_elements['piles'].append(Pile_displacement(
pile=pile_pair.pile_obj, x=disp_x, y=disp_y, z=disp_z, time_step=time_step))
return self.displacements_foundation_elements['piles']
[docs] def get_viia_object_address(self) -> str:
""" Retrieve the address for the object."""
if 'object_adressen' in list(self.project.project_information.keys()):
return \
f"{self.project.project_information['object_adressen'][0]['straatnaam']} " \
f"{self.project.project_information['object_adressen'][0]['huisnummer']} in " \
f"{self.project.project_information['object_adressen'][0]['plaatsnaam']}"
return 'No address obtained from MYVIIA'
### ===================================================================================================================
### 3. End of script
### ===================================================================================================================