N2PGetLoadFasteners User Manual#
Overview#
N2PGetLoadFasteners is a NaxToPy module which provides information about the loads that fasteners in a model experience. It must be used after the N2PGetFasteners class, which is the one that creates the joints used in this class.
Example usage#
1. Importing the module#
import NaxToPy as NP
from NaxToPy.Modules.Fasteners.N2PGetFasteners import N2PGetFasteners
from NaxToPy.Modules.Fasteners.N2PGetLoadFasteners import N2PGetLoadFasteners
2. Run N2PGetFasteners#
model = NP.load_model(r"file_path")
element_list = [(57510018, '0'), (57510014, '0')]
n2pelem = model.get_elements(element_list)
fasteners = N2PGetFasteners()
fasteners.Model = model
fasteners.ElementList = n2pelem
fasteners.calculate()
3. Create and configure N2PGetLoadFasteners#
loads = N2PGetLoadFasteners()
loads.GetFasteners = fasteners
loads.ResultsFiles = [r"results_files_1", r"results_files_2"]
loads.LoadCases = loads.Model.get_load_case([68220, 68221])
Warning
Introducing a list of load cases is not compulsory. If this attribute is not selected, all load cases in the model will be analyzed.
4. Run calculations#
loads.calculate()
5. Access the results#
fasteners.PlateList[0].BearingForce # Bearing force of the first plate
fasteners.PlateList[0].NxBypass # Nx bypass loads of the first plate
fasteners.BoltList[0].AxialForce # Axial force of the first bolt
6. Export results#
loads.AnalysisName = "my first analysis" # Optional name of the file (without extension)
loads.ExportLocation = r"route" # The route must be the direction to a folder, not to a file
loads.export_results()
Warning
This method will overwrite any file with the same name in the folder.
For advanced usage, or extra information about the outputs of the class, see the sections below.
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 N2PGetLoadFasteners provides information about the loads that fasteners in a model experience. There are three distinct elements (N2PJoints
, N2PBolts
and N2PPlates
) that will be used in the analyses, but its definition and properties have already been defined in the N2PGetFasteners User Manual, so this information will not be repeated here.
Mandatory Inputs#
Property |
Type |
Description |
---|---|---|
|
|
Results file(s) or folder with the results files |
|
|
.h5 file with the obtained bypass results |
|
|
N2PGetFasteners object with the geometrical information about a model |
|
|
FEM model to be analysed |
|
|
List of N2PJoints to be analysed |
Take note that the user should either set the GetFasteners
attribute, or the Model
and JointsList
attribute, but not both at the same time. It is simpler, and thus recommended, to set only the GetFasteners
attribute. Furthermore, to perform the bypass and bearing calculations, the BypassResults
attribute should not be filled in, but to load the previously calculated bearnig and bypass results, it should be filled in, but the ResultsFiles
attribute should not. This last case (importing previously obtained results) will be explained at the very end, as most of the document will be focused on actually analysing fasteners.
FEM Requirements#
For this module to function properly, the FEM model must include forces in the output requests. Additionally, the model should accurately represent all elements and load cases used in the analysis, including fasteners, elements pierced by fasteners, and elements surrounding them. This is module is avaible for Nastran, Optistruct and Abaqus, and only “CFAST” and “CBUSH” elements are supported.
Supported Type Files#
Solver |
File Extension |
---|---|
Nastran |
.op2 |
Nastran |
.xdb |
Nastran |
.h5 |
Optistruct |
.op2 |
Optistruct |
.h3d |
Optional Inputs#
Since N2PGetLoadFasteners
has many optional inputs, they are split between two classes. Firstly, optional inputs that are directly accessed from N2PGetLoadFasteners
will be explained:
LoadCases
(list[N2PLoadCase]
): list of load cases that will be analysed. By default, all of them will be analysed. Take note that the load cases must correspond to a model that, when creating the N2PGetFasteners class, has not been yet created (this will be explained in detail later on), so the way of selecting these load cases is not very intuitive. See the previous example.TypeAnalysis
(str
): type of analysis that will be executed. By default, the “PAG” analysis will be done, but the user could also select the “ALTAIR” analysis.ExportLocation
(str
): location where results are to be exported. By default, nothing will be exported. Take note that this path should be the folder path, not the (non-existing) file path.TypeExport
(str
): way in which the results will be exported. By default, the results will be exported in a .txt file. The following exports are supported:“TXT”: two .txt files will be created, one for composite plates and one for metallic plates. The files are similar to the files created by PAG.
“HDF5”: one .h5 file will be created with most available results.
“REDUCED_HDF5”: one .h5 file will be created with a few results. It is useful if one wants to load these results again.
“CSV”: one .csv file will be created with most available results.
“ALTAIR”: one .csv file will be created with similar results to the file created by Altair.
AnalysisName
(str
): name of the file that will be created when results are exported. By default, its name will be ‘JointAnalysis’.
To export results, introduce the folder path in the ExportLocation
attribute. To select the file’s name, modify the AnalysisName
attribute before executing the calculate()
method.
loads.ExportLocation = r"route"
loads.AnalysisName = "MyAnalysis" # optional
To change the way in which the analysis is exported, simply change the TypeExport
attribute.
loads.TypeExport = "HDF5" # for HDF5 export
loads.TypeExport = "REDUCED_HDF5" # for reduced HDF5 export
loads.TypeExport = "CSV" # for CSV export
loads.TypeExport = "ALTAIR" # for Altair export
To change the type of analysis from “PAG” to “ALTAIR”, modify the TypeAnalysis
attribute.
loads.TypeAnalysis = "ALTAIR"
The following inputs are inside the OptionalAttributes
attribute in N2PGetLoadFasteners
. The user can modify any of these, but they can also be set to their default values and the analysis will be correct:
LoadSecondModel
(bool
): boolean that shows if a new model will be generated or not when obtaining results, in order to load results in less elements. By default, it is set toFalse
. The user may want to set this toTrue
if the time spent loading results is excessive.CompressionEqualsZero
(bool
): boolean that shows whether or not the pullthrough force is set to zero when a fastener is compressed. By default, it is set toTrue
. The user may want to set this toFalse
if they want to see negative pullthrough forces.PullThroughAsIs
(bool
): boolean that shows if the pullthrough force is set to the value found in the results files or if it is calculated. By default, it is set toTrue
. The user may want to set this toFalse
if they want to calculate the pullthrough force instead of obtaining it directly from the results files.ShearAsIs
(bool
): boolean that shows if the bolts’ shear force is set to the value found in the results files or if it is calculated. By default, it is set toTrue
. The user may want to set this toFalse
if they want to calculate the shear force instead of obtaining it directly from the files.AdjacencyLevel
(int
): number of layers of adjacent elements that will be included in the new, reduced model (if any). By default, it is -1, meaning that a new model will not be created. In order to exemplify how this parameter works, assume that it is set to 2. In this case, the new model will include all elements that make up the joints (both bolts and plates), as well as all adjacent elements to those, and the adjacent elements to the adjacent elements. By including a high adjacency level, more elements will be included in the model and the analysis will be naturally slower. However, by including a low adjacency level, it is possible that, when creating the bypass box, some points will lie in elements that have not been loaded in. It has been found by testing that 4 is usually a good enough number for most models, but the user may want to modify it, especially when the model’s elements are particularly big (a lower adjacency level may be adequate) or particularly small (a higher adjacency level may be needed). If the W520 warning shows up many times during the obtention of the bypass box, the user may want to increase the adjacency level, as it means that there are points belonging to the bypass box that are placed outside of the loaded model.CornerData
(bool
): boolean that shows if the results files have data in the corners or not. By default, it is set toFalse
. If the results files do have corner data, it is recommended (but it is not compulsory) to set this attribute toTrue
, as results will be more precise (even though the analysis may be slightly slower). If this value is set toFalse
and there is corner data, a good analysis will be executed regardless. However, if this value is set toTrue
and there is no corner data in the results files, the program may break. The user may want to set this toTrue
if they want to obtain more precise results and there is data on the corners.DefaultDiameter
(float
): diameter that will be assigned by default to joints with no previously assigned diameter. The user may want to change this value if there are joints with no diameter in their cards, such as CBUSH elements.ExportPrecision
(int
): precission that the exported results (in HDF5 files) will have. By default, it is set to 4 (single precission), but it could also be set to 8 (double precission). The user may want to modify this value to 8 if they want to achieve greater precision when exporting results to a .h5 file.LoadCaseNumber
(int
): number of load cases that are being analysed at the same time. By default, it is set to -1, meaning that all load cases will be analyzed. The user may want to modify this value if there are many load cases, but it heavily depends on how fast the computer is.MaterialFactorMetal
(float
): material factor used for metallic materials in the calculation of the dimension of the bypass box. By default, it is set to 4.0. The user should not modify this value.MaterialFactorComposite
(float
): material factor used for composite materials in the calculation of the dimension of the bypass box. By default, it is set to 4.0. The user may want to modify this value to 4.5 for the Altair analysis.AreaFactor
(float
): area factor used in the calculation of the dimension of the bypass box. By default, it is set to 2.5. If the user does not modify these three values, the dimension of the bypass box will be 4*Diameter, which is the formula used by PAG. The user should not modify this value.MaxIterations
(int
): maximum number of iterations allowed when obtaining the bypass box. By default, it is set to 200. The user may want to modify this value if the bypass box is not obtained for certain joints.ProjectionTolerance
(float
): numerical tolerance used in the projection of points onto the bypass box. By default, it is set to 0.01. The user should not modify this value unless certain errors show up.
To modify the rest of the parameters, modify them at will.
loads.OptionalAttributes.AdjacencyLevel = 3
loads.OptionalAttributes.CompressionEqualsZero = False
loads.OptionalAttributes.PullThroughAsIs = False
loads.OptionalAttributes.ShearAsIs = False
loads.OptionalAttributes.CornerData = True
loads.OptionalAttributes.LoadCaseNumber = 200
loads.OptionalAttributes.ExportPrecission = 8 # This only makes sense if the results are exported to an HDF5 file
loads.OptionalAttributes.MaterialFactorComposite = 4.5
Order of the inputs#
The order in which the inputs are assigned is relevant, because (as will be explained later on), before selecting the calculate()
method, a new, reduced model will be created. This model will be created when the ResultsFiles
attribute has been filled in and, either the GetFasteners
, or both the JointsList
and Model
attributes, have been introduced. Therefore, the order in which some attributes are assigned must take this into acccount: the AdjacencyLevel
attribute, which must be introduced before the ResultsFiles
one, and the LoadCases
attribute, which must be introduced after the ResultsFiles
one.
If the AdjacencyLevel
attribute is assigned after the reduced model has been created, no error will appear, but the model will be generated twice, thus slowing down the process. If the LoadCases
attributes is assigned before the new model has been created, an error may appear.
Expected Outputs#
Even though all relevant outputs will be assigned to attributes of either plates or bolts, the N2PGetLoadFasteners
class has an extra property that has not been mentioned: the Results
property, which is a dictionary with results in all elements of the model for all selected load cases. The user could access this property, but there is no need.
Possible errors and warnings#
E524: all files loaded in the
ResultsFiles
attribute do not exist.W522: the user is setting the
GetFasteners
attribute when theModel
orJointsList
attribute has been set before, so a new model will be created.W523: the user is setting the
Model
attribute when theGetFasteners
attribute has been set before, so a new model may be created.W524: the user is setting the
JointsList
attribute when theGetFasteners
attribute has been set before, so a new model may be created.W525: the type of analysis or export is not suppported, so it is not updated.
W526: a parameter defined in the
BypassParameters
dictionary attribute is not of the correct type.W527: a non-compulsory attribute is of the wrong instance, so it is not updated (for example, the
AdjacencyLevel
attribute is not set to an integer).W528: the type of precission is not supported.
W534: a list attribute has no valid objects inside (for example, the
LoadCases
attribute is filled with objects that are notN2PLoadCase
objects).W544: a file loaded in the
ResultsFiles
attribute does not exist, so it is not loaded.
New model creation#
Before executing the calculate()
method, a new model will be created, as has been commented before. This new model will be created when one of the following happens:
The
GetFasteners
andResultsFiles
attributes have been filled in.The
Model
,JointsList
andResultsFiles
attributes have been filled in.The
AdjacencyLevel
attribute has been updated and a new model has already been created. Take note that a new model may be created twice if theAdjacencyLevel
property is updated after a new model has been created, which is the reason it was recommended in the previous section that this attribute be filled in before theResultsFiles
one.
In any case, when any of these conditions is met, the load_reduced_model()
method is executed. Firstly, a new model is created with the get_adjacency()
method if the optional attribute AdjacencyLevel
is modified, which follows the following steps:
All N2PElements that make up the joints (both bolts and plates) are selected.
The
get_elements_adjacent()
method is called as many times as theAdjacencyLevel
attribute says. If this attribute is set to 2, the function will fire twice, and all elements adjacent to the ones in the joints are obtained, as well as those adjacent to adjacent elements.A new model is loaded with only these elements, which will hopefully include less elements than the original model.
Results files are loaded onto this new model.
After a new model has been created, certain attributes must be updated. For example, the ElementList
attribute of existing plates will be filled with N2PElement objects corresponding to the old model, not to the new one. The updated attributes are: ElementList
attribute for N2PBolts and the ElementList
, CentralElement
and BoltElementList
attribute for N2PPlates.
Obtention of the bypass box#
In order to calculate the bypass loads, which will be done later, a box must be created, which is onde using the get_bypass_box()
method. The following steps are followed:
Firstly, joints with no diameter are assigned the diameter extracted from their fasteners’ cards and, if there is no diameter in the cards, the diameter assigned is the one defined by the
DefaultDiameter
attribute.Next, joints with no diameter (in case that, for example,
DefaultDiameter
has not been filled in) or with negative diameter (for example, because the user incorrectly assigned the joint’s diameter) are removed from the list, as they cannot be analysed. Now, the box is calculated for each plate using a method also calledget_bypass_box()
.The box’s dimension \( a \) is the following:
where \( AF \) is the area factor, \( MF \) is the material factor, and \( \phi \) is the joint’s diameter. Recall that the default values for the area factor and material factor were 2.5 and 4.0, respectively. Using these parameters, the box’s dimension is
which is the formula recommended by PAG.
Knowing its dimension, the box is defined using a specific orientation, which is defined by the material reference frame of the first element of the plate.
Next, the theoretical bypass points are calculated. The points are numbered from 1 through 8, with the first point being located in the south-western side of the box, in the coordinates \( (-a/2, -a/2) \) in the box system, and then they are ordered in a counter-clockwise fashion, as shown in the following image.

Note that the south side (side 1) is made up of points 1 through 3, the east side (side 2) is made up of points 3 to 5, the north side (side 3) is made up of points 5 to 7, and the west side (side 4) is made up of points 7, 8, and 1.
Take note that these points are the theoretical points, and may not be the true, final points used in the calculations, as will be shown now.
After the points have been calculated, the elements in which these points lie in must be determined. This process is not at all trivial. The first step is selecting adjacent elements to the first element of the plate and checking if any point lie within these elements. If some points remain with no element, more elements are located further away until either all points have an associated element, or the distance between the fastener (the center of the box) and the elements that are being searched is greater than the box’s semidiagonal.
Of course, if all elements have been found, the box is perfectly defined and the program stops. However, if the distance from the fastener to the elements is too great, this means that no points will be located in further elements. If this is the case, the point is orthogonally projected onto the closest element to the mathematical point. This could happen if a point is too close to an edge, or if the selected adjacency level is too low and not enough elements have been loaded. In the following image, several of the shown points would be orthogonally projected onto the edges, as that points would not be part of any element in the model.

The algorithm used to determine whether or not a point lie within an element or not is also not trivial. For CQUAD elements, they are split in two triangles and the barycentric coordinates of the box point within these triangles are calculated. Remember that the barycentric coordinates \( \lambda_1 \), \( \lambda_2 \) and \( \lambda_3 \) of a point \( P \) within a triangle defined by its vertices \( A \), \( B \) and \( C \) can be calculated as:
where \( \Delta_{XYZ} \) is the area formed by the \( X \), \( Y \) and \( Z \) points, as can be found by the cross product:
It can be shown that, if the point \( P \) lies within the \( ABC \) triangle, then all barycentric coordinates must add up to one:
as can be shown through elemental geometry.
Therefore, to determine if a point lies within a triangle, its barycentric coordinates are calculated and, if they add up to one, the point lies within that element.
It is also possible that a mathematical point does not lie within any element because, due to the geometry of the model, it is slightly “over” or “under” any element, which can occur, for example, when there is a certain curvature in the model. In this case, points are orthogonally projected over the plane of the elements and it determined whether or not the projected point lies within that element. This is considered acceptable.
After the bypass box has been found, the following attributes are filled in for
N2PPlate
objects:BoxDimension
: float representing the dimension of the box \( a \).BoxSystem
: list of nine floats representing the material reference frame.BoxPoints
: dictionary in the form {1: [X1, Y1, Z1], …, 8: [X8, Y8, Z8]} representing the coordinates of all eight points in the box. Note that these points are not necessarily the mathematical points calculated before. If any point is projected (either because the point is not on the plane of its corresponding element or because it has to be projected as the fastener lies close to an edge), the new coordinates are included in this attribute.BoxElements
: dictionary in the form {1: E1, … 8: E8} representing the elements in which all eight points of the box lie.
Possible errors and warnings#
E504: no load cases have been imported.
E521: no model has been imported.
E523: no joints have been imported.
W512: a plate has no assigned elements, so it is ignored.
W520: a plate does not have enough adjacent elements, so their bypass box points are projected.
W521: a plate does not have an assigned intersection point, so it is ignored.
W530: a plate does not have an assigned normal direction, so it is ignored.
W535: certain joints have an incorrect (negative, zero or non-existent) diameter, so they are removed from the list of joints.
W540: the maximum number of iterations has been reached for a plate.
W542: it is being checked if a point lies within an element that is not supported.
Results obtention#
After the new model has been created and the elements have been updated, results are extracted from the results files, which is done by using the get_results()
method. The following steps are followed:
Results only have to be extracted in the following elements:
Plates and bolts.
Elements where points of the bypass box lie in, and adjacent elements to them. Results in the bolt’s elements (typically CFASTs) are obtained in the bolt’s element system, while results in all other elements should be extracted in the associated plate’s material reference frame to minimize transformations.
However, when an element’s results are used in the calculation of the bypass box of two different plates (because their boxes are nearby), results can only be asked in one reference frame, and that is the material system that has been first assigned, so no rotations have to be made for one of the plates. For the rest, that common element, as well as its associated material system, is saved in the _elements_to_rotate attribute of the plate.
After determining in what elements results should be obtained in and in which reference frames, a new model will be loaded with only those elements if the
LoadSecondModel
attribute is set toTrue
, and certain attributes of plates and bolts will be updated.Regardless of whether or not a new model has been created, results are extracted using the similarly named
get_results()
method. The following steps are followed:Results are extracted from the results files. This is done differently depending on the solver. The NaxToPy function used in the results extraction is
get_result_by_LCs_Incr()
.If
CornerData
is set toTrue
, results are also extracted in the corners. For CTRIA3 elements, only results in the centroid are supported, so in these elements the corner data will be replaced with results in the centroid.If some of the load cases are broken, that is, there are no results for that load case, that load cases are removed from the list of load cases and a warning shows up.
For non broken load cases (which should be all of the load cases), a 3D array will be created. The first dimension will be the load case, the second dimension, the type of result obtained, and the third one, the elements in which results are obtained. The obtained results are 1D forces (X, Y and Z), force fluxes (XX, YY and XY) and moment fluxes (XX, YY and XY). If there is corner data, another array will be created, whose results will include only force and moment fluxes in the corners.
Possible errors and warnings#
E521, E522, E523: either the model, list of joints, or results files, have not been loaded.
E518: the solver is not supported.
E519: all load cases are broken.
W511:
CornerData
is set toFalse
.W536: the bypass boxes have not been calculated.
W545: a load case is broken and removed from the list.
Forces obtention#
After results are extracted, the forces are obtained via the get_forces
method, which is slightly different for the “PAG” and “ALTAIR” analyses.
Firstly, the fastener forces are extracted. This force, \( \vec{F}_{fastener}^E \), is expressed in the fastener element reference frame (note the “E” superscript, for element reference frame).
The fastener forces are rotated according to the following expression:
\[ \vec{F}_{fastener}^M = \bar{\bar{R}}_M \cdot \bar{\bar{R}}_S^T \cdot \vec{F}_{fastener}^E \cdot F \]where the “M” superscript denotes that the forces vector has been obtained in the material reference frame of the first plate. The three rotation matrices are as follows:
\( \bar{\bar{R}}_M \): matrix whose rows are the vectors that define the plate’s material reference frame.
\( \bar{\bar{R}}_S \): matrix whose rows are the vectors that define the fastener element reference frame.
\( F \) is the CFAST Factor, whose value will be +1 or -1 depending on the relative orientation of the fastener with respect to the plate. The positive sign will be used if the “A” node is on the plate, while the negative sign will be used if the “B” node is on the plate. This is determined by the plate’s
BoltDirection
attribute.
If a plate is attached to two fasteners, its contribution are summed up:
\[ \vec{F}_{bearing}^M = \vec{F}_{fast_A}^M + \vec{F}_{fast_B}^M \]If a plate is attached to only one fastener, its bearing force will simply be the force of the fastener:
\[ \vec{F}_{bearing}^M = \vec{F}_{fastener}^M \]If the
PullThroughAsIs
attribute is set toTrue
, the last component of the bearing force (which is the pullthrough force), will be changed to the \( F_x \) force as obtained in the results files.If the
CompressionEqualsZero
attribute is set toTrue
, if the pullthrough force of a plate is negative (the plate is compressed), then the pullthrough force will be set to zero.Finally, if a plate is attached to two fasteners, its pullthrough force will always be set to zero if the “PAG” analysis is used, but nothing will be done if the “ALTAIR” analysis is selected (this is the only difference between them).
After having done this calculations, the following attributes are assigned for plates:
BearingForce
: dictionary in the form {LC ID: [FxBearing, FyBearing, FPullThrough]}, corresponding to the \( \vec{F}_{bearing}^M \) vector.TranslationalFastenerForces
: dictionary in the form {LC ID: [[FxA, FyA, FzA], [FxB, FyB, FzB]]}, corresponding to the \( \vec{F}_{fast_A}^M \) and \( \vec{F}_{fast_A}^M \) vectors. If the plate only has one fastener, the part of the non-existing fastener will be filled with zeros.
Also, the following attributes are assigned for bolts:
AxialForce
: dictionary in the form {LC ID: {EID: Force}} with the axial force or bolt tension, that is, the pullthrough force of each fastener (if it is possitive), or zero (if it is negative).MaxAxialForce
: dictionary in the form {LC ID: Force} with the maximum axial force or bolt tension, that is, the maximum axial force of all fasteners in the bolt.LoadAngle
: dictionary in the form {LC ID: {EID: Angle}} with the angle formed by the bearing force, which is obtained by the following equation:
\[ \theta = \arctan2(F_x^{Bearing}, F_y^{Bearing}) \]Finally, the shear force is calculated:
However, if
ShearAsIs
is set toTrue
, the shear force is
where \(F_y\) and \(F_z\) are obtained from the results files.
Now, the
ShearForce
attribute is assigned to bolts. Its structure is a dictionary in the form {LC ID: {EID: Force}} with the obtained \(F_{shear}\).
Possible errors and warnings#
W539: the results files have not been yet loaded, meaning that this method is being executed before the
get_results()
, so it is called
Bypass loads obtention#
In order to calculate the bypass loads, the get_bypass_loads()
method is used, which simply calls the also called get_bypass_loads()
method for each plate in each joint. The method used is very slightly different for the PAG and ALTAIR analyses, as will be explained later on, but they are both based on the crown method, which involves the use of a square shaped box that has already been created. The following steps are followed:
After obtaining the bypass box, the bypass fluxes and loads must be calculated, which is done using the
get_bypass_loads()
method once for each plate. In order to obtain the fluxes in each point of the box, a different methodology is used depending on whether or notCornerData
is set toTrue
.CornerData = True
:If the user asks for results in the corner when running the model and obtaining the corresponding results, these results will be given by node and not by element, giving several values for a node, related to the element where it is. Results will be more accurate if corner data is used, as there are more values to be used, but the process may be slower.
Taking each of the box’s points, the same procedure is carried out. Firstly, the results for all nodes that form the element where the box point is are retrieved. They are represented in their element reference frame, so they are transformed into the same reference frame. Once 3 or 4 values for the nodes are obtained (depending on wether the element is a TRIA or QUAD), a bilinear interpolation to the box point from the node locations is used.
Finally, the obtained values for the point are transformed to the material reference frame of the element where the bolt is pierced, which will be the system where the forces are to be represented in. Consider the following example:
As the point is located in element 431, the forces for the nodes that form it are retrieved, those nodes being the ones with IDs 476, 477, 515 and 523. It can be seen that, for nodes 476 and 477, four values would be obtained, as they are contained in four different elements. However, node 523 would have three values and 515 would have 5 values. Then, all the results should be transformed to be represented in the element reference frame of element 431 to make the average and obtain a single result for each node. Next, an interpolation from the four nodes to the point 2 is done and, finally, the transformation from the element reference frame of element 431 to the material reference frame of element 446 is done.
CornerData = False
The results in the result files are retrieved in the centroid of each element, leading to results that will be less precise, since results in the corners must be approximated instead of actually calculated. This approximation is made by averaging the adjacent elements. Besides this, the same procedure is used as in the previous case.
Finally, all results are transformed into the material reference frame corresponding to the element where the joint is pierced. Consider the same example as before:
The “goal” is to get the data in the surrounding nodes in order to be able to interpolate and obtain the result in point 2. Thus, if we use as an example node 515, the data in the centroid for elements 439, 431, 436, 437 and 438 should be retrieved. These values should be represented in the same reference frame (element reference frame of element 431). Finally, the average between these values should be computed in order to get the value in the node. This procedure should be carried out for all the nodes of the point element. Once these values have been computed, the same methodology is followed as in the corner data case: interpolate from the corners to the point and transform onto the element reference frame where the bolt is pierced.
After fluxes have been calculated in each point, fluxes are now calculated in each side. This is done by averaging the fluxes of all points in the side:
where the the subindex \( i \) represents the \( x \), \( y \) or \( xy \) fluxes and the superscript represent the side (North, West, South or East) or the point (1-8) in which the flux is calculated. The same formula is used for momenta.
Finally, the bypass force fluxes, total force fluxes and total momentum fluxes are calculated according to the following expressions:
where the superscript \( B \) denotes the bypass flux and the superscript \( T \) denotes the total flux.
If the “ALTAIR” option has been selected as the type of analysis, the momentum fluxes will instead be calculated as
Furthermore, the maximum and minimum bypass force flux is also calculated:
After all these calculations have been done, the following attributes are filled in for plates:
BoxFluxes
: dictionary in the form {LC ID: {1: [Nx1, Ny1, Nxy1, Mx1, My1, Mxy1], …, 8: [Nx8, …]}} with the force and momentum fluxes in each point.BypassSides
: dictionary in the form {LC ID: [[NxN, NxS, NxW, NxE], [NyN, NyS, NyW, NyE], [NxyN, NxyS, NxyW, NxyE], [MxN, MxS, MxW, MxE], [MyN, MyS, MyW, MyE], [MxyN, MxyS, MxyW, MxyE]]}.NxBypass
,NyBypass
,NxyBypass
,NxTotal
,NyTotal
,NxyTotal
,MxTotal
,MyTotal
,MxyTotal
,BypassMax
,BypassMin
: dictionary in the form {LC ID: F} with the corresponding bypass or total force or momentum, as calculated with the previous methodology.
Possible errors and warnings#
W539: the results files have not been yet loaded, meaning that this method is being executed before the
get_results()
one, so it is called.W542, W543: there is a problem with the interpolation.
Export results#
In order to export results, the ExportLocation
attribute must be filled in with a valid path file. Also, the TypeExport
attribute must be congruent with the TypeAnalysis
export, since outputs vary slightly. In any case, depending on the TypeExport
attribute, results are exported in one way or another. This is done with the export_results()
method.
TXT#
For the “TXT” export type, two .txt files are created through the __export_txt()
method, one for metallic materials and one for composite materials. The structure of these files is the same as the .txt files generated by the PAG tool. The file generated for composite materials has the following structure:
Section 1 (SETTING/VALUE): includes some general information about the analysis, as shown in the picture below.
Section 2 (ELEMENT/CONNECTOR-SYSTEM/EXTRACTION_POINTS): includes information about analysed plates, including the following:
Header |
Description |
---|---|
A/B-ELEM |
Solver ID of the plate’s central element |
A/B-PROPERTY |
Property ID of the plate’s central element |
CFAST_A |
Solver ID of the plate’s “A” fastener |
CFAST_B |
Solver ID of the plate’s “B” fastener |
DIRECTIONS |
Directions of the plate’s fastener. The pipe character (“|”) denotes the plate, while the arrow tip dentoes the location of the GB node |
EXT.ZONE |
Shape of the plate (SQUARE, TRIA, or POLYGON) |
ELEMENT_1, 2, …, 8 |
Solver ID of the element in which the bypass box’s points lie in |
POINT_1, 2, …, 8 |
Coordinates of the bypass box’s points |
Section 3 (ELEMENT/CONNECTOR-SYSTEM/EXTRACTION_POINTS part 2): includes information about analysed fasteners, including the following:
Header |
Description |
---|---|
CFAST-ID |
Solver ID of the fastener |
CFAST-PROPERTY |
Property ID of the fastener |
GS-NODE |
Solver ID of the fastener’s GS node |
GA-NODE |
Solver ID of the fastener’s GA node |
GB-NODE |
Solver ID of the fastener’s GB node |
A-ELEM |
Solver ID of the plate pierced by the GA node |
B-ELEM |
Solver ID of the plate pierced by the GB node |
DIAM(mm) |
Fastener’s diameter |
MATERIAL |
Fastener’s material |
Section 4 (RESULTS): includes the main results obtained in the class, including the following:
Header |
Description |
---|---|
A/B-ELEM |
Solver ID of the plate’s central element |
A/B-PROPERTY |
Property ID of the plate’s central element |
LOADCASE,SUBCASE |
Name of the load case |
BypassFlux Nxx |
Bypass force flux in the x-direction |
BypassFlux Nyy |
Bypass force flux in the y-direction |
BypassFlux Nxy |
Bypass x-y shear force flux |
XBearing Force |
Bearing force in the x-direction |
YBearing Force |
Bearing force in the y-direction |
PullThrough Force |
Tension/pullthrough force acting out of plane |
TotalMomentum Mxx |
Bypass momentum flux in the x-direction |
TotalMomentum Myy |
Bypass momentum flux in the y-direction |
TotalMomentum Mxy |
Bypass shear momentum flux in the xy-plane |
BoltShear |
Shear force acting on the bolt |
BoltTension |
Tension force acting in the bolt |
Section 5 (TRANSLATIONAL_FASTENER_FORCES): includes the forces associated to each fastener.
Section 6 (EXTRACTION_POINT_SHELL_FORCE_FLUXES): includes the force fluxes in each of the eight extraction points in each of the three directions, as well as the averaged value for each side (North, South, West and East) and the resulting bypass forces.
Section 7 (EXTRACTION_POINT_SHELL_MOMENTUM_FLUXES): includes the momentum fluxes in each of the eight extraction points in each of the three directions, as well as the averaged value for each side (North, South, West and East) and the resulting bypass momenta.
The file generated for metallic materials has exactly the same structure, with two exceptions: firstly, the last section (the one that included momentum fluxes) is supressed and, secondly, the “RESULTS” section varies slightly. It includes the following information:
Header |
Description |
---|---|
A/B-ELEM |
Solver ID of the plate’s central element |
A/B-PROPERTY |
Property ID of the plate’s central element |
LOADCASE,SUBCASE |
Name of the load case |
TotalFlux Nx |
Total force flux in the x-direction |
TotalFlux Nyy |
Total force flux in the y-direction |
TotalFlux Nxy |
Total x-y shear force flux |
F_Shear Fx |
Bolt shear force in the x-direction |
F_Shear Fy |
Bolt shear force in the y-direction |
Fastener Fx |
Bearing force in the x-direction |
Fastener Fy |
Bearing force in the y-direction |
PullThrough Fz |
Tension/pullthrough force acting out of plane |
BoltShear |
Shear force acting on the bolt |
BoltTension |
Tension force acting in the bolt |
HDF5#
For the “HDF5” export type, one .h5 file is created through the __export_hdf5()
method. Its structure is the same as the structure in all NaxToPy HDF5 file, that being a nested structure that includes the following data:
Load case
Increment
Results name (in this case, it will be “FASTENER ANALYSIS”)
Section
Data
The information included in the “DATA” section is the following:
“ID_ENTITY”: solver ID of the plate’s central element.
“BYPASS FLUX NXX”, “BYPASS FLUX NYY”, “BYPASS FLUX NXY”: bypass fluxes.
“TOTAL FORCE FLUX NXX”, “TOTAL FORCE FLUX NYY”, “TOTAL FORCE FLUX NXY”: total force fluxes.
“X BEARING FORCE”, “Y BEARING FORCE”, “PULLTHROUGH FORCE”: bearing and pullthrough force.
“TOTAL MOMENTUM FLUX MXX”, “TOTAL MOMENTUM FLUX MYY”, “TOTAL MOMENTUM FLUX MXY”: total momentum fluxes.
“BOLT SHEAR”: shear force.
“BOLT TENSION: tension force.
“FXX CFAST A”, “FYY CFAST A”, “FZZ CFAST A”, “FXX CFAST B”, “FYY CFAST B”, “FZZ CFAST B”: translational fastener forces.
“FXX POINT 1”, “FYY POINT 1”, …, “MXY POINT 1”, “FXX POINT 2”, …: fluxes in each point of the bypass box.
“FXX NORTH”, “FYY NORTH”, …, “MXY EAST”: fluxes in each side of the bypass box.
REDUCED_HDF5#
For the “REDUCED_HDF5” export type, one .h5 file is created also through the __export_hdf5()
method. Its structure is the same as the structure in all NaxToPy HDF5 file, that being a nested structure that includes the following data:
Load case
Increment
Results name (in this case, it will be “FASTENER ANALYSIS”)
Section
Data
The information included in the “DATA” section is the following:
“ID_ENTITY”: solver ID of the plate’s central element.
“BYPASS FLUX NXX”, “BYPASS FLUX NYY”, “BYPASS FLUX NXY”: bypass fluxes.
“BOLT TENSION: tension force.
CSV and ALTAIR#
For the “CSV” export type, one .csv file is created through the __export_csv()
method. The same results that were exported to a .h5 file is being exported now to a .csv file, with the same name and order.
For the “ALTAIR” export type, one .csv file is created, also through the export_csv()
method, and the following data is exported, which is the same as the data exported to an Altair .csv file:
“DDP”: joint’s internal ID.
“entityid”: plate’s internal ID.
“elementid”: plate’s element solver ID.
“Component Name”: plate’s element property ID.
“elem 1 id”, “elem 2 id”: fastener’s solver ID.
“elem 1 node id”, “elem 2 Node id”: fastener’s nodes solver ID.
“box dimension”: bypass box dimension.
“loadcase”: load case ID.
“file Name”: analysis name.
“LoadCase Name”: load case name.
“Time Step Name”: increment ID.
“pierced location”: coordinates of the intersection point between the plate and its fasteners.
“Fx”, “Fy”, “Fz”: bearing and pullthrough forces.
“MaxFz”: maximum axial force.
“p1”, …, “p8”: coordinates of the points of the bypass box.
“Fxx p1”, “Fxx p2”, …, “Mxy p8”: bypass fluxes in each point of the bypass box.
“Nx bypass”, “Nx total”, “Ny bypass”, “Ny total”, “Nxy bypass”, “Nxy total”, “Mx total”, “My total”, “Mxy total”: bypass and total forces and momentum fluxes.
Possible errors and warnings#
W537: the bearing force has not been calculated, which means that this method is being called before the
get_forces_joints()
one.W538: the bypass loads have not been calculated, which means that this method is being called before the
get_bypass_joints()
one.
Load results again#
If the user has already performed the bearing and bypass analysis, and wants to load these results onto another N2PGetLoadFasteners
object (for example, the Python kernel is restarted), a completely different approach is used. Firstly, as was mentioned in the start of the document, the ResultsFiles
attribute should not be filled in, while the BypassResults
attribute should. This attribute must be a string corresponding to the path for a .h5 file that has all of the required information. It is recommended that this file be obtained with the TypeExport
attribute set to “REDUCED_HDF5”, as the program will be much faster loading these results. Take note that the rest of the compulsory attributes must be filled in, that is, either the GetFasteners
attribute, or the Model
and JointsList
attributes. Of course, most of the N2PGetLoadFasteners
attributes will not be used, so they should not be modified. Some of the attributes that may be altered are LoadCases
and LoadCaseNumber
.
To extract results, the user should use the load_h5()
method, which calls the get_results_h5()
method. This method, similarly to the get_results()
one, extracts results from the results file and then assigns them to the corresponding plates and bolts.
Possible errors and warnings#
E521, E522, E523: either the model, list of joints, or results files, have not been loaded.
Example#
import NaxToPy as NP
from NaxToPy.Modules.Fasteners.N2PGetFasteners import N2PGetFasteners
from NaxToPy.Modules.Fasteners.N2PGetLoadFasteners import N2PGetLoadFasteners
# The first analysis is done
model = NP.load_model(r"route.fem")
elementList = [(57510018, '0'), (57510014, '0'), (57510022, '0')]
N2PElementList = model.get_elements(elementList)
fasteners = N2PGetFasteners()
fasteners.Model = model
fasteners.ElementList = N2PElementList
fasteners.calculate()
loads = N2PGetLoadFasteners()
loads.GetFasteners = fasteners
loads.ResultsFiles = [r"results_1.op2", r"results_2.op2", r"results_3.op2"]
loads.TypeExport = "REDUCED_HDF5"
loads.AnalysisName = "Test analysis"
loads.ExportLocation = r"C:\User\Analysis_folder"
loads.calculate()
# Now that results have been exported to a reduced .h5 file, the user may restart the Python kernel, turn off the computer, or delete the results in memory in any other way
# A new N2PGetFasteners() object is created with the same fasteners as the original one
fasteners2 = N2PGetFasteners()
fasteners2.Model = model
fasteners2.ElementList = N2PElementList
fasteners2.calculate()
# Results are loaded to those fasteners
loads2 = N2PGetLoadFasteners()
loads2.GetFasteners = fasteners2
loads2.BypassResults = r"C:\User\Analysis_folder\Test analysis_fastpph.h5"
loads2.load_h5()
Influence of optional attributes#
Now that the functionality of the class has been shown, it would be useful to understand the influence of the optional attributes, regarding the numerical values of the results obtained and the performance of the method:
CompressionEqualsZero
,ShearAsIs
,PullThroughAsIs
: it has no effect on performance, but the bearing and shear values will change. For the first attribute, negative pullthrough forces will be set to zero; for the second one, the shear force will not be calculated and instead the force obtained in the results file will be used; and for the last one, the pullthrough force will not be calculated and instead the default value will be used.MaterialFactorMetal
,MaterialFactorComposite
,AreaFactor
: it has no effect on performance, but the bypass values will differ, as they are used to create the bypass box. It is highly recommended that the user leaves these values as they are (especially for a PAG analysis) or just changes theMaterialFactorComposite
value to 4.5 (for an ALTAIR analysis).ExportPrecision
: it has no effect on performance. The only difference is the type of float (with simple or double precision) that will be exported to a HDF5 file.DefaultDiameter
: it has no effect on performance. This value will be assigned as diameter to all joints with no diameter in their cards. If this is not present, joints with no diameter will not have their values calculated.MaxIterations
: it could have an influence on both the performance and the results, because, if this value is too small, “good” plates will be discarded and their loads not calculated. It is not recommended to change this value, as usually the bypass box will be obtained within a few iterations.ProjectionTolerance
: it could have an influence on both the performance and the results, because it has an influence in the determination of wether or not a point belongs to an element. it is not recommended to change this value.CornerData
: it has an influence on both the performance and the results obtained. It is recommended to keep this set toFalse
, as the other option is significantly more computationally expensive and has not been tested as much, even if it would guarantee a slightly better accuracy.LoadSecondModel
: it has an influence on the performance, but not the obtained results. Setting this toTrue
would mean that, before obtaining the results, a new model would have to be created and elements would have to be updated, but results would be obtained in less elements. Therefore, the user may want to set this toTrue
if obtaining the results takes a very long time compared to the other parts of the method.LoadCaseNumber
: it has an influence on the performance, but not the obtained results. Setting this value to an integer N would mean that results are obtained in batches of N, which the user may want to do if the number of load cases to be analysed is very high. The amount that should be set depends mainly on the computer in which the method is ran, and a rough estimate would be 1000.AdjacencyLevel
: it has an influence on the performance and it may have an influence on the obtained results. Setting this to an integer N would mean that a new model is created with less elements (which takes time), and some elements have to be updated (which also takes time). However, a model with less elements would mean that obtaining the bypass box and bypass loads take less time, but obtaining the results take more time. Therefore, the user may want to set this to some value if loading results does not take much time, but creating the bypass boxes and/or obtaining the bypass loads do. The value to be set depends on how fine the mesh is, and the user should make sure that a high enough value is set so that all elements within approximately 5 diameters of every bolt are included, with 4 being a good value for most cases. Regarding the accuracy of the results, it is important to note that selecting a value that is too low would mean that some points making up the bypass box would be located outside of the model, giving worse results (as has been explained before).
Validation#
Both the get_forces_joints()
and the get_bypass_joints()
methods were validated against the Altair JointLoad method and the Patran PAG Fasteners Tool. It has been found that the average difference between the results obtained with both tools and the results obtained with the NaxToPy tools were of less than \(\pm\) 1 N/mm or 1 N (depending on whether forces or momentums were compared), which is the same uncertainty that PAG offers. Take note, however, that different formulae are used for the Altair and PAG analyses regarding bypass momentum calculations and pullthrough forces for unions with several bolts, so results will differ depending on the analysis made. Also, the default attributes for this method correspond to the default attributes used for the PAG analysis, so if a user were to compare the results obtained from this tool and the results obtained from Altair’s JointLoad method, they should remember to set:
TypeAnalysis
toALTAIR
.OptionalAttributes.PullThroughAsIs
toFalse
.OptionalAttributes.ShearAsIs
toFalse
.OptionalAttributes.CompressionEqualsZero
toFalse
.OptionalAttributes.MaterialFactorComposite
to 4.5. Also, the user should remember thatN2PGetFasteners
andN2PGetLoadFasteners
assume that, if two fastener pierce the same plate at two different nodes, they are considered to be two different joints, which is the same criterion used by Altair, but not by PAG. Therefore, bearing results will be very different for these cases, while bypass results will not be affected.
Extra examples#
import NaxToPy as NP
from NaxToPy.Modules.Fasteners.N2PGetFasteners import N2PGetFasteners
from NaxToPy.Modules.Fasteners.N2PGetLoadFasteners import N2PGetLoadFasteners
model = NP.load_model(r"route.fem")
elementList = [(57510018, '0'), (57510014, '0'), (57510022, '0')]
N2PElementList = model.get_elements(elementList)
fasteners = N2PGetFasteners()
fasteners.Model = model
fasteners.ElementList = N2PElementList
fasteners.GetAttachmentsBool = False # Attachments are not calculated in order to save time
fasteners.GetDistanceBool = True # Distances are obtained
fasteners.calculate()
fasteners.JointsList[0].Diameter = 6.0 # One of the joints is manually assigned a certain diameter
fasteners.assign_diameter(model.get_elements((57510014, '0')), 5.4) # Other joint is assigned a certain diameter through the assign_diameter() method
loads = N2PGetLoadFasteners()
loads.Model = model
loads.JointsList = fasteners.JointsList # As mentioned, the user does not have to use the loads.Fasteners attribute,
# even if it is recommended
loads.OptionalAttributes.AdjacencyLevel = 3 # A lower adjacency level is selected in order to save time, even if it risks not finding the
# bypass box for certain joints
loads.ResultsFiles = r"C:\User\Results" # The user can load an entire folder full of results files
# From this point on, a new model is generated and the loads.Model attribute is updated.
loads.LoadCases = loads.Model.get_loadcase([253, 333, 717])
loads.CornerData = True # This option should only be turned on if the user is sure that there actually is corner data
loads.DefaultDiameter = 5.6 # Joints with no diameter will be assigned this value for their Diameter attribute. The
# joints that had been assigned a diameter before will not be modified
loads.OptionalAttributes.ProjectionTolerance = 0.1
loads.OptionalAttributes.MaterialFactorComposite = 4.5
loads.TypeAnalysis = "ALTAIR"
loads.TypeExport = "HDF5"
loads.OptionalAttributes.ExportPrecission = 8
loads.OptionalAttributes.CompressionEqualsZero = False
loads.OptionalAttributes.PullThroughAsIs = False
loads.OptionalAttributes.ShearAsIs = False
loads.AnalysisName = "Analysis_1"
loads.ExportLocation = r"C:\User\Analysis_folder"
loads.calculate()
References#
[Ref-1]: JointLoad Method: https://2023.help.altair.com/2023/hwdesktop/hwx/topics/pre_processing/aerospace/methods_built_in_libraries_jointload_r.htm
[Ref-2]: Gustavo Silva, Rodolphe Le Riche, Jérôme Molimard, Alain Vautrin. Exact and efficient interpolation using finite elements shape functions. 2007.
[Ref-3]: Patran PAG Fastener Tools User Guide v1.5. 2015.
All rights reserved. This document is licensed under the terms of theLICENSE of the NaxToPy package.