Hi
I want to create an interior discontinuity for Poisson’s equation as below
import dolfinx
import dolfinx.fem.petsc
from petsc4py import PETSc
import ufl
from mpi4py import MPI
import numpy as np
domain = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, 8, 8)
V = dolfinx.fem.functionspace(domain, ("DG", 1))
tdim = domain.topology.dim
fdim = tdim - 1
def on_center_center(x):
return np.isclose(x[0],0.5)&(x[1]>=.5)
def left_domain(x):
return (x[0]<=.5)
domain.topology.create_connectivity(fdim, tdim)
domain.topology.create_connectivity(tdim, fdim)
facet_map = domain.topology.index_map(fdim)
num_facets_on_proc = facet_map.size_local + facet_map.num_ghosts
facets = np.arange(num_facets_on_proc, dtype=np.int32)
facet_values = np.ones(num_facets_on_proc, dtype=np.int32)
facet_values[dolfinx.mesh.locate_entities(domain, domain.topology.dim - 1, on_center_center)] = 2
ft = dolfinx.mesh.meshtags(domain, domain.topology.dim - 1, facets, facet_values)
dS = ufl.Measure("dS", domain=domain, subdomain_data=ft)
#Setting subdomain_data to define +/- side https://fenicsproject.discourse.group/t/integrating-over-an-interior-surface/247/4
cell_map = domain.topology.index_map(tdim)
num_cells_on_proc = cell_map.size_local + cell_map.num_ghosts
cells = np.arange(num_cells_on_proc, dtype=np.int32)
cell_values = 2*np.ones(num_cells_on_proc, dtype=np.int32)
cell_values[dolfinx.mesh.locate_entities(domain, tdim, left_domain)] = 1 # 3
st = dolfinx.mesh.meshtags(domain, tdim, cells, cell_values)
dx = ufl.Measure('dx', domain=domain,subdomain_data=st)
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
f = dolfinx.fem.Constant(domain, dolfinx.default_scalar_type(0))
leftValue=dolfinx.fem.Constant(domain, dolfinx.default_scalar_type(-1))
rightValue=dolfinx.fem.Constant(domain, dolfinx.default_scalar_type(1))
n=ufl.FacetNormal(domain)
h = ufl.Circumradius(domain)
alpha = dolfinx.fem.Constant(domain, dolfinx.default_scalar_type(100))
a = ufl.dot(ufl.grad(u), ufl.grad(v)) * dx
a += -ufl.inner(ufl.jump(v,n),ufl.avg(ufl.grad(u)))*dS(1)
a += -ufl.inner(ufl.avg(ufl.grad(v)),ufl.jump(u,n))*dS(1)
a += alpha/ufl.avg(h)*ufl.inner(ufl.jump(v,n),ufl.jump(u,n)) * dS(1)
a += - ufl.inner(n('+'), ufl.grad(u('+'))) * v('+') * (dS(2))
a += - ufl.inner(n('+'), ufl.grad(v('+'))) * u('+') * (dS(2)) + alpha/h('+') * ufl.inner(u('+'), v('+')) * (dS(2))
a += - ufl.inner(n('-'), ufl.grad(u('-'))) * v('-') * (dS(2))
a += - ufl.inner(n('-'), ufl.grad(v('-'))) * u('-') * (dS(2)) + alpha/h('-') * ufl.inner(u('-'), v('-')) * (dS(2))
L = f * v * dx
L += - ufl.inner(n('+'), ufl.grad(v('+'))) * leftValue * dS(2) + alpha/h('+') * ufl.inner(leftValue, v('+')) * dS(2)
L += - ufl.inner(n('-'), ufl.grad(v('-'))) * rightValue * dS(2) + alpha/h('-') * ufl.inner(rightValue, v('-')) * dS(2)
A = dolfinx.fem.petsc.create_matrix(dolfinx.fem.form(a))
b = dolfinx.fem.petsc.create_vector(dolfinx.fem.form(L))
dolfinx.fem.petsc.assemble_vector(b, dolfinx.fem.form(L))
dolfinx.fem.petsc.assemble_matrix(A, dolfinx.fem.form(a))
A.assemble()
ksp=PETSc.KSP()
solver = ksp.create(domain.comm)
solver.setOperators(A)
uhd = dolfinx.fem.Function(V)
solver.solve(b, uhd.vector)
This works, but except for this simple case the (‘+’) and (‘-’) side is arbitrarily defined. I tried to apply this, but it does not seem to work with dolfinx.
How can consistently define the direction of “+”?
Thanks
Torben