First thing, I’m using FEniCS 2019.1.0. In the MWE pasted below, I initialize a function phi_n by projecting the right-hand side of the equation
onto a function space, V. Then I initialize a function mu_n by determining the representation of
in the space V - that is to say, I use L2 projection to get a finite-dimensional approximation to the above.
Now, mu_n should be perfectly symmetric. Given two points, (x_0 - dx, y_0) and (x_0 + dx, y_0), I should see that \mu(x_0 - dx, y_0) - \mu(x_0 + dx, y_0)= \mathcal{O}(1\times10^{-16}). However, this is not what I see at all.
After solving the requisite linear system for mu_n, I find that (for example) mu_n(2.5, 0.1) = 0.002777… and mu_n(7.5, 0.1) = 0.003796…. What accounts for this discrepancy?
I’ve tried different solvers, changing the mesh resolution, changing the degree of the function space… the list goes on. Nothing dispenses with this disparity in mu_n.
import fenics as fe
import os
import numpy as np
initDropDiam = 5
L_x, L_y = 2*initDropDiam, 2*initDropDiam
nx, ny = 200, 200
h = min(L_x/nx, L_y/ny)
# Relevant constants
sigma = 0.005
Cn = 0.05
eps = Cn * initDropDiam
beta = 12*sigma/eps
kappa = 3*sigma*eps/2
# Droplet center
center_init_x, center_init_y = L_x/2, 0
# Set up domain.
mesh = fe.RectangleMesh(fe.Point(0, 0), fe.Point(L_x, L_y), nx, ny)
# Set periodic boundary conditions at left and right endpoints
class PeriodicBoundaryX(fe.SubDomain):
def inside(self, point, on_boundary):
return fe.near(point[0], 0.0) and on_boundary
def map(self, right_bdy, left_bdy):
# Map left boundary to the right
left_bdy[0] = right_bdy[0] - L_x
left_bdy[1] = right_bdy[1]
pbc = PeriodicBoundaryX()
V = fe.FunctionSpace(mesh, "P", 1, constrained_domain=pbc)
# Define trial and test functions, as well as
# finite element functions at previous timesteps
f_trial = fe.TrialFunction(V)
phi_n = fe.Function(V)
mu_n = fe.Function(V)
v = fe.TestFunction(V)
# Initialize \phi
phi_init_expr = fe.Expression(
"0.5 - 0.5 * tanh( 2.0 * (sqrt(pow(x[0]-xc,2) + pow(x[1]-yc,2)) - R) / eps )",
degree=1, # polynomial degree used for interpolation
xc=center_init_x,
yc=center_init_y,
R=initDropDiam/2,
eps=eps
)
phi_n = fe.project(phi_init_expr, V)
# Define variational problems
bilin_form_mu = f_trial * v * fe.dx
lin_form_mu = 4*beta*(phi_n - 1)*(phi_n - 0)*(phi_n - 0.5)*v*fe.dx\
+ kappa*fe.dot(fe.grad(phi_n),fe.grad(v))*fe.dx
mu_mat = fe.assemble(bilin_form_mu)
mu_solver = fe.KrylovSolver("cg", "ilu")
mu_solver.set_operator(mu_mat)
rhs_mu = fe.assemble(lin_form_mu)
mu_solver.solve(mu_n.vector(), rhs_mu)


