Skip to main content

Postprocessing of simplified bolted connections with the help of PyAnsys

| 09.18.2023

This article is brought to you on behalf of Serhii Zhuravel.

Introduction

Due to increasing demand for simulations, precise results and reduced post-processing, it is a must to automate repetitive routines, such as calculation of bolted connections, wherever possible. In particular, large complex models with numerous bolted joints.

This article demonstrates graphical user interface (GUI) application possibilities in calculating pre-tensioned bolted connections using PyMAPDL. The application uses widely recognised standards for bolted connections such as EN 1993-1-8 and VDI 2230. In addition a simplified code snippet is shown below that extracts reaction forces from a bolted connection and saves the results to a Microsoft Excel file. This file can be used for further analytical calculations in Python and/or in Excel.

Context

The focus of this piece is on demonstrating post-processing of a double bolted lap joint. It demonstrates the capabilities of PyMAPDL to automate, access, post-process and visualize the resulting data.

Required software and Python libraries:

  • PyCharm 2023.2 (Community Edition)
  • Ansys version 2023R1
  • Python version 3.10
  • Python libraries
    • ansys-mapdl-core library ver. 0.65.1
    • numpy library ver. 1.25.2
    • Python Standard Library - csv

GUI application

Before doing any post-processing, the finite element model has to be created. In the example below, a double bolted lap joint is analyzed.

The joint is made of 5 bolted connections, where 2 slip surfaces are present.

The multipoint constraint contact (MPC) formulation is used for each bolted connection.

The boundary conditions are represented as an axial force with 10 kN from one side and fixed supports on the other.

Stress results for the calculated model look like this.

The GUI uses the built-in TKinter library and is shown below.

Upon clicking "Run", Python runs a PyMAPDL script which extracts all the necessary information from the Ansys model and plots the data using PyVista.

The GUI with the slipping resistance factor (SRF) results in PyVista is shown below.

A screenshot of the excel result file with all bolt names and reaction forces in .csv format is below.

As can be seen the application takes the model with created named selections for a bolted group and calculates slipping resistance factor (SRF) for each bolt. The local coordinate system is used for each bolt regardless of its orientation. The application gives insight into the results for bolts together with a mesh model. It reduces post-processing time and helps visualize the results that are not accessible in Ansys normally.

Snippet to extract reaction forces for a bolted connection

In order to use the code snippet below, a named selection for each bolted connection has to be created:

Note: In total, it is 10 named selections for 5 bolts because the double lap joint has 2 slipping surfaces.

The complete script looks as follows.

    import pip
    import csv
    import traceback

    # Load all the necessary Python libraries, install them if they are missing
    try:
        from ansys.mapdl.core import launch_mapdl, inline_functions
        import numpy as np
    except ImportError:
        pip.main(['install', 'ansys.mapdl.core'])
        pip.main(['install', 'numpy'])
        from ansys.mapdl.core import launch_mapdl, inline_functions
        import numpy as np

    def extract_reactions(rst_path):
        # Create a dictionary to store results
        result_dict = {}

        # Enter POST1 and load the .RST file with first timestep
        mapdl.post1()
        mapdl.file(fname=rst_path)
        mapdl.set(lstep='FIRST')

        # Get a list of all named selections that start with 'BOLT' name
        named_selection_list = [mapdl.get(entity='COMP', item1='NAME', entnum=item) for item in
                                range(int(mapdl.get(entity='COMP', item1='NCOMP'))) if
                                str(mapdl.get(entity='COMP', item1='NAME', entnum=item)).startswith('BOLT_')]

        # Iterate throughout the named selection list and extract reaction forces
        for named_selection in named_selection_list:
            # Select a named selection
            mapdl.cmsel(type_='S', name=named_selection)
            # Initiate FSUM command
            mapdl.fsum()

            # Extract reaction forces in the global coordinate system
            f_x = round(mapdl.get(entity='FSUM', item1='ITEM', it1num='FX'), 2)
            f_y = round(mapdl.get(entity='FSUM', item1='ITEM', it1num='FY'), 2)
            f_z = round(mapdl.get(entity='FSUM', item1='ITEM', it1num='FZ'), 2)

            # Save results to a dictionary
            result_dict[named_selection] = [f_x, f_y, f_z]

        # Exit MAPDL instance and return the dictionary with reaction forces
        mapdl.exit()
        return result_dict

    def save_to_excel(results, dir_path):
        # Create a new file and write data to it
        with open(dir_path + '/' + 'BoltReactionForces.csv', 'w', newline='') as file:

            # Create field names and write them
            fieldnames = ['Bolt_name', 'Reaction_X', 'Reaction_Y', 'Reaction_Z']
            writer = csv.DictWriter(file, fieldnames=fieldnames)
            writer.writeheader()

            # Iterate over elements and write results
            for key, value in results.items():
                name = key
                fx = value[0]
                fy = value[1]
                fz = value[2]

                writer.writerow(
                    {'Bolt_name': name, 'Reaction_X': fx, 'Reaction_Y': fy, 'Reaction_Z': fz})

    if __name__ == "__main__":
        # Input parameters
        directory_path = r'C:\ANSYS_Project_Folder\dp0\SYS-1\MECH'
        rst_file_path = directory_path + r'\file.rst'
        ansys_version = 23.1
        number_of_cpu = 2

        # Launch MAPDL instance
        mapdl = launch_mapdl(run_location=directory_path, nproc=number_of_cpu, version=ansys_version, override=True)

        try:
            reactions = extract_reactions(rst_file_path)
            save_to_excel(reactions, directory_path)
        except Exception:
            mapdl.clear()
            mapdl.exit()
            traceback.print_exc()

Summary

PyAnsys enables automation of routine tasks utilising the immense capabilities of the Python language, which significantly reduces postprocessing time and allows Python-based libraries to be coupled to scripts. It sets a new level of finite element calculation in Ansys allowing for more in-depth automation at both the pre- and post-processing stages.