Hello everyone, I’m trying to solve a very simple problem from linear elasticity, where a square mesh of 2x2 elements has a different shear modulus at each element (the shear modulus is piecewise constant, DG degree 0). Then apply a shear to the mesh, and compute the resulting strain.
My problem is that, even though I set the elements to CG with degree 1, I obtain what seems to be the result of degree 2, i.e., instead of linear it looks quadratic. You can appreciate in the attached image the strain plotted (in Paraview) along the diagonal of the mesh. In brown is the linear result I expected, and in orange, it is shown the result from Fenics (quadratic-like).
I would like to know how can I use linear interpolation, and why Fenics is still using quadratic. You can see my code bellow.
Thanks in advance.
The code to reproduce this is the following:
from __future__ import print_function
from dolfin import *
import numpy as np
import matplotlib.tri as tri
from mshr import *
import matplotlib.pyplot as plt
mesh = RectangleMesh.create( [Point(0., 0.),Point(2, 2)], [2,2], CellType.Type.quadrilateral)
nu = Constant(0.3)
# piecewise constant shear modulus
V = FunctionSpace(mesh, "DG", 0)
G = Function(V)
G.vector().vec().setValueLocal(0, 1)
G.vector().vec().setValueLocal(1, 6)
G.vector().vec().setValueLocal(2, 0.3)
G.vector().vec().setValueLocal(3, 4)
# isotropic stifness tensor
a = 2*G/(1-nu)
C = as_matrix([[a,a*nu,0],[a*nu,a,0],[0,0,G]])
def eps(v):
return sym(grad(v))
def strain2voigt(e):
"""e is a 2nd-order tensor, returns its Voigt vectorial representation"""
return as_vector([e[0,0],e[1,1],2*e[0,1]])
def voigt2stress(s):
"""s is a stress-like vector (no 2 factor on last component)returns its tensorial representation"""
return as_tensor([[s[0],s[2]],[s[2],s[1]]])
def sigma(v):
return voigt2stress(dot(C,strain2voigt(eps(v))))
# use linear shape functions
fem_order = 1
# define problem
f = Constant((0,0))
V = VectorFunctionSpace(mesh, 'CG', fem_order)
du = TrialFunction(V)
u_ = TestFunction(V)
a = inner(sigma(du), eps(u_))*dx
l = inner(f, u_)*dx
# apply a shear deformation of eps_xy=0.25 to the whole boundadry
eps_xy = 0.25
def all_boundary(x, on_boundary): return on_boundary
inflow_profile = ('{}*x[1]'.format(eps_xy), '{}*x[0]'.format(eps_xy))
dirichelt_shear_BCs = DirichletBC(V, Expression(inflow_profile, degree=2), all_boundary)
# solve problem
u = Function(V, name="Displacement")
solve(a == l, u, dirichelt_shear_BCs, form_compiler_parameters={"optimize": True})
file_results = XDMFFile("./output.xdmf")
file_results.parameters["flush_output"] = True
file_results.parameters["functions_share_mesh"] = True
file_results.write(u, 0.)
# compute strain
T = TensorFunctionSpace(mesh, 'CG', fem_order)
strain = project(eps(u), T)
[e11, e12, e21, e22] = strain.split(True)
S = project(e12, FunctionSpace(mesh, 'CG', fem_order))
file_results.write(S, 0.)