N2PCreateFasteners User Manual#

Overview#

The N2PCreateFasteners Module is designed to create the cards that model a set of fasteners joining several meshes of 2D elements. Where N2PGetFasteners detects the fasteners that are already modelled in a FEM, this module does the opposite: given the position, the direction and the diameter of each fastener, it writes the GRID, connector, 1D element, property, material and coordinate system cards needed to model them, and it works out their stiffness with the same formulation used by N2PUpdateFastener.

All the new cards are written into a new include file, so the original files of the model are left untouched.

Example Usage#

1. Importing the module#

import NaxToPy as n2p
from NaxToPy.Modules.static.fasteners import N2PCreateFasteners

2. Load the model#

model = n2p.load_model(r"file path")

3. Define the pieces to be joined#

Each piece is a list of 2D elements. There is no need to list the whole plate: get_elements_attached() returns every element connected to the ones given.

domain = [element for element in model.get_elements() if element.TypeElement in ("CQUAD4", "CTRIA3")]

skin = model.get_elements_attached(model.get_elements([83271476]), domain = domain)
frame = model.get_elements_attached(model.get_elements([63604583, 63604889]), domain = domain)

4. Create and configure N2PCreateFasteners#

creator = N2PCreateFasteners()
creator.Model = model                                  # Assign the model
creator.PieceList = [skin, frame]                      # Pieces to be joined
creator.IncludeName = "new_fasteners.bdf"              # Name of the include file
creator.Positions = [[7532.5, 501.9, 3447.3, 0.0, 0.0, 1.0, 6.35]]

5. Run calculations#

creator.calculate()

6. Write the input data file#

creator.write_bdf("C:\\my_directory\\out")

Setup#

Prerequisites#

  • Python Environment: Ensure you have a compatible Python environment with the following libraries:

    • numpy

    • NaxToPy modules

  • NaxToPy Framework: The module integrates with the NaxToPy library, which must be installed and configured in your environment.

Class Breakdown#

The class N2PCreateFasteners builds every fastener in two stages. First it resolves the geometry: it works out the axis of each fastener, which pieces it actually joins, where it pierces each of them and which nodes of each mesh take part in the connection. Then it writes the cards. The first stage can be run on its own with resolve_geometry(), which touches nothing of the model and lets the user review the result before anything is written.

Module Inputs#

Mandatory Inputs#

Property

Type

Description

Model

N2PModelContent

FEM model the fasteners will be created in

PieceList

list[list[N2PElement]]

One list of 2D elements per part to be joined. At least two

Positions

np.ndarray

Table of fasteners, one row each

IncludeName

str

Name of the include file the new cards will be written in

The Positions table admits two shapes. The diameter is always compulsory, and the direction is optional:

Shape

Columns

Description

(n, 4)

[x, y, z, D]

The direction of each fastener is worked out from the meshes

(n, 7)

[x, y, z, dx, dy, dz, D]

The direction is given by the user

Column

Field

Description

1, 2, 3

x, y, z

Any point of the axis of the fastener, in the basic system

4, 5, 6

dx, dy, dz

Optional. Direction of the axis of the fastener

last

D

Diameter of the fastener

The first three columns are a point of the axis, not of any plate: the point does not have to lie on the mesh, and the module intersects the line it defines with every piece to find out where the fastener actually crosses each of them.

The direction of the fastener#

Columns 4, 5 and 6 are the direction of the axis. They can be left out, in which case the table has four columns instead of seven and the direction is worked out from the mesh: the pieces are checked in the order they were given in PieceList until one of them has an element the point projects inside of, and the normal of that element is taken as the axis of the fastener.

Note

The vector does not need to be a unit vector, as the module normalizes it. What matters is its direction and its sense.

This direction is what defines the X axis of the 1D element that models the fastener, that is, of the CBUSH, the CBAR or the CROD. It is therefore the direction along which K1 of the PBUSH acts as the axial stiffness, while K2 and K3 act as the two shear stiffnesses in the plane of the plates.

Besides that, the direction governs three more things:

  • Which pieces the fastener joins. Only the pieces the line pierces within Tolerance times the diameter are taken.

  • The order of the pieces. The crossings are sorted along the axis, and the 1D elements are chained between consecutive pieces following that order.

  • Which side is the head and which is the nut. When the user gives the direction, it is understood to go from the head to the nut. When it is worked out from the mesh there is no way to tell them apart, so one side is taken as the head and the other as the nut.

Note

The IDs of the new grids decrease along this direction: the first piece the axis meets gets the highest ID and the last one the lowest.

# With direction: the axis of the fastener is (0, 0, 1)
creator.Positions = [[7532.5, 501.9, 3447.3, 0.0, 0.0, 1.0, 6.35],
                     [7532.5, 512.2, 3447.3, 0.0, 0.0, 1.0, 6.35]]

# Without direction: it is worked out from the mesh of the first piece the point falls on
creator.Positions = [[7532.5, 501.9, 3447.3, 6.35],
                     [7532.5, 512.2, 3447.3, 6.35]]

The table can also be read from a csv file with the method load_positions_from_csv(), which fills the Positions property directly. Empty lines and lines starting with # are skipped, so the file can carry comments and a header:

creator.load_positions_from_csv("C:\\my_directory\\rivets.csv", delimiter = ";")

FEM Requirements#

For this module to function properly, the FEM model must be a Nastran or Optistruct Input File (usually called bdf and fem), as the module needs the cards of the model to be able to write new ones next to them.

Only CQUAD4 and CTRIA3 elements are supported in the pieces. Any other element given in PieceList is discarded with a warning.

Warning

This module does not support superelements (parts). All components must be in the superelement "0".

Supported Type Files#

Solver

File Extension

Nastran Input Data

.bdf or .dat

Optistruct Input Data

.fem

Note

The cards this module writes (GRID, CBUSH, CBAR, CROD, CFAST, RBE2, RBE3, CORD2R, PBUSH, PBAR, PROD, PFAST and MAT1) are common to both solvers, so the module never has to branch by solver and the same script works for a .bdf and for a .fem.

Optional Inputs#

Modelling method#

Property

Type

Default

Description

Method

str

"RBE3+CBUSH"

Way in which every fastener of the run is modelled

Method

Description

"RBE3+CBUSH"

A new grid at each crossing, tied to the mesh with an RBE3, and a CBUSH between them

"RBE2+CBUSH"

The same, with an RBE2 instead

"RBE3+CBAR", "RBE2+CBAR"

The 1D element is a CBAR of circular section

"RBE3+CROD", "RBE2+CROD"

The 1D element is a CROD of circular section

"RBE3+CBUSH_HW"

Reproduces the way HyperWorks models a fastener. See Methodology

"RBE3+RBE3+CBUSH"

Two levels of RBE3, spreading the load over four points of the plate

"COINCIDENT-NODE"

No connector: the closest node of each mesh is moved onto the axis and the CBUSH is attached to it

"CFAST"

A CFAST of type ELEM tying the two shell elements directly, with no grid and no connector

Note

All the fasteners of the same calculate() are built with the same method.

Geometry#

Property

Type

Default

Description

Tolerance

float

10.0

Largest distance allowed between the point given and each crossing, in diameters

WeightMethod

str

"SHAPE_FUNCTIONS"

How the nodes a connector ties are chosen and weighted

DiameterFactor

float

1.0

Radius of the influence area, in diameters. Only used with "DISTANCE"

ElementTolerance

float

0.01

Numerical tolerance of the inside-the-element test

MaxNodeMovementFactor

float

0.25

Only for "COINCIDENT-NODE", largest fraction of the size of an element that one of its nodes may be moved

WeightMethod

Description

"SHAPE_FUNCTIONS"

Only the nodes of the pierced element take part, weighted with the shape functions of that element at the crossing. They add up to one and are how a load applied there is really shared out

"DISTANCE"

The nodes inside the influence radius are taken as well, weighted by how far they are from the crossing

Stiffness#

Property

Type

Default

Description

StiffnessMethod

str

"HUTH"

Formulation used for the shear stiffness

ConnectionType

str

"bolt"

May be "bolt" or "rivet"

ShearType

str

"AUTO"

May be "AUTO", "simple" or "double"

FastenerModulus

float

120000.0

Elastic modulus of the fasteners

FastenerPoisson

float

0.33

Poisson ratio of the fasteners

HeadHeight

float

0.0

Height of the head

NutHeight

float

0.0

Height of the nut

K4

float

100.0

Torsional stiffness of the PBUSH around the axis

K5

float

1.0e8

Bending stiffness of the PBUSH around the Y axis

K6

float

1.0e8

Bending stiffness of the PBUSH around the Z axis

Note

The available stiffness methods are: "HUTH", "BOEING", "TATE_ROSENFELD", "GRUMMAN", "SWIFT" and "NELSON". They are the same ones N2PUpdateFastener uses, and their formulation is described in its manual.

Note

With "AUTO", a fastener that joins two pieces is taken as single shear and one that joins three or more is taken as double shear.

K1, K2 and K3 of the PBUSH are computed by the module. K4, K5 and K6 are fixed values given by the user, as there is no accepted formulation for them.

Numbering of the new cards#

Property

Type

Default

Description

OffsetIDsNodes

int

-1

First ID of the new grids

OffsetIDsElements

int

-1

First ID of the new elements

OffsetIDsProperties

int

-1

First ID of the new properties and materials

OffsetIDsCoords

int

-1

First ID of the new coordinate systems

A value of -1 starts the numbering right after the highest ID already present in the model. A positive value starts it there, skipping forward if that ID happens to be taken.

Note

Nastran and Optistruct only accept IDs of up to eight digits. When the model already reaches that limit, the module fills the gaps that are free below it instead of failing, and reports it with W6011 or W6012.

Output file#

Property

Type

Default

Description

AllowExistingInclude

bool

False

If True, the new cards are appended to the include file when it already belongs to the model

CreateCoordinateSystemPerFastener

bool

False

If True, every fastener gets its own CORD2R and all its CBUSH are oriented by CID

Note

With CreateCoordinateSystemPerFastener set to False, a CORD2R is only written for the fasteners that need one, that is, the ones whose CBUSH has no length because two pieces are in contact. In that case the solver requires a coordinate system, as no direction can be worked out from two coincident grids. The rest of the CBUSH are oriented by vector, so a model with thousands of fasteners does not end up with thousands of coordinate systems.

Output Description#

The module creates the cards in the model in memory and, when write_bdf() is called, writes them to disk inside the include file given in IncludeName, linked to the launcher file of the model through an INCLUDE statement. If a folder is given, the whole model is rebuilt there keeping its original file structure; if no folder is given, the model is updated in place and only the files holding modified cards are rewritten.

Property

Type

Description

LayoutList

list[N2PFastenerLayout]

Geometry of the fasteners that could be resolved

DiscardedList

list[tuple[int, str]]

Row and reason of every fastener that could not be built

Each N2PFastenerLayout gives access to the axis of the fastener, its diameter and the list of its crossings, and each crossing to the pierced element, the crossing point, the nodes taken and their weights:

for layout in creator.LayoutList:
    print(layout.Index, layout.NumberOfPieces, layout.Direction)
    for pierce in layout.Pierces:
        print(pierce.PieceIndex, pierce.Element.ID, pierce.Point, pierce.ShapeFunctions)

Warning

A fastener that cannot be built is reported in DiscardedList and skipped, but the rest of the run carries on. It is worth checking that this list is empty, or that the fasteners in it are the expected ones, before using the model.

Common Errors#

  • E6004: the Positions property does not have four or seven columns.

  • E6006: some fastener has a diameter that is not greater than zero.

  • E6017: some piece has no supported elements, so no fastener can be created.

  • E6018: some compulsory property has not been filled.

  • E6030: the property of a pierced element could not be found in the model.

  • E6035: the property of a pierced element is not a PSHELL or a PCOMP.

  • E6040: the include file already belongs to the model and AllowExistingInclude is False.

  • E100: the low level libraries rejected something while writing a card. It is reported by the core, not by the module.

  • E6051: a card has ended up invalid and will be written as a block of comments instead of as a card.

  • E6025: there is no free ID left below the eight digit limit of the solver.

Common Warnings#

  • W6001: some elements of a piece were discarded because only CQUAD4 and CTRIA3 are supported.

  • W6003: a fastener has been discarded, with the reason why.

  • W6004: no fastener could be resolved at all.

  • W6010: the offset requested for a numbering space is already in use, so the numbering starts later.

  • W6011, W6012: the model reaches the eight digit limit of the solver, so the new IDs are taken from the free gaps.

  • W6020: the include file already belongs to the model, so the new cards are appended to it.

  • W6021: a fastener could not be written, with the reason why.

Methodology #

For every row of the Positions table the module follows these steps:

  1. Axis of the fastener. If the user gave a direction, that is the axis. If not, the pieces are checked in the order they were given until one of them has an element the point projects inside of, no farther than Tolerance times the diameter, and the normal of that element is taken as the axis.

  2. Pieces joined. The line defined by the point and that axis is intersected with every piece, discarding the crossings farther than Tolerance times the diameter. A fastener is only created when the line pierces two or more pieces, which is what allows the user to give three pieces where some fasteners join the three of them and others only join two. When a piece is folded and the line pierces it twice, the crossing closest to the point is the one taken.

  3. Connection to each mesh. The crossings are sorted along the axis and, at each of them, a new grid is created and tied to the mesh with the connector the method asks for.

  4. 1D elements. The pieces are joined by a chain of one 1D element per pair of consecutive pieces, each with its own property.

  5. Stiffness. The axial stiffness comes from the effective length of the fastener and the shear stiffness from the formulation chosen in StiffnessMethod, using the thickness and the elastic moduli of the two plates of each segment oriented in the axes of the fastener.

The “RBE3+CBUSH_HW” method#

When this method is selected the module reproduces what HyperWorks writes when it creates a fastener, following what its manuals describe.

For each piece the fastener goes through, two RBE3 are written sharing the same dependent grid instead of one:

  • The first takes the translations: REFC = 123, and the independent grids with components 123.

  • The second takes the rotations: REFC = 456, and the independent grids with components 456.

Both hang from the same nodes with the same weights, and each of them closes with a last weight group of weight 1.0 that ties the dependent grid to itself through the components the other card takes care of, that is, 456 in the first and 123 in the second.

Note

Those last groups must use the complementary components. An RBE3 whose reference grid appears among the independent ones with overlapping degrees of freedom constrains the same degree of freedom twice and is rejected as invalid.

The independent grids are only the nodes of the pierced element, and their weights are the shape functions of that element evaluated at the crossing, which is the default WeightMethod of the module.

The “RBE3+RBE3+CBUSH” method#

This method spreads the load over four points of the plate instead of one. For each piece the fastener goes through:

  • Four new grids are placed on the circumference of the fastener, at a radius of half its diameter and every 90 degrees, and projected onto the surface of the mesh so that they lie on the plate.

  • A first RBE3 hangs the grid of the fastener from those four, all of them with weight 1.0.

  • One RBE3 per new grid then ties it to the element of the mesh it landed on, with the usual weights.

Note

Each of the four grids may land on a different element, which is the point of the method. If any of them falls outside the mesh, because the fastener is too close to the edge of the plate, the whole fastener is discarded.

Limitations#

  • Only CQUAD4 and CTRIA3 elements are supported in the pieces.

  • Only PSHELL and PCOMP properties are supported in the plates. Within a PSHELL, the material must be a MAT1, a MAT8 or one whose reduced stiffness matrix the model provides.

  • Superelements (parts) are not supported. All components must be in the superelement "0".

  • All the fasteners of the same calculate() are built with the same method, with the same diameter-independent parameters and with the same fastener material.

  • The "COINCIDENT-NODE" method moves nodes that already exist in the model, which distorts the elements around them. The movement is limited by MaxNodeMovementFactor, and a node that another fastener has already moved is not moved again, but the resulting mesh should be reviewed.

  • The "CFAST" method needs the two shell elements it ties, so it cannot be used when the fastener does not pierce an element of each piece.

  • A CBAR or a CROD between two pieces that are in contact would have no length, so those fasteners are discarded. A method based on CBUSH has to be used instead.

Extra Examples#

Reading the fasteners from a csv file, modelling them the way HyperWorks does and writing the result in a separate folder:

import NaxToPy as n2p
from NaxToPy.Modules.static.fasteners import N2PCreateFasteners

model = n2p.load_model("C:\\my_directory\\my_model.bdf")

domain = [element for element in model.get_elements() if element.TypeElement in ("CQUAD4", "CTRIA3")]
skin = model.get_elements_attached(model.get_elements([83271476]), domain = domain)
frame = model.get_elements_attached(model.get_elements([63604583]), domain = domain)

creator = N2PCreateFasteners()
creator.Model = model
creator.PieceList = [skin, frame]
creator.IncludeName = "new_fasteners.bdf"
creator.load_positions_from_csv("C:\\my_directory\\rivets.csv", delimiter = ";")

creator.Method = "RBE3+CBUSH_HW"
creator.StiffnessMethod = "HUTH"
creator.ConnectionType = "bolt"
creator.FastenerModulus = 110000.0

creator.calculate()
creator.write_bdf("C:\\my_directory\\out")

for row, reason in creator.DiscardedList:
    print(f"Fastener {row} was discarded because {reason}")

Reviewing the geometry before writing anything into the model:

creator = N2PCreateFasteners()
creator.Model = model
creator.PieceList = [skin, frame, clip]
creator.IncludeName = "new_fasteners.bdf"
creator.Positions = positions

# Nothing is written yet: only the geometry is worked out
creator.resolve_geometry()

for layout in creator.LayoutList:
    pieces = [pierce.PieceIndex for pierce in layout.Pierces]
    print(f"Fastener {layout.Index} joins the pieces {pieces}")

# Once the geometry has been checked, the cards are created
creator.calculate()
creator.write_bdf("C:\\my_directory\\out")

References#

  • [Ref-1]: Altair Engineering, «HyperWorks User Guide: Connectors», Altair HyperWorks documentation.

  • [Ref-2]: H. Huth, «Influence of Fastener Flexibility on Load Transfer and Fatigue Life Predictions for Multirow Bolted and Riveted Joints», NASA Foreign Exchange Program, 1984.

  • [Ref-3]: MSC Software, «MSC Nastran Quick Reference Guide», sections RBE3, CBUSH, PBUSH and CFAST.


idaero-logo
© 2026 Idaero Solutions S.L.

All rights reserved. This document is licensed under the terms of the LICENSE of the NaxToPy package.