Source code for viiapackage.results.geo_output.geo_output

### ===================================================================================================================
###   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 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"] = get_fstrip_width(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_geo_input( self, analysis: Analysis, tb_file_5a: Optional[Path] = None, tb_file_5b: Optional[Path] = None, abaqus_results: Optional[Path] = None, get_displacements: bool = True): """ Function to obtain the input for creating the GeoOutput objects (NLTH and NLS), which would contain the data for the Geo-output. The input includes the list of foundation elements and the input forces from the relevant tb-files. Input: - analysis (obj): Object reference of analysis of the results in the tb-file(s). - tb_file_5a (Path): Path of the tb-file for the geo-output. Default value None, only required for shallow foundations. - tb_file_5b (Path): Path of the tb-file for the geo-output. Default value None, only required for pile foundations. - abaqus_results (Path): The full path to Abaqus post processed results file. Mutually exclusive to output_5a/output_5b. Default value is None. - get_displacements (bool): Switch to get displacements. Can be False when getting NLS data. Default value True. Output: - The input required for the geo-output classes are returned. """ # Check input if (tb_file_5a or tb_file_5b) and abaqus_results: raise ValueError( "ERROR: Both output from DIANA (tb files) and ABAQUS are specified. Only one of them are allowed.") if not (tb_file_5a or tb_file_5b) and not abaqus_results: raise ValueError("ERROR: Please specify tb-files (DIANA) or ABAQUS output.") # Tabulated file paths handling if tb_file_5a: if self.foundation_type in ['strips', 'mixed']: self.get_forces_from_diana(tb_file=tb_file_5a, data_type='fstrips', analysis=analysis) self.get_fstrip_elements() else: self.project.write_log( "WARNING: Output file for strip foundations is provided but the model foundation type is " f"{self.foundation_type}. Ignoring this output.") if tb_file_5b: if self.foundation_type in ['piles', 'mixed']: self.get_forces_from_diana(tb_file=tb_file_5b, data_type='piles', analysis=analysis) if get_displacements: self.get_pile_displacements_from_diana() self.get_pile_elements() else: self.project.write_log( "WARNING: Output file for strip foundations is provided but the model foundation type is " f"{self.foundation_type}. Ignoring this output.") # ABAQUS output handling if abaqus_results: self.get_forces_from_abaqus(abaqus_results) if get_displacements: self.get_pile_displacements_from_abaqus(abaqus_results) self.get_fstrip_elements() self.get_pile_elements()
[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 ### ===================================================================================================================