Source code for pyfem.materials.MaxStrain

# SPDX-License-Identifier: MIT
# Copyright (c) 2011–2026 Joris J.C. Remmers

"""
Maximum strain failure criterion for composite materials.

This module implements the maximum strain failure criterion, which is commonly
used for fiber-reinforced composite materials. Failure is predicted when any
principal strain component exceeds its allowable limit.
"""

from pyfem.materials.BaseFailure import BaseFailure
from numpy import ndarray
from typing import Union


[docs] class MaxStrain(BaseFailure): """ Maximum strain failure criterion. This criterion predicts failure when any strain component exceeds its corresponding allowable strain. It is one of the simplest failure criteria for orthotropic materials like fiber-reinforced composites. The failure index is computed as: FI = max(ε₁/ε₁ᵗ, |ε₁|/ε₁ᶜ, ε₂/ε₂ᵗ, |ε₂|/ε₂ᶜ, |γ₁₂|/γ₁₂ᵘ) where: - ε₁, ε₂: normal strains in principal material directions - γ₁₂: shear strain - Superscripts: t = tension, c = compression, u = ultimate Failure occurs when FI ≥ 1.0 Required Properties ------------------- eps1t : float Maximum tensile strain in fiber direction (direction 1). eps1c : float Maximum compressive strain in fiber direction (magnitude, positive). eps2t : float Maximum tensile strain transverse to fibers (direction 2). eps2c : float Maximum compressive strain transverse to fibers (magnitude, positive). gamma12u : float Maximum shear strain (magnitude, positive). Examples -------- Typical values for carbon fiber/epoxy composite: <Failure> type = "MaxStrain"; eps1t = 0.015; # 1.5% tensile strain in fiber direction eps1c = 0.012; # 1.2% compressive strain eps2t = 0.005; # 0.5% transverse tensile strain eps2c = 0.010; # 1.0% transverse compressive strain gamma12u = 0.020; # 2.0% shear strain </Failure> Notes ----- - This criterion does not account for interaction between strain components - Conservative for combined loading conditions - Simple to implement and computationally efficient - Suitable for preliminary design and conservative estimates """ def __init__(self, props) -> None: """ Initialize the MaxStrain failure criterion. Parameters ---------- props : Properties Material properties object containing strain limits. """ BaseFailure.__init__(self, props) # Validate that all required properties are present required_props = ['eps1t', 'eps1c', 'eps2t', 'eps2c', 'gamma12u'] for prop in required_props: if not hasattr(self, prop): raise ValueError(f"Required property '{prop}' not found for MaxStrain failure criterion")
[docs] def check(self, stress: ndarray, deformation) -> float: """ Evaluate the maximum strain failure criterion. Parameters ---------- stress : ndarray Stress tensor (not used in this criterion, but kept for interface consistency). deformation : object Deformation object containing strain information. Must have attribute 'strain' or 'eps'. Returns ------- float Failure index (FI). FI ≥ 1.0 indicates failure. FI < 1.0 indicates safe condition. Notes ----- The strain tensor should be in engineering notation: - For 2D: [ε₁, ε₂, γ₁₂] - For 3D: [ε₁, ε₂, ε₃, γ₂₃, γ₁₃, γ₁₂] Shear strains are engineering shear strains (γ = 2ε₁₂). """ # Get strain from deformation object if hasattr(deformation, 'strain'): strain = deformation.strain elif hasattr(deformation, 'eps'): strain = deformation.eps else: raise AttributeError("Deformation object must have 'strain' or 'eps' attribute") FI = 0.0 # Check normal strain in direction 1 (fiber direction) if strain[0] > 0.0: FI = strain[0] / self.eps1t else: FI = abs(strain[0]) / self.eps1c # Check normal strain in direction 2 (transverse direction) if strain[1] > 0.0: FI = max(strain[1] / self.eps2t, FI) else: FI = max(abs(strain[1]) / self.eps2c, FI) # Check shear strain # For 2D plane stress: strain[2] is γ₁₂ # For 3D: strain[5] is γ₁₂ if len(strain) == 3: FI = max(abs(strain[2]) / self.gamma12u, FI) else: FI = max(abs(strain[5]) / self.gamma12u, FI) return FI