Adaptive solver with multiple unknowns


208
views
0
6 months ago by
Hi everyone,

I want to use an adaptive solver to solve a system of coupled equations.
To get the hang of the adaptive solver, I started with a very simple example in one unknown, based on this old example.
This code works perfectly fine and solves the equation in 8 successive mesh refinement steps:
from fenics import *
from dolfin import *

tol = DOLFIN_EPS

# Create mesh and define function space
mesh = UnitSquareMesh(8, 8)

# classes to define boundaries on the geometry
class LeftBoundary(SubDomain):
  def inside(self, x, on_boundary):
  return on_boundary and near(x[0], 0., tol)

# Initialize subdomain (boundary) classes
left = LeftBoundary()

# build the function space
Element = FiniteElement('Lagrange', mesh.ufl_cell(), 1)
Space= FunctionSpace(mesh, Element)

# Dirichlet boundary conditions
bc0 = DirichletBC(Space, 1., left)

# Define variational problem
f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2)) / 0.02)", degree=1)
g = Expression("sin(5*x[0])", degree=1)
u = TrialFunction(Space)
v = TestFunction(Space)
equation = -inner(grad(u), grad(v))*dx + f*v*dx + g*v*ds

# Define problem, goal and solve
sol = Function(Space)
R = action(equation, sol)
DR = derivative(R, sol)
M = sol*dx
problem = NonlinearVariationalProblem(R, sol, bc0, DR)
solver_tol = 1.e-5
solver = AdaptiveNonlinearVariationalSolver(problem, M)
solver.parameters["error_control"]["dual_variational_solver"]["linear_solver"] = "cg"
solver.parameters["error_control"]["dual_variational_solver"]["symmetric"] = True
solver.solve(solver_tol)

solver.summary()
​

However, once I turn the example into a problem with two unknowns (I simply solve the same equation twice) it doesn't work anymore.

# build the function space
Element = FiniteElement('Lagrange', mesh.ufl_cell(), 1)   
CompleteElement = MixedElement([Element, Element])
Space= FunctionSpace(mesh, CompleteElement)

# boundary conditions
bc0 = DirichletBC(Space.sub(0), 1., left)
bc1 = DirichletBC(Space.sub(1), 1., left)
   
# Define variational problem
u, p = TrialFunction(Space)
v, w = TestFunction(Space)
equation = - inner(grad(u), grad(v))*dx + f*v*dx + g*v*ds - inner(grad(p), grad(w))*dx + f*w*dx + g*w*ds

# Define function for the solution
sol = Function(Space)
R = action(equation, sol)
DR = derivative(R, sol)

# Define problem and goal functional (quantity of interest)
M = sol.sub(0)*dx
problem = NonlinearVariationalProblem(R, sol, [bc0, bc1], DR)

solver = AdaptiveNonlinearVariationalSolver(problem, M)
solver.parameters["error_control"]["dual_variational_solver"]["linear_solver"] = "cg"
solver.parameters["error_control"]["dual_variational_solver"]["symmetric"] = True
solver.solve(solver_tol)

solver.summary()


The adaptive solver gives a perfect zero error estimate in adaptive iteration 0 and hence never refines the mesh.
Am I doing something wrong or what can I do to make the adaptive solver work with multiple unknowns?

I am running Fenics 2016.1.0 on Debian.

Thank you for your answers,
dvlaethe

Community: FEniCS Project

1 Answer


2
5 months ago by
So I finally found the solution.
The goal functional should be written as:
M = sol[0]*dx​
instead of:
M = sol.sub(0)*dx​
Source: https://github.com/FEniCS/dolfin/blob/master/demo/undocumented/auto-adaptive-navier-stokes/python/demo_auto-adaptive-navier-stokes.py
Please login to add an answer/comment or follow this question.

Similar posts:
Search »