Hello, I’m trying to approximate a maximum value of a field, u_sol
, using the p-norm, \int(u_{sol}(x)^pdx)^\frac{1}{p}. I want to be able to take the derivative of the functional so I can eventually use it with optimization (and with stress), which is why I’m using the p-norm as an approximation.
I’ve implemented the p-norm, but I get an unexpected result. I would expect the p-norm of the field to always be larger than the maximum value, but as the p value increases p-norm gets closer to the maximum value. However, I don’t get this behavior from my implementation and I’m not sure what’s going wrong.
So this is a simple example of what I’ve done, I’m using legacy FEniCS 2019.1.0,
from fenics import *
from fenics_adjoint import *
import numpy as np
from ufl import nabla_div
# Define parameters
nelx = 20
nely = 20
nelz = 20
lx = 0.1
ly = 0.1
lz = 0.1
kappa = Constant(20)
# Create a mesh
mesh = BoxMesh.create(
[Point(0.0, 0.0, 0.0), Point(lx, ly, lz)], # define opposing corners
[nelx, nely, nelz], # number of elements in each direction
CellType.Type.hexahedron)
mesh = Mesh(mesh)
# FE function space and functions
V = FunctionSpace(mesh, "CG", 1)
u = TrialFunction(V)
v = TestFunction(V)
u_sol = Function(V) # function for storing the solution
# Bounday condition
class Left(SubDomain):
def inside(self, x, on_boundary):
return near(x[0], 0.)
left = Left()
bc = DirichletBC(V, Constant((0.)), left)
# Define forms
f = Constant((1.0781e3))
L = dot(f, v) * dx
a = inner(kappa*grad(u), grad(v)) * dx
# Solve
A, b = assemble_system(a, L, bc)
solver = KrylovSolver("cg", "ilu")
solver.solve(A, u_sol.vector(), b)
# Calculate pnorm
p = 6
J1 = pow(assemble(pow(u_sol, p)*dx(metadata={'quadrature_degree': 5})), 1/p)
p = 20
J2 = pow(assemble(pow(u_sol, p)*dx(metadata={'quadrature_degree': 5})), 1/p)
p = 40
J3 = pow(assemble(pow(u_sol, p)*dx(metadata={'quadrature_degree': 5})), 1/p)
# Compare with pnorms with max value
print('pn-6 =', float(J1))
print('pn-20 =', float(J2))
print('pn-40 =', float(J3))
print('Max val =', u_sol.vector().max())
The output of this is
pn-6 = 0.07120772774142763
pn-20 = 0.17573760154304024
pn-40 = 0.21576352505332388
Max val = 0.2695257644203194
where the first three values are the p-norm evaluated at p=6, p=20, and p=40 and the last value is the maximum value from u_sol
. So the p-norm is much smaller than the maximum and it’s not until a very large p value, 40, that it starts to get close.