I am trying to solve a single truss element problem defined by two points A and B. In each point I have two DoF i.e. u1,u2,u3,u4.
I tried to use the tutorial for 2d beams see and an old thread `but I could not solve my problem defining the correct mesh and boundary condition.
So far I have this code:
import numpy as np
from dolfin import *
# Material variables
E = Constant(1e5)
nu = Constant(0.3)
mu = E/2/(1+nu)
lmbda = E*nu/(1+nu)/(1-2*nu)
# Define Single Truss mesh from point A to point B with DoF 2 in each point
#
#
mesh = Mesh(mesh)
V = VectorFunctionSpace(mesh, 'Lagrange', degree=1)
# Define Dirichlet boundary i.e. left point A is fixed
#
#
def eps(v):
return sym(grad(v))
def sigma(u):
d = u.geometric_dimension()
I = Identity(d)
return lmbda * tr(eps(u)) * I + 2 * mu * eps(u)
# Solution variables
dx = Measure("dx")
du = TrialFunction(V)
U = Function(V)
u = U.vector()
u_ = TestFunction(V)
d = U.geometric_dimension()
I = Identity(d)
f = Constant((0, 0))
# Assembly system
a = inner(sigma(du), eps(u_)) * dx
L = inner(f, u_) * dx
K, f_vec = assemble_system(a, L, bc)
# External force on point B
f_vec[3] = 0
f_vec[4] = -1
# Solve system
solve(K, u, f_vec)
This does not answer my question. The problem I have is the definition of a truss element. For example I just need a mesh which consists of one Element and both nodes have DoF 2 i.e. displacemnt in direction x and y. Do I really need an external software?
Unfortunatly no. I am searching for a method to define something like:
The blue line is one Element defined by two points. The left side is fixed by Dirichlet boundary. On the right point a force is acting in the y-direction. Therefore I would expect a displacement vector [u1_x, u1_y, u2_x, u2_y]. Where u1 is the displacement of the left point and u2 of the right point.
The error message is: Can’t add expressions with different shapes. I can resolve this issue by just returning nabla_grad(v). I guess this has something to do with taking the transpose of a vector and adding them.
If I understood correctly you just want to solve a simple truss problem. The axial strain measure must therefore be computed from the tangential part of the displacement field in the local frame of a truss member \epsilon = d(\underline{u}\cdot\underline{t})/ds which is scalar. You cannot consider the full symmetrized gradient of the displacement (this is for 2D/3D solids).
You can adapt this demo on 3D beam elements which involves all 6 internal forces of a beam (axial force, 2 bending moments, 2 shear forces and one torsion moment). You can then adapt it ignoring rotations and all forces/strains except the axial force/strain.
import numpy as np
from dolfin import *
# Material variables
L = 2; W = 0.0000001
E = Constant(3e5)
# Define Single Truss mesh from point A to point B with DoF 2 in each point
mesh = IntervalMesh(1, 0, L)
VE = VectorElement("CG", interval, 1, dim=2)
V = FunctionSpace(mesh, VE)
mesh = Mesh(mesh)
# Define Dirichlet boundary
tol = 1E-14
def clamped_boundary(x, on_boundary):
return on_boundary and x[0] < tol
bc = DirichletBC(V, Constant((0, 0)), clamped_boundary)
def eps(v):
return nabla_grad(v)
def sig(u):
return E * eps(u)
# Solution variables
dx = Measure("dx")
du = TrialFunction(V)
U = Function(V)
u = U.vector()
v = TestFunction(V)
f = Constant((0, 0))
T = Constant((0, -10))
a = inner(sig(du), eps(v))*dx
L = dot(f, v)*dx + dot(T, v)*ds
# Assembly system
K, f_vec = assemble_system(a, L, bc)
print(np.array(f_vec))
# Solve system
solve(K, u, f_vec)
u = np.array(u)
print(u)