2D Mechanics Problem

Hi,

I’m trying to run a simple 2D problem on fenics based on the 3D example here. Currently, my code works because I’ve set all the z-components for the boundary conditions and traction values to 0. However, I am not sure if this is the best way to go about this problem. Currently, if I change the Dirichlet condition to a 2D vector I get the following:

*** Error:   Unable to create Dirichlet boundary condition.
*** Reason:  Illegal value dimension (2), expecting (3).
*** Where:   This error was encountered inside DirichletBC.cpp.

A similar problem arises if I set the traction force as a 2D vector:

ufl.log.UFLException: Dimension mismatch in dot product.

MWE:

#!/usr/bin/env python3
from fenics import *
from ufl import nabla_div
from ufl import nabla_grad
import numpy as np
import os
import meshio

mesh_file = './mesh' #Mesh folder name
model_name = 'Half_cy' #Mesh model to load

msh = meshio.read(mesh_file+'/'+model_name+'.msh')

#read mesh
meshio.write(mesh_file+'/'+model_name+'.xdmf', meshio.Mesh(points=msh.points, cells={"triangle":msh.cells["triangle"]}))

#mesh function (mf) to pick the boundaries (Pick up line)
meshio.write(mesh_file+'/mf'+model_name+'.xdmf', meshio.Mesh(points=msh.points, cells={"line":msh.cells["line"]}, \
    cell_data={"line":{"name_to_read":msh.cell_data["line"]["gmsh:physical"]}}))

#cell function (cf) to pick out the different regions (Pick up surface)
meshio.write(mesh_file+'/cf'+model_name+'.xdmf', meshio.Mesh(points=msh.points, cells={"triangle":msh.cells["triangle"]}, \
    cell_data={"triangle":{"name_to_read":msh.cell_data["triangle"]["gmsh:physical"]}}))

mesh = Mesh()
with XDMFFile(mesh_file+'/'+model_name+'.xdmf') as infile:
    infile.read(mesh) #Feeds data from xdmf to mesh variable

mvc = MeshValueCollection("size_t", mesh, 1) #Container for mesh values 
with XDMFFile(mesh_file+'/mf'+model_name+'.xdmf') as infile:
    infile.read(mvc, "name_to_read") #Feeds boundary data to mvc 

mvc2 = MeshValueCollection("size_t", mesh, 1) #Container for mesh values
with XDMFFile(mesh_file+'/cf'+model_name+'.xdmf') as infile:
    infile.read(mvc2, "name_to_read") #Feeds region data into mvc2

boundaries = MeshFunction("size_t", mesh, mvc) #Contains information regarding the boundaries
regions = MeshFunction("size_t", mesh, mvc2) #Constains information regarding the regions

V = VectorFunctionSpace(mesh, 'P', 1) #Vector function space for the equations

L = 1
W = 0.2
mu = 1
rho = 1
delta = W/L
gamma = 0.4*delta**2
beta = 1.25
lambda_ = beta
g = gamma

#Based on gmsh Line and sufurce marker 
Fixed_boundary_marker = 1
Traction_boundary_marker = 2
Region_marker = 3

boundary_conditions = {
        1 : {"Dirichlet" : Constant((0, 0, 0))} #Should it be 3D?
    }

bcs = []
for i in boundary_conditions:
    if "Dirichlet" in boundary_conditions[i]:
        #Here V.sub(1) refers to pressure while 0 refers to velocity
        bc = DirichletBC(V, boundary_conditions[i]["Dirichlet"], boundaries, i) 
        bcs.append(bc)

#Strain
def epsilon(u):
    return 0.5*(nabla_grad(u) + nabla_grad(u).T)
    #return sym(nabla_grad(u))

#Stress
def sigma(u):
    return lambda_*nabla_div(u)*Identity(d) + 2*mu*epsilon(u)

# Define variational problem
u = TrialFunction(V)  
d = u.geometric_dimension()  
v = TestFunction(V) 
f = Constant((0, rho*g, 0.0))   
T = Constant((0, 0, 0.0)) # Should it be 3D???
a = inner(sigma(u), epsilon(v))*dx
L = dot(f, v)*dx + dot(T, v)*ds

# Compute solution
u = Function(V)
solve(a == L, u, bcs)

# Compute magnitude of displacement
u_magnitude = sqrt(dot(u, u))
u_magnitude = project(u_magnitude, V)

print('min u: '+str(u_magnitude.vector()[:].min()))
print('max u: '+str(u_magnitude.vector()[:].max()))

The gmsh geo file:

//+
Point(1) = {0, 0, 0, 1.0};
//+
Point(2) = {0.5, 0, 0, 1.0};
//+
Point(3) = {1.5, 0, 0, 1.0};
//+
Point(4) = {2.0, 0, 0, 1.0};
//+
Point(5) = {1.0, 0, 0, 1.0};
//+
Circle(1) = {3, 5, 2};
//+
Circle(2) = {4, 5, 1};
//+
Line(3) = {1, 2};
//+
Line(4) = {3, 4};
//+
Curve Loop(1) = {1, -3, -2, -4};
//+
Plane Surface(1) = {1};
//+
Physical Curve("1") = {3};
//+
Physical Curve("2") = {4};
//+
Physical Surface("3") = {1};

Worth noting that the gmsh version is: 4.4.1

Thanks

1 Like

As your mesh is 2D, you should remove the z-coordinate of your mesh before loading it into dolfin. See

You could remove the z-corodinates from your points input here, which will make the problem 2D, and all vectors in dolfin should be 2D.

2 Likes

Thanks very much dokken! :slight_smile:

For anyone who has a similar problem, this is what I edited:

msh = meshio.read(mesh_file+'/'+model_name+'.msh')
TwoDpoints= msh.points
TwoDpoints = np.delete(TwoDpoints, obj=2, axis=1) # Removes the 2D points'

meshio.write(mesh_file+'/'+model_name+'.xdmf', meshio.Mesh(points=TwoDpoints, cells={"triangle":msh.cells["triangle"]}))

2 Likes

Hey Kart i was having the same problem, please can u tell me if ur solution looks like this? i used your geo file and changed all constants to 2D like this —>((0,0))

Compute solution

u = Function(V)
solve(a == L, u, bcs)
vtkfile = File(“mypc/file.pvd”)
vtkfile << u

this is the plot of “u”

Hi Jose Alejandro Pena,

I used a slightly more refined mesh though.

The solution I got for stress is as follows:

For strain is the following: