Hello,
I am trying to compute the principal strains and their associated principal direction in the case of linear elasticity. I noticed the SLEPcEigenSolver which can compute the eigenvalues and eigenvectors of a given matrix.
Could it be used for this purpose?
Here is a MWE for the usage of the solver in the case of a 2D rectangle under traction, however I think I am computing the eigenvalues and eigenvectors of the stiffness matrix.
Is there a way to pass the strain tensor instead?
Thanks in advance
from dolfin import *
import mshr as mr
# --- Mesh
L, H = 1, 0.1
nel = 75
geom = mr.Rectangle(Point(0, 0), Point(L, H))
mesh = mr.generate_mesh(geom, nel)
ndim = mesh.topology().dim()
# --- Material Parameter
E = Constant(70e3)
nu = Constant(0.3)
lmbda = E*nu/(1+nu)/(1-2*nu)
mu = E/2./(1+nu)
k = lmbda + mu*2/3.
# --- Function Spaces
Vs = FunctionSpace(mesh, 'DG', 0)
V = VectorElement("Lagrange", mesh.ufl_cell(), 1)
V_u = FunctionSpace(mesh, V)
u = Function(V_u)
du = TrialFunction(V_u)
v = TestFunction(V_u)
u.rename('u', 'u')
S3 = TensorFunctionSpace(mesh, 'DG', 0)
Eps = Function(S3)
Eps.rename('E', 'E')
# ---Boundaries
class Left(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], 0.0)
left = Left()
class Right(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], L)
right = Right()
def NodeL(x):
return near(x[0], 0) and near(x[1], 0.)
# ---Measures
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
left.mark(boundaries, 1)
right.mark(boundaries, 3)
# ---Displacement BC
#u_R = Expression("t*(0.5-x[1]/H)", H=H, t=0.05, degree=1)
u_R = Expression("t", t=0.05, degree=0)
bcu_l = DirichletBC(V_u.sub(0), Constant(0.), boundaries, 1)
bcu_r = DirichletBC(V_u.sub(0), u_R, boundaries, 3)
bcu_L = DirichletBC(V_u.sub(1), Constant(0.), NodeL, method = 'pointwise')
bcu = [bcu_r, bcu_l, bcu_L]
# ---Definitions
def eps(u):
return sym(grad(u))
def sigma(u):
return 2. * mu * (eps(u)) + lmbda * tr(eps(u)) * Identity(2)
# --- Eigenproblem
k_form = inner(sigma(v), eps(du)) *dx
K = PETScMatrix()
assemble_system(k_form, l_form, bcu, A_tensor=K)
eigensolver = SLEPcEigenSolver(K)
eigensolver.parameters['problem_type'] = 'gen_hermitian'
eigensolver.parameters['spectral_transform'] = 'shift-and-invert'
eigensolver.parameters['spectral_shift'] = 1e-12
N_eig = 2
eigensolver.solve(N_eig)
eI_, c, nI_, cx = eigensolver.get_eigenpair(0)
eI = Function(Vs, name = 'evI')
eI.vector()[:] = eI_
nI = Function(V_u, name = "nI")
nI.vector()[:] = nI_
eII_, c, nII_, cx = eigensolver.get_eigenpair(1)
eII = Function(Vs, name = 'evII')
eII.vector()[:] = eII_
nII = Function(V_u, name = "nII")
nII.vector()[:] = nII_
File('Linear_elasticity/' + 'evI.pvd') << eI
File('Linear_elasticity/' + 'evII.pvd') << eII
File('Linear_elasticity/' + 'nI.pvd') << nI
File('Linear_elasticity/' + 'nII.pvd') << nII