Polycrystals
The whole page as one script
Every block of this page, in order, is scripts/material_laws/12_polycrystals.jl. From a clone of the repository, julia --project=docs -e 'using Pkg; Pkg.instantiate()' once, then julia scripts/material_laws/12_polycrystals.jl, runs it end to end.
A metal is an aggregate of grains, each a single crystal that deforms by slip on its own slip systems, oriented at random or along a texture. Its response follows from the single-crystal law of every grain and from a rule saying how the grains share the macroscopic strain and stress. This page states three such rules for an aggregate of many grains: the uniform strain of Taylor, and the interaction of each grain with a matrix standing for the others, elastic after Kröner and elastoplastic after Berveiller and Zaoui. The uniform-field composites are the uniform rules for a few phases. The example below runs an aggregate.
The grains
Grain CrystalViscoplasticity, whose cube axes are the vectors of its orientation: cubic elasticity, slip on the twelve systems of the FCC or the BCC lattice, a critical resolved shear stress
The Taylor model
Every grain undergoes the macroscopic strain:
It is the uniform-strain composite of the grains. Since a grain then sees nothing of the others, each is integrated on its own: Polycrystal keeps the state of every grain in a vector and calls the local integration of each, which scales to hundreds of grains, where UniformStrain solves all the phases in one system of equations.
To follow a plastic strain imposed on it, a grain has to activate enough slip systems to produce any isochoric strain, five independent ones in general. The macroscopic flow stress in tension is then
A random texture
random_orientations draws orientations uniformly over the rotations. With the Euler angles of TensND,
Grains in a matrix: Kröner
Under the Taylor model a grain cannot strain differently from its neighbors, whatever their resistance. Kröner (1961) lets each grain be a spherical inclusion in a homogeneous matrix that stands for all the others. Grains and matrix share the isotropic elasticity
A grain that slips more than the average is unloaded by the matrix, at the rate of the elastic shear modulus. Plastic strains soon exceed the elastic ones by far, and so the internal stresses grow until every grain slips almost as the average: past the elastoplastic transition, Kröner's model comes back close to Taylor's.
A matrix that flows: Berveiller and Zaoui
The matrix stands for grains that flow too, and accommodates the misfit of a grain plastically as well. Berveiller and Zaoui (1978) give it an isotropic secant elastoplastic behavior: its plastic strain proportional to its stress deviator,
equation (3.15) of the paper:
The interaction in the package
KronerModel and BerveillerZaouiModel write both rules in strains, for grains of any law. With the shared elasticity
Polycrystal solves its six components by the trust-region method of SimpleNonlinearSolve, each iterate integrating every grain on its own at the strain the interaction gives it, itself the root of a trust-region iteration. Since
Both papers assume grains of the isotropic elasticity of the matrix. Grains of cubic elasticity are accepted, their elastic mismatch then entering the eigenstrain, an approximation outside the papers. The secant matrix of Berveiller and Zaoui is meant for proportional loading; otherwise
Steady viscoplastic flow: the tangent model
At large strains the elasticity of the grains is negligible, and the grains can be taken rigid–viscoplastic: PowerLawCrystal slips on each system at the rate
The tangent model of Molinari et al. (1987) lets every grain, a sphere, interact with a homogeneous matrix that behaves as the aggregate linearized at its current stress: through its tangent viscosity, since the stress around the grain departs from the average. In their computations, as here, the matrix is isotropic and incompressible, of viscosity
flow_stress solves it by the trust-region method of SimpleNonlinearSolve on the six components of
What is not covered
The Sachs model, every grain at the macroscopic stress, is the uniform-stress composite of the grains, for a few of them. For an aggregate of nearly rigid–plastic grains it needs the stress of the step to stay below the flow stress of every grain while it is sought, which a strain-driven iteration does not ensure; it is not offered for large aggregates.
The β rule of Cailletaud and Pilvin (1994), Hill's self-consistent elastoplastic scheme with the anisotropic tangent of the aggregate, and the anisotropic matrix of Lebensohn and Tomé (1993) in the tangent model.
Example: a random FCC aggregate
This example pulls an aggregate of copper-like grains of random orientations, under the Taylor model, and recovers the Taylor factor of a random FCC texture.
The aggregate
using MeanFieldHomogenization, Random, Plots, ForwardDiff
τ₀ = 10.0 # critical resolved shear stress, MPa
grain(frame) = CrystalViscoplasticity(; C₁₁ = 168.4e3, C₁₂ = 121.4e3, C₄₄ = 75.4e3,
K = 0.05, n = 10, τ₀, frame)
frames = random_orientations(60; rng = MersenneTwister(2))
aggregate = Polycrystal(grain.(frames))| code | theory |
|---|---|
CrystalViscoplasticity(…; frame) | the law of a grain, its cube axes along frame |
random_orientations(60) | 60 orientations drawn uniformly over the rotations |
Polycrystal(grains) | every grain at the macroscopic strain (Taylor), equal volumes |
Tension
The aggregate is pulled along
r = point_response(aggregate, LoadingPath(range(0, 1; length = 26); ε11 = t -> 1e-2 * t))
plot(r[:ε11] * 100, r[:σ11] / τ₀; lw = 2, label = "Taylor aggregate, 60 grains",
xlabel = "axial strain (%)", ylabel = "σ₁₁ / τ₀", legend = :bottomright)
hline!([3.06]; ls = :dash, label = "Taylor factor, Bishop and Hill (1951)")
The response is elastic until the grains reach their critical stresses, then flows at about
r[:σ11][end] / τ₀3.0879994771047183Inside the aggregate
The state of every grain is kept. The number of slip systems that slipped in each grain over the last step:
active(s_old, s_new) = count(abs.(s_new.y[1:12] - s_old.y[1:12]) .> 1e-8)
counts = active.(grain_states(r.states[end - 1]), grain_states(r.states[end]))
histogram(counts; bins = 0.5:1:12.5, label = "", xlabel = "active slip systems in a grain",
ylabel = "number of grains")
Most grains slip on six or eight systems, a few on four. A rigid–plastic grain following an imposed strain selects five independent systems; the viscous law of the grains makes no such selection, and spreads the slip over every system whose resolved stress reaches its critical value.
Grains in a matrix: Taylor, Kröner, Berveiller–Zaoui
Both interaction models assume grains of the isotropic elasticity of the matrix; the grains below have it (
E_y, ν = 120e3, 0.3 # MPa
C₁₁, C₁₂ = E_y * (1 - ν) / ((1 + ν) * (1 - 2ν)), E_y * ν / ((1 + ν) * (1 - 2ν))
iso_grain(frame) = CrystalViscoplasticity(; C₁₁, C₁₂, C₄₄ = (C₁₁ - C₁₂) / 2, K = 1.0, n = 5, τ₀, frame)
few = random_orientations(8; rng = MersenneTwister(2))
pull = LoadingPath(range(0, 1; length = 7); ε11 = t -> 3e-3 * t)
q = plot(; xlabel = "axial strain (%)", ylabel = "σ₁₁ / τ₀", legend = :bottomright)
for (model, label) in ((TaylorModel(), "Taylor"), (KronerModel(; E = E_y, ν), "Kröner"),
(BerveillerZaouiModel(; E = E_y, ν), "Berveiller–Zaoui"))
rm = point_response(Polycrystal(iso_grain.(few); model), pull)
plot!(q, rm[:ε11] * 100, rm[:σ11] / τ₀; lw = 2, marker = :circle, label)
end
q
Kröner's matrix, elastic, opposes any misfit of a grain with the full elastic shear modulus: past the onset of slip it holds the grains almost to the average strain, and the response stays close to Taylor's. The elastoplastic matrix of Berveiller and Zaoui yields with the grains, lets them deviate, and lowers the flow stress of the aggregate.
Steady flow: Taylor, tangent and Sachs
Rigid–viscoplastic grains of the same random texture, pulled at a constant strain rate, for exponents from linear viscosity to nearly rate-independent slip:
crystals(n) = ViscoplasticPolycrystal([PowerLawCrystal(; γ̇₀ = 1e-3, τ₀, n, frame) for frame in frames])
D = Mandel{Float64}(1e-3, -5e-4, -5e-4, 0, 0, 0) # 1/s, isochoric tension
# Sachs: every grain at the uniaxial stress s whose average axial rate is D₁₁.
function sachs(p)
rate(s) = sum(w * crystal_strain_rate(c, Mandel(2s / 3, -s / 3, -s / 3, zero(s), zero(s), zero(s)))[1] for (c, w) in zip(p.grains, p.weights)) - D[1]
s = 10τ₀
for _ in 1:100
s -= rate(s) / ForwardDiff.derivative(rate, s)
end
return s
end
exponents = [1, 2, 3, 5, 8, 12, 20]
taylor = [von_mises(flow_stress(crystals(n), D; model = TaylorModel()).σ) for n in exponents]
tangent = [von_mises(flow_stress(crystals(n), D).σ) for n in exponents]
lower = [sachs(crystals(n)) for n in exponents]
plot(exponents, [taylor tangent lower] / τ₀; lw = 2, marker = :circle, xscale = :log10,
label = ["Taylor" "tangent (Molinari et al.)" "Sachs"], xlabel = "exponent n",
ylabel = "Σ_eq / τ₀ at D₁₁ = γ̇₀", legend = :topleft)
Under linear viscosity the three differ by the heterogeneity of the grains alone. As
This page was generated using Literate.jl.