#add code here
from dolfin import *
import fenics as fe
import matplotlib.pyplot as plt
import numpy as np
from mshr import *
#import ufl
fe.set_log_level(13)
# --------------------
# Functions and classes
# --------------------
def bottom(x, on_boundary):
return (on_boundary and fe.near(x[1], 0.0))
# Strain function
def epsilon(u):
return 0.5*(fe.grad(u) + fe.grad(u).T)
# Stress function
def sigma(u):
return lmbda*fe.div(u)*fe.Identity(2) + 2*mu*epsilon(u)
# --------------------
# Parameters
# --------------------
# Lame's constants
#lmbda = 1.25
#mu = 20
E = 20.0e6
mu = 0.5*E
rho_0 = 200.0
l_x, l_y = 5.0, 5.0 # Domain dimensions
n_x, n_y = 500, 500 # Number of elements
# Load
g_int = 1.0e5
b_int = -10.0
# --------------------
# Geometry
# --------------------
#mesh_quad = fe.UnitSquareMesh.create(n_x, n_y, fe.CellType.Type.quadrilateral)
domain = Rectangle(Point(0., 0.), Point(5, 5)) - Circle(Point(2.5, 2.5), 1.8, 100)
mesh = generate_mesh(domain, 500)
fe.plot(mesh)
plt.show()
# Definition of Neumann condition domain
boundaries = fe.MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
top = fe.AutoSubDomain(lambda x: fe.near(x[1], 5.0))
top.mark(boundaries, 1)
ds = fe.ds(subdomain_data=boundaries)
# --------------------
# Function spaces
# --------------------
V = fe.VectorFunctionSpace(mesh, "CG", 1)
u_tr = fe.TrialFunction(V)
u_test = fe.TestFunction(V)
u = fe.Function(V)
g = fe.Constant((0.0, g_int))
b = fe.Constant((0.0, b_int))
N = fe.Constant((0.0, 1.0))
aa, bb, cc, dd, ee = 0.5*mu, 0.0, 0.0, mu, -1.5*mu
# --------------------
# Boundary conditions
# --------------------
bc = fe.DirichletBC(V, fe.Constant((0.0, 0.0)), bottom)
# --------------------
# Weak form
# --------------------
I = fe.Identity(2)
F = I + fe.grad(u) # Deformation gradient
C = F.T*F # Right Cauchy-Green tensor
J = fe.det(F) # Determinant of deformation fradient
#psi = (aa*fe.tr(C) + bb*fe.tr(ufl.cofac(C)) + cc*J**2 - dd*fe.ln(J))*fe.dx - fe.dot(b, u)*fe.dx + fe.inner(f, u)*ds(1)
#n = fe.dot(ufl.cofac(F), N)
#surface_def = fe.sqrt(fe.inner(n, n))
psi = (aa*fe.inner(F, F) + ee - dd*fe.ln(J))*fe.dx - rho_0*J*fe.dot(b, u)*fe.dx +fe.inner(g,u)*ds(1) #+ surface_def*fe.inner(g, u)*ds(1)
# --------------------
# Solver
# --------------------
Form = fe.derivative(psi, u, u_test)
Jac = fe.derivative(Form, u, u_tr)
problem = fe.NonlinearVariationalProblem(Form, u, bc, Jac)
solver = fe.NonlinearVariationalSolver(problem)
prm = solver.parameters
#prm["newton_solver"]["error_on_convergence"] = False
#fe.solve(Form == 0, u, bc, J=Jac, solver_parameters={"error_on_convergence": False})
solver.solve()
print(np.amax(u.vector()[:]))
# --------------------
# Post-process
# --------------------
fe.plot(u,mode='displacement')
plt.show()
Thank you Dokken, this should be correct.
I am referring to this
n = fe.dot(ufl.cofac(F), N)
surface_def = fe.sqrt(fe.inner(n, n))