N2PFatigueDamage User Manual#
Overview#
The N2PFatigueDamage Module is designed to compute the cumulative fatigue damage of a structure subjected to cyclic loading, based on Finite Element Analysis (FEA) results and external load time histories. The module combines FEM loadcases with load sequences, performs cycle counting following the ASTM E1049-85 (2017) standard (see [Ref-1]), applies a mean-stress correction, enters the material S-N curve and accumulates damage through the Palmgren-Miner linear rule.
The total accumulated damage is obtained by superposing the contribution of every load cycle, every load combination, every event and every event repetition:
where \(n_i\) is the number of applied cycles of cycle \(i\), \(N_{f,i}\) is the number of cycles to failure read from the S-N curve for the equivalent alternating stress of that cycle, \(R_e\) is the number of repetitions of the event and \(s_e\) its scale factor.
For each load combination the stresses are reconstructed from the linear FEM result by scaling the unit-load stress field with the counted load peaks and the stress concentration factor \(K_t\):
from which the alternating and mean stresses are derived:
The fatigue life is finally evaluated on an equivalent fully-reversed alternating stress \(S_{a,\text{equiv}}\) obtained after the mean-stress correction.
Example Usage#
1. Importing the module#
import NaxToPy as n2p
from NaxToPy.Modules.fatigue import N2PFatigueDamage
2. Load the model#
model = n2p.load_model(r"file path")
3. Create N2PFatigueDamage and assign model#
damage = N2PFatigueDamage()
damage.Model = model # Assign the model
4. Define Fatigue Loads and Materials Files#
damage.EventsFile = r"FatigueEvents.csv" # Events and load combinations file
damage.MaterialsFile = r"Materials.csv" # Materials database file
5. Define the analysis options#
damage.ResultType = 'STRESSES'
damage.Method = 'VON_MISES'
damage.ResultsPosition = 'ELEMENTS'
damage.MeanStressCorrection = 'GOODMAN'
damage.CycleCountingMethod = "RAINFLOW_FOR_REPEATING_HISTORIES"
6. Assign materials and stress concentration factors to elements#
damage.MaterialAssignment = {"Steel": Steel_elements_n2p} # Material name -> elements
damage.Kts = {1.5: kt1_5_elements_n2p} # Kt value -> elements
Note
The material names used in MaterialAssignment must match the material names defined in the MaterialsFile.
7. Run the calculation#
Damage_Results = damage.calculate()
More information and advanced usage in Module Inputs.
Setup#
Mandatory 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.
Input files: An Events file and a Materials file (both in CSV format) must be provided. See Module Inputs.
Optional Prerequisites#
Output libraries: The results can be exported to CSV and Altair HWASCII formats. No additional library is required for the export.
Module Inputs#
The N2PFatigueDamage class provides methods and attributes for defining the model, the load events, the materials and the calculation options.
Mandatory Inputs#
Property |
Type |
Description |
|---|---|---|
.Model |
|
FEM model to be analyzed |
.EventsFile |
|
Path to the CSV file describing the fatigue events and combinations |
.MaterialsFile |
|
Path to the CSV file describing the materials and their S-N curves |
.MaterialAssignment |
|
Mapping of material name to the list of elements made of it |
Optional Inputs#
Property |
Type |
Default |
Description |
|---|---|---|---|
.ResultType |
|
|
Type of FEM result used for the assessment ( |
.Method |
|
|
Stress evaluation method: |
.ResultsPosition |
|
|
Position where the damage is computed: |
.MeanStressCorrection |
|
|
Mean-stress correction: |
.CycleCountingMethod |
|
|
Cycle counting method: |
.Kts |
|
|
Mapping of stress concentration factor \(K_t\) to the list of elements where it applies. |
Warning
The CRITICAL_PLANE method is only available for 2D shell elements (e.g. CQUAD4, CTRIA3 / S3, S4). If the method is requested and no 2D elements exist in the model, an exception is raised.
FEM Requirements#
For this module to function properly, the FEM model must include static stress results in the output requests for all the load cases referenced by the combinations. The model should accurately represent all elements and load cases where the fatigue assessment is expected to be applied. This module is available for Nastran, Optistruct, Abaqus and Ansys.
Supported Type Files#
Solver |
File Extension |
|---|---|
Nastran |
.op2 |
Nastran |
.xdb |
Nastran |
.h5 |
Optistruct |
.op2 |
Optistruct |
.h3d |
Abaqus |
.odb |
Ansys |
.rst |
Events File format#
The Events file is a ;-delimited CSV that groups the load combinations into events. Each event is delimited by ### EVENT / ### END EVENT markers and contains:
## Repeats: number of repetitions of the event.## Scale: global scale factor applied to the event.A combinations table (header starting with
# Comb_ID) with one row per combination, with columns:Comb_ID,Result_File,LC_ID,Increment,csv_File(load time history),Component,Scale,Filter_MinandOffset.
Each combination links a FEM load case/increment (Result_File, LC_ID, Increment) with an external load history (csv_File, Component). An increment value of -1 is automatically resolved to the last increment of the referenced load case.
Load History File format#
The load history files referenced by the combinations can be of two types, auto-detected from the header:
Timeseries: a column named
timeplus one column per load component. The selectedComponentcolumn is cycle-counted according toCycleCountingMethod.Blockload: pre-counted cyclic loads with columns
id,Pmax,Pmin,n(already expressed as load peaks and cycle counts, so no cycle counting is applied).
Materials File format#
The Materials file is a ;-delimited CSV. Each material block starts with # Material and defines:
## Name: material name (must match the keys ofMaterialAssignment).## UTS: Ultimate Tensile Strength.## YP: Yield Point.## R: stress ratio \(R\) of the S-N curve.## SN_Curve(N;Sa): header followed by the S-N curve points, oneN;Sapair per line.
Material Assignment#
Materials are associated with elements through the MaterialAssignment dictionary. If an element is included in more than one material, only its first occurrence (according to dictionary order) is kept and a warning is issued.
Warning
Every analyzed element must have a material assigned. If any element is left without material, the calculation raises an error.
Output Description#
The calculate() method returns a Damage_Results dictionary and stores it in the Damage_Results property. The dictionary contains, per analyzed element:
"Damage": total accumulated fatigue damage."logNf": \(-\log(\text{Damage})\)."Life": estimated fatigue life (\(1/\text{Damage}\), or infinite when the damage is zero)."Orientation": critical plane orientation (only for theCRITICAL_PLANEmethod).
The intermediate quantities (Smax, Smin, S_a, S_m, Sa_equiv, N_fatiga, d_i, D_total_comb) are also stored in each combination object for traceability.
Result export#
At the end of the calculation the results for every analysed elemments are automatically exported to two timestamped files in the working directory:
Damage_Results_<YYYYMMDD>_<HHMMSS>.csv(NaxToView format)Damage_Results_<YYYYMMDD>_<HHMMSS>.hwascii(Altair HWASCII format)
In addition, for every combination the fatigue matrix of the critical (most damaged) element is written to fatigue_max_damage_matrix_Comb<ID>_Element<ID>.csv, and the counted cycles of each time history are written to a cycles_*.csv file.
Common Warnings#
An element included in several materials: it will be considered only in the first material where it appears.
Elements that do not have results for all the combinations: they are discarded from the analysis and their IDs are reported.
Elements provided in
MaterialAssignmentthat are not valid for the selectedMethod: they are discarded and reported.
Common Errors#
Invalid Cycle Counting Method: raised when an unsupported value is assigned toCycleCountingMethod.Invalid ResultType: raised when an unsupported value is assigned toResultType.Invalid Method: raised when an unsupported value is assigned toMethod.Invalid MeanStressCorrection: raised when an unsupported value is assigned toMeanStressCorrection.Unrecognized solver: raised when the model solver is not one of Nastran, Optistruct, Abaqus or Ansys.NO 2D Elements in model: raised whenCRITICAL_PLANEis requested but the model has no 2D elements.Some elements have no material assigned: raised when an element is left without material.Unable to match combination: raised when a combination cannot be matched against any model load case/increment.
Methodology#
Background Theory#
The methodology follows the classical stress-life (S-N) approach for high-cycle fatigue, combining four well-established building blocks:
Linear superposition of stresses: the FEM stress obtained for each FEM load case/increment (
Result_File,LC_ID,Increment) is scaled by the actual load magnitude and by the stress concentration factor \(K_t\) to reconstruct the local stress state.Cycle counting: the irregular load time histories are simplified considering full/half cycles following the ASTM E1049-85 (2017) standard. See [Ref-1].
Mean-stress correction: each cycle, characterized by its alternating and mean stress, is converted into an equivalent fully-reversed alternating stress.
Linear damage accumulation: the damage of every cycle is summed following the Palmgren-Miner rule.
Cycle counting#
Three cycle counting algorithms, all based on the rules described in ASTM E1049-85 (2017), are available:
RAINFLOW(ASTM 5.4.4): three-point rainflow counting, producing both full and half cycles, without history rearrangement or closing of the last cycle.RANGE-PAIR(ASTM 5.4.3): range-pair counting with a forward and a backward pass.RAINFLOW_FOR_REPEATING_HISTORIES(ASTM 5.4.5): simplified rainflow counting for repeating histories. The series is first rearranged to start at the absolute maximum peak (or minimum valley), then closed by appending the first value at the end, and counted producing only full cycles. This is the default method.
In all cases the raw history is first reduced to its reversals (peaks and valleys) by removing consecutive duplicates and intermediate non-turning points. Each counted cycle is described by its amplitude, mean and count, and converted into a blockload format (\(P_{\max} = \text{mean}+\text{amp}\), \(P_{\min} = \text{mean}-\text{amp}\), \(n = \text{count}\)).
Stress evaluation method#
The local stress used for the assessment depends on the Method:
VON_MISES/MAX_PRINCIPAL: the corresponding scalar stress component is read directly from the FEM results.CRITICAL_PLANE: the in-plane stress tensor (\(\sigma_{xx}\), \(\sigma_{yy}\), \(\tau_{xy}\)) is projected onto 18 candidate planes spanning 0°-170° in 10° steps,
and the fatigue assessment is carried out independently for each orientation. The critical plane is the one yielding the maximum damage, and its orientation is reported per element.
Mean-stress correction#
The equivalent alternating stress \(S_{a,\text{equiv}}\) is computed from \(S_a\) and \(S_m\) according to MeanStressCorrection.
Goodman: For the Goodman correction the following cases are distinguished:
\(S_m \le 0\) (compressive Mean Stress): no correction is applied and \(S_{a,\text{equiv}} = S_a\), conservatively keeping the original amplitude.
\(0 < S_m < S_u\) (Goodman domain):
where \(R\) is the stress ratio of the material S-N curve.
\(S_m \ge S_u\) (mean stress beyond the ultimate strength): a high artificial value (\(10\,S_u\)) is assigned so that the resulting damage is driven to failure.
Number of cycles to failure#
The number of cycles to failure \(N_f\) is obtained by entering the material S-N curve with \(S_{a,\text{equiv}}\), using a piecewise log-log interpolation considering the following cases:
if \(S_{a,\text{equiv}}\) is below the lowest stress of the curve (considered as the Endurace limit), an effectively infinite life is assigned (\(N_f = 10^{15}\));
if \(S_{a,\text{equiv}}\) is above the highest stress of the curve, the first segment is extrapolated;
otherwise the value is interpolated within the corresponding segment of the curve.
Any \(N_f\) that falls below 1 cycle (which can happen, for instance, when \(S_m \ge S_u\) under the Goodman correction) is clamped to 1, so the cycle contributes with damage equals 1.
Damage accumulation#
Damage is calculated eor each result Result component and for each element as follows:
Cycle Damage is computed with the Palmgren-Miner rule, \(d_i = n_i / N_{f,i}\).
Combination Damage: The damages per cycle are summed to obtain the damage of the combination.
Event Damage: The combination damages are summed per stress component to obtain the damage of the event.
Global damage is obtained by summing the events damages weighting each one by its number of repetitions and scale factor.
Implementation#
The main entry point is the calculate() method, which orchestrates the full pipeline:
Read the Events file and build the
FatigueEvents -> Event -> Combinationhierarchy.Read the Materials file and build the materials database (by name and by ID).
Build the element list from
MaterialAssignmentand filter it according to the selected method (2D Elements for Critical Plane Method).Assign the internal N2P load case ID to every combination.
Extract the FEM stress results for all the load case/increment pairs referenced by the combinations (the element list is reduced to the elements that actually have results).
Map the material ID to every element.
Map the \(K_t\) factor to every element.
For each event and combination: count the load cycles, reconstruct \(S_{\max}\) and \(S_{\min}\), compute \(S_a\), \(S_m\), the equivalent stress, the number of cycles to failure (per material) and the cycle damage.
Accumulate the damage at combination, event and global level, and compute the per-element results.
Export the results to CSV and HWASCII.
The whole calculation is vectorized with NumPy: stresses are handled as 3D arrays of shape (n_elements, 1, n_blocks) and broadcasting is used to combine the per-element FEM stresses, the per-element \(K_t\) factors and the per-block load peaks, so that all elements and all cycles are processed simultaneously.
Advanced Features#
Feature |
Description |
|---|---|
Critical plane |
Per-element damage and critical orientation obtained by scanning 18 candidate planes ( |
Multiple materials |
Different materials, each with its own S-N curve and UTS, can be assigned to different element sets. |
Blockload input |
Pre-counted blockloads can be provided directly, bypassing the cycle counting stage. |
Critical element trace |
For every combination, the fatigue matrix of the most damaged element is exported. |
Extra Examples#
import NaxToPy as n2p
from NaxToPy.Modules.fatigue import N2PFatigueDamage
model = n2p.load_model(r"C:\my_directory\my_model.op2")
# Select the elements to assign to each material
all_elements = model.get_elements()
damage = N2PFatigueDamage()
damage.Model = model
damage.EventsFile = r"FatigueEvents.csv"
damage.MaterialsFile = r"Materials.csv"
damage.ResultType = 'STRESSES'
damage.Method = 'CRITICAL_PLANE'
damage.MeanStressCorrection = 'GOODMAN'
damage.CycleCountingMethod = "RAINFLOW_FOR_REPEATING_HISTORIES"
# Assign every element to a single material
damage.MaterialAssignment = {"DC90": all_elements}
# Optional: assign stress concentration factors
damage.Kts = {2.5: all_elements}
Damage_Results = damage.calculate()
# Access the per-element results
damage_array = Damage_Results["Damage"]
life_array = Damage_Results["Life"]
orientation_array = Damage_Results["Orientation"] # only for CRITICAL_PLANE
References#
This guide serves as a comprehensive reference for using the N2PFatigueDamage Module in structural analysis tasks. For further information, refer to the source code comments and examples provided.
All rights reserved. This document is licensed under the terms of the LICENSE of the NaxToPy package.