如何解决 Fenics Example ft06_elasticity.py 中的名称 'nabla_div' is not defined 错误?
How to work around the name 'nabla_div' is not defined error in Fenics Example ft06_elasticity.py?
我在 Ubuntu 18.04 上使用 Conda 安装了 Fenics,在 运行 他们的 ft06_elasticity.py 示例中收到以下错误。
我试图在文档中找到解决方案或变通方法,但我什至无法在任何地方找到 nabla_div() 函数描述。
Fenics documentation 声明如下:
nabla_grad
The gradient and divergence operators now have a prefix nabla_. This
is strictly not necessary in the present problem, but recommended in
general for vector PDEs arising from continuum mechanics, if you
interpret ∇ as a vector in the PDE notation; see the box about
nabla_grad in the section Variational formulation.
"""
FEniCS tutorial demo program: Linear elastic problem.
-div(sigma(u)) = f
The model is used to simulate an elastic beam clamped at
its left end and deformed under its own weight.
"""
from __future__ import print_function
from fenics import *
# Scaled variables
L = 1; W = 0.2
mu = 1
rho = 1
delta = W/L
gamma = 0.4*delta**2
beta = 1.25
lambda_ = beta
g = gamma
# Create mesh and define function space
mesh = BoxMesh(Point(0, 0, 0), Point(L, W, W), 10, 3, 3)
V = VectorFunctionSpace(mesh, 'P', 1)
# Define boundary condition
tol = 1E-14
def clamped_boundary(x, on_boundary):
return on_boundary and x[0] < tol
bc = DirichletBC(V, Constant((0, 0, 0)), clamped_boundary)
# Define strain and stress
def epsilon(u):
return 0.5*(nabla_grad(u) + nabla_grad(u).T)
#return sym(nabla_grad(u))
def sigma(u):
return lambda_*nabla_div(u)*Identity(d) + 2*mu*epsilon(u)
# Define variational problem
u = TrialFunction(V)
d = u.geometric_dimension() # space dimension
v = TestFunction(V)
f = Constant((0, 0, -rho*g))
T = Constant((0, 0, 0))
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, bc)
# Plot solution
plot(u, title='Displacement', mode='displacement')
# Plot stress
s = sigma(u) - (1./3)*tr(sigma(u))*Identity(d) # deviatoric stress
von_Mises = sqrt(3./2*inner(s, s))
V = FunctionSpace(mesh, 'P', 1)
von_Mises = project(von_Mises, V)
plot(von_Mises, title='Stress intensity')
# Compute magnitude of displacement
u_magnitude = sqrt(dot(u, u))
u_magnitude = project(u_magnitude, V)
plot(u_magnitude, 'Displacement magnitude')
print('min/max u:',
u_magnitude.vector().array().min(),
u_magnitude.vector().array().max())
# Save solution to file in VTK format
File('elasticity/displacement.pvd') << u
File('elasticity/von_mises.pvd') << von_Mises
File('elasticity/magnitude.pvd') << u_magnitude
# Hold plot
interactive()
Traceback (most recent call last):
File "fenics_ft06_elasticity.py", line 48, in <module>
a = inner(sigma(u), epsilon(v))*dx
File "fenics_ft06_elasticity.py", line 40, in sigma
return lambda_*nabla_div(u)*Identity(d) + 2*mu*epsilon(u)
NameError: name 'nabla_div' is not defined
我发现将 'nabla_div(u)' 替换为 'div(u)' 可以解决该错误。但是,它确实直接导致了下一个错误:
Traceback (most recent call last):
File "fenics_ft06_elasticity.py", line 56, in <module>
plot(u, title='Displacement', mode='displacement')
File "/home/ron/miniconda3/envs/fenicsproject/lib/python3.7/site-packages/dolfin/common/plotting.py", line 438, in plot
return _plot_matplotlib(object, mesh, kwargs)
File "/home/ron/miniconda3/envs/fenicsproject/lib/python3.7/site-packages/dolfin/common/plotting.py", line 282, in _plot_matplotlib
ax.set_aspect('equal')
File "/home/ron/miniconda3/envs/fenicsproject/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 1281, in set_aspect
'It is not currently possible to manually set the aspect '
NotImplementedError: It is not currently possible to manually set the aspect on 3D axes
只需将这两行添加到代码的开头即可使用 nabla_grad 和 nabla_div:
from ufl import nabla_grad
from ufl import nabla_div
我在 Ubuntu 18.04 上使用 Conda 安装了 Fenics,在 运行 他们的 ft06_elasticity.py 示例中收到以下错误。
我试图在文档中找到解决方案或变通方法,但我什至无法在任何地方找到 nabla_div() 函数描述。
Fenics documentation 声明如下:
nabla_grad
The gradient and divergence operators now have a prefix nabla_. This is strictly not necessary in the present problem, but recommended in general for vector PDEs arising from continuum mechanics, if you interpret ∇ as a vector in the PDE notation; see the box about nabla_grad in the section Variational formulation.
"""
FEniCS tutorial demo program: Linear elastic problem.
-div(sigma(u)) = f
The model is used to simulate an elastic beam clamped at
its left end and deformed under its own weight.
"""
from __future__ import print_function
from fenics import *
# Scaled variables
L = 1; W = 0.2
mu = 1
rho = 1
delta = W/L
gamma = 0.4*delta**2
beta = 1.25
lambda_ = beta
g = gamma
# Create mesh and define function space
mesh = BoxMesh(Point(0, 0, 0), Point(L, W, W), 10, 3, 3)
V = VectorFunctionSpace(mesh, 'P', 1)
# Define boundary condition
tol = 1E-14
def clamped_boundary(x, on_boundary):
return on_boundary and x[0] < tol
bc = DirichletBC(V, Constant((0, 0, 0)), clamped_boundary)
# Define strain and stress
def epsilon(u):
return 0.5*(nabla_grad(u) + nabla_grad(u).T)
#return sym(nabla_grad(u))
def sigma(u):
return lambda_*nabla_div(u)*Identity(d) + 2*mu*epsilon(u)
# Define variational problem
u = TrialFunction(V)
d = u.geometric_dimension() # space dimension
v = TestFunction(V)
f = Constant((0, 0, -rho*g))
T = Constant((0, 0, 0))
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, bc)
# Plot solution
plot(u, title='Displacement', mode='displacement')
# Plot stress
s = sigma(u) - (1./3)*tr(sigma(u))*Identity(d) # deviatoric stress
von_Mises = sqrt(3./2*inner(s, s))
V = FunctionSpace(mesh, 'P', 1)
von_Mises = project(von_Mises, V)
plot(von_Mises, title='Stress intensity')
# Compute magnitude of displacement
u_magnitude = sqrt(dot(u, u))
u_magnitude = project(u_magnitude, V)
plot(u_magnitude, 'Displacement magnitude')
print('min/max u:',
u_magnitude.vector().array().min(),
u_magnitude.vector().array().max())
# Save solution to file in VTK format
File('elasticity/displacement.pvd') << u
File('elasticity/von_mises.pvd') << von_Mises
File('elasticity/magnitude.pvd') << u_magnitude
# Hold plot
interactive()
Traceback (most recent call last):
File "fenics_ft06_elasticity.py", line 48, in <module>
a = inner(sigma(u), epsilon(v))*dx
File "fenics_ft06_elasticity.py", line 40, in sigma
return lambda_*nabla_div(u)*Identity(d) + 2*mu*epsilon(u)
NameError: name 'nabla_div' is not defined
我发现将 'nabla_div(u)' 替换为 'div(u)' 可以解决该错误。但是,它确实直接导致了下一个错误:
Traceback (most recent call last):
File "fenics_ft06_elasticity.py", line 56, in <module>
plot(u, title='Displacement', mode='displacement')
File "/home/ron/miniconda3/envs/fenicsproject/lib/python3.7/site-packages/dolfin/common/plotting.py", line 438, in plot
return _plot_matplotlib(object, mesh, kwargs)
File "/home/ron/miniconda3/envs/fenicsproject/lib/python3.7/site-packages/dolfin/common/plotting.py", line 282, in _plot_matplotlib
ax.set_aspect('equal')
File "/home/ron/miniconda3/envs/fenicsproject/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 1281, in set_aspect
'It is not currently possible to manually set the aspect '
NotImplementedError: It is not currently possible to manually set the aspect on 3D axes
只需将这两行添加到代码的开头即可使用 nabla_grad 和 nabla_div:
from ufl import nabla_grad
from ufl import nabla_div