Defining non-linear constitutive laws

Hello,

I was wondering if there is a way to define non-linear elastic constants in FEniCS. I am looking for constitutive relations in the form of

\sigma_{11} = E(\epsilon_{11})*\epsilon_{11}

where E(\epsilon_{11}) is some non-linear function of \epsilon_{11}.

Specifically, I am trying to study some contact problems where I want to insert a fictitious material with high compressive modulus but small/negligible tensile modulus, in order to simulate the contacts.

I was wondering if this is possible. Thank you for your attention.

You can do this by defining E in terms of the solution, using UFL. In particular, the conditional function can be used to switch between different values under different conditions. Take a look at the following example of 1D axial deformation with different stiffness values in tension and compression:

from dolfin import *
N = 128
mesh = UnitIntervalMesh(N)
x = SpatialCoordinate(mesh)
V = VectorFunctionSpace(mesh,"CG",1)

# Displacement:
u = Function(V)

# Strain:
eps = sym(grad(u))

# Define E to switch stiffness depending on sign of
# the axial strain, using a UFL `conditional`:
E_comp = Constant(1e2)
E_tens = Constant(1)
E = conditional(lt(eps[0,0],0),E_comp,E_tens)

# Simplified axial Hooke's law:
sigma = E*eps

# External forcing pushes toward the center of the
# interval.
f = as_vector([sin(2*pi*x[0]),])

# Energy:
energy = (0.5*inner(sigma,eps) - dot(f,u))*dx

# Solve with homogeneous Dirichlet boundary conditions:
solve(derivative(energy,u)==0,u,
      bcs=[DirichletBC(V,Constant((0,)),"on_boundary"),])

# Plot results:
from matplotlib import pyplot as plt

# The middle of the interval is under compression, with
# small negative strains, while the edges are in tension
# with larger positive strains, as expected from the
# given sinusoidal body force and nonlinear $E$.
plot(u[0])
plt.show()
2 Likes

Hi David,

do you know whether it is possible to define multiple conditions (for dolfinx) such as c < a < b
(not just a < b). I cannot find the answer in the user manual https://fenics.readthedocs.io/_/downloads/ufl/en/latest/pdf/ (page 23).

Apparently, the following doesn’t work

ufl.conditional(lt(a,b) and gt(a,c), true_value, false_value) 
#or
ufl.conditional(np.logical_and(np.less(a,b), np.greater(a,c)), true_value, false_value) 

and raises the error:

UFL conditions cannot be evaluated as bool in a Python context

It’s a little bit clumsy, but you can nest several conditionals, e.g.,

conditional(lt(a,b),
            conditional(gt(a,c),a_between_c_and_b,a_leq_c),
            a_geq_b)
1 Like