I have a problem which involves nonlinear Neumann boundary condition q(u,k) controlled by a parameter k. I want to solve the system and find k for which the integral at the boundary reach a specific value A. I want to add the equation q(u,k)*ds - A = 0
to the system and k as an additional dof. Is it possible to do so?
Following is an example of the problem for a simple Poisson equation on a square. Changing k will result in monotonically varying values of the flux between 0 and 1. How can I adjust the code so it solves for k to get specified flux in addition to the dofs of uh
?
import ufl
import numpy as np
from mpi4py import MPI
from dolfinx import mesh, fem, default_scalar_type
from dolfinx.fem.petsc import NonlinearProblem
from dolfinx.nls.petsc import NewtonSolver
def q(u,k):
return k*u**2
domain = mesh.create_unit_square(MPI.COMM_WORLD, 10, 10)
V = fem.functionspace(domain, ("Lagrange", 1))
u_D = fem.Function(V)
u_D.x.array[:] = 1
def left_bnd(x):
return np.isclose(x[0], 0)
def right_bnd(x):
return np.isclose(x[0], 1)
fdim = domain.topology.dim - 1
left_boundary_facets = mesh.locate_entities_boundary(domain, fdim, left_bnd)
left_dofs = fem.locate_dofs_topological(V, fdim, left_boundary_facets)
bcs = [fem.dirichletbc(default_scalar_type(1), left_dofs, V)]
facets = mesh.locate_entities(domain, fdim, right_bnd)
facet_markers = np.full_like(facets, 0)
facet_tag = mesh.meshtags(domain, fdim, facets, facet_markers)
ds = ufl.Measure("ds", domain=domain, subdomain_data=facet_tag)
k = 10
uh = fem.Function(V)
v = ufl.TestFunction(V)
F = ufl.dot(ufl.grad(uh), ufl.grad(v)) * ufl.dx + v*q(uh,k)*ds(0)
problem = NonlinearProblem(F, uh, bcs=bcs)
solver = NewtonSolver(MPI.COMM_WORLD, problem)
idx, converged = solver.solve(uh)
flux = fem.assemble_scalar(fem.form(q(uh,k) * ds(0)))
print(flux)