How the Phase-Field Fracture Model Works in PhaseFieldX: A Technical Deep Dive
PhaseFieldX implements a staggered finite-element formulation that alternately solves mechanical equilibrium and phase-field evolution until convergence, using spectral energy splits and modular degradation functions to simulate brittle fracture.
The phase-field fracture model in PhaseFieldX provides a robust framework for simulating crack initiation and propagation without explicit tracking of discontinuities. This open-source library, built on FEniCSx/DOLFINx, couples a mechanical displacement problem with a phase-field (damage) problem through an efficient staggered algorithm. The following sections dissect the core components, governing equations, and implementation details found in the castillonmiguel/phasefieldx repository.
Core Components of the Phase-Field Fracture Model
Linear Elastic Material Model
The foundation of the fracture model rests on isotropic linear elasticity defined in src/phasefieldx/Materials/elastic_isotropic.py. This module computes the strain-energy density ψ and the strain tensor ε based on Young's modulus E and Poisson's ratio ν. The elastic constitutive law feeds directly into the energy split routines that determine how damage evolves under tensile versus compressive loading.
Spectral Energy Decomposition
To ensure that cracks only propagate under tension while preserving compressive stiffness, PhaseFieldX employs a spectral decomposition of the elastic energy. The file src/phasefieldx/Element/Phase_Field_Fracture/split_energy_stress_tangent_functions.py defines the functions psi_a and psi_b, which separate the strain energy into a tensile part ψₐ and a compressive part ψ_b. Corresponding stress functions sigma_a and sigma_b compute the degraded and undegraded stress contributions, respectively.
Degradation Functions
The degradation function g(φ) reduces the tensile stiffness as the phase-field variable φ ∈ [0,1] evolves from 0 (intact) to 1 (fully broken). PhaseFieldX offers multiple functional forms—including quadratic, Borden, Alessi, and Sargado—implemented in src/phasefieldx/Element/Phase_Field_Fracture/g_degradation_functions.py. The selector function g(phi, degradation_type) and its derivative dg allow users to switch models by changing the degradation_function parameter in the Input class.
Fracture Surface Energy
The regularized crack surface energy follows the Ambrosio-Tortorelli (AT1/AT2) functionals. The module src/phasefieldx/Element/Phase_Field/energy.py provides calculate_crack_surface_energy, which computes the fracture energy term Gc * ( (1/(c₀ l) φ + (l/c₀) |∇φ|² ). The constant c₀ depends on the selected crack density functional, distinguishing between AT1 (linear) and AT2 (quadratic) models.
The Staggered Solution Algorithm
PhaseFieldX solves the coupled displacement-damage system using a staggered scheme rather than a fully monolithic approach. This algorithm, implemented in src/phasefieldx/Element/Phase_Field_Fracture/solver/solver.py, alternates between mechanical and phase-field sub-problems until convergence.
The staggered loop follows these steps:
- Solve mechanical equilibrium using the current phase-field
φto degrade the tensile stiffness. - Update the history variable
Hto enforce irreversibility (damage cannot heal). - Solve the phase-field evolution using the updated history variable.
- Check convergence by evaluating the L²-norm change of both displacement
uand phase-fieldφ.
# Pseudocode extracted from solver.py (lines 29-49, 84-106)
while t < final_time:
# Outer time loop
while not converged and stagger_iter < max_iter:
# 1) Solve mechanical problem (Newton → problem_u.solve())
# update displacement field u_new → u_old
# 2) Update history variable H (irreversibility)
project(psi_a(u_new, Data), V_c) # line 55
H.x.array[:] = np.maximum(V_c.x.array, V_n.x.array) \
if Data.irreversibility == "miehe" else V_c.x.array
# 3) Solve phase-field problem (Newton → problem_phi.solve())
# update phase field Φ_new → Φ_old
# 4) Optional fatigue update (lines 62-77)
# 5) Check L²-norm errors (eval_error_L2_normalized)
# break when both < stagger_error_tol
The convergence check uses eval_error_L2_normalized to compute normalized L² norms, ensuring that both fields reach equilibrium before advancing to the next time step.
Governing Equations
The weak forms implemented in PhaseFieldX follow the standard phase-field fracture theory with spectral splits.
Mechanical equilibrium (weak form):
∫_Ω [(g(φ) + k) σ_a(u) : ε(δu) + σ_b(u) : ε(δu)] dx = ∫_Γ_N t̄ · δu ds
Here, g(φ) is the degradation function, k is a small stabilization parameter (Data.k), σ_a is the degraded tensile stress, and σ_b is the undegraded compressive stress.
Phase-field evolution (variational inequality):
∫_Ω [g'(φ) (σ_a(u) : ε(u)) δφ + (G_c / (c₀ l)) δφ + G_c l ∇φ · ∇δφ] dx = 0
When fatigue is enabled, an additional term Fatigue * Gc * (...) appears in the phase-field residual, as implemented in lines 17-21 of solver.py.
Optional Extensions
Fatigue Degradation
For cyclic loading scenarios, PhaseFieldX includes a fatigue extension in src/phasefieldx/Element/Phase_Field_Fracture/fatigue_degradation_functions.py. This introduces a history-dependent degradation factor that evolves with a cumulative fatigue variable α, allowing the simulation of subcritical crack growth under repeated loading cycles.
Energy Monitoring and Post-Processing
Accurate energy tracking is essential for verifying the thermodynamic consistency of fracture simulations. PhaseFieldX provides dedicated utilities in src/phasefieldx/Element/Phase_Field_Fracture/energy.py.
The function compute_total_energies calculates:
- Degraded elastic energy using the current phase-field
- Split components
ψₐ(tensile) andψ_b(compressive) - Total elastic energy
E = degraded_energy + ψ_b
# compute_total_energies (energy.py, lines 13-17)
psi_a_val, psi_b_val = compute_elastic_energy_components(u, Data, comm, dx=dx)
degraded_energy = compute_degraded_elastic_energy(u, phi, Data, comm, dx=dx)
E = degraded_energy + psi_b_val
Additionally, calculate_crack_surface_energy from src/phasefieldx/Element/Phase_Field/energy.py computes the regularized crack surface energy γ, its phase-field component γ_φ, and its gradient component γ_∇φ. The solver writes these values to total.energy at each time step, enabling post-processing of energy release rates and crack resistance curves.
Practical Implementation Example
The following minimal driver script demonstrates how to set up and run a phase-field fracture simulation using the Input class and staggered solver:
# example_driver.py
from phasefieldx.Element.Phase_Field_Fracture.Input import Input
from phasefieldx.Element.Phase_Field_Fracture.solver.solver import solve
from phasefieldx.Mesh.generator import create_mesh # hypothetical helper
from phasefieldx.FunctionSpaces import create_function_spaces # hypothetical helper
# ------------------------------------------------------------------
# 1. Define simulation parameters
# ------------------------------------------------------------------
data = Input(
E=210.0, # Young's modulus [GPa]
nu=0.3, # Poisson ratio
Gc=2.7e-3, # Critical fracture energy [N/mm]
l=0.015, # Length-scale parameter
degradation="isotropic",
split_energy="spectral",
degradation_function="quadratic",
irreversibility="miehe",
fatigue=False,
save_solution_vtu=True,
)
# ------------------------------------------------------------------
# 2. Build mesh and function spaces (replace with your own utilities)
# ------------------------------------------------------------------
msh = create_mesh() # returns dolfinx.mesh
V_u, V_phi = create_function_spaces(msh)
# ------------------------------------------------------------------
# 3. Boundary conditions (simple example)
# ------------------------------------------------------------------
bc_u = [] # list of dolfinx.DirichletBC for displacement
bc_phi = [] # list of DirichletBC for phase field
# ------------------------------------------------------------------
# 4. Run the staggered solver
# ------------------------------------------------------------------
solve(
Data=data,
msh=msh,
final_time=1.0,
V_u=V_u,
V_Φ=V_phi,
bc_list_u=bc_u,
bc_list_phi=bc_phi,
dt=0.01,
)
Key implementation details include the Input class definition in src/phasefieldx/Element/Phase_Field_Fracture/Input.py and the solver entry point in src/phasefieldx/Element/Phase_Field_Fracture/solver/solver.py (lines 29-49).
Summary
- PhaseFieldX implements a staggered finite-element formulation that alternates between mechanical equilibrium and phase-field evolution until convergence.
- The spectral energy split in
split_energy_stress_tangent_functions.pyensures damage only affects tensile strains, preventing unphysical cracking under compression. - Modular degradation functions in
g_degradation_functions.pysupport quadratic, Borden, Alessi, and Sargado models via thedegradation_functionparameter. - The history variable
Henforces irreversibility through the Miehe approach or allows healing when disabled. - Energy monitoring via
compute_total_energiesandcalculate_crack_surface_energyprovides thermodynamic consistency checks and post-processing capabilities.
Frequently Asked Questions
What is the staggered solution algorithm in PhaseFieldX?
The staggered algorithm decouples the displacement and phase-field problems to improve robustness and reduce computational cost per iteration. At each time step, the solver first computes mechanical equilibrium with a fixed damage field, then updates the history variable to enforce irreversibility, and finally solves the phase-field evolution using the new strain history. Convergence is assessed via normalized L²-norms of both fields using eval_error_L2_normalized in solver.py.
How does PhaseFieldX prevent damage under compressive loading?
The library employs a spectral decomposition of the elastic energy tensor, implemented in split_energy_stress_tangent_functions.py. This split separates the strain energy into positive (tensile) and negative (compressive) components. The degradation function g(φ) only multiplies the tensile part ψₐ, while the compressive part ψ_b remains undegraded, ensuring that cracks do not propagate under pure compression.
What degradation function options are available in PhaseFieldX?
PhaseFieldX provides four degradation models selectable via the degradation_function parameter in the Input class: quadratic (standard polynomial), Borden (modified for better crack surface approximation), Alessi, and Sargado. These functions and their derivatives dg are defined in src/phasefieldx/Element/Phase_Field_Fracture/g_degradation_functions.py, allowing users to switch models without modifying the solver logic.
How is the critical fracture energy Gc incorporated into the model?
The critical fracture energy Gc appears in the regularized crack surface energy term computed in src/phasefieldx/Element/Phase_Field/energy.py. The functional form depends on the selected AT1 or AT2 model, scaling the phase-field gradient and the field itself by Gc/(c₀l) and Gc*l/c₀, respectively, where l is the length-scale parameter and c₀ is a model-specific constant. This term drives the evolution of the damage field when the elastic energy release exceeds the fracture resistance.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →