spectralDNS / shenfun

High performance computational platform in Python for the spectral Galerkin method

Home Page:http://shenfun.readthedocs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeError when applying inhomogeneous bcs in both x- and y- direction

thoeschler opened this issue · comments

Hi Mikael,
I am using shenfun to solve a vector Poisson problem on a 2D domain with inhomogeneous Dirichlet boundary conditions. Implementing inhomogeneous bcs in either x-direction or y-direction works perfectly fine. However, when I try to apply inhomogeneous bcs in both x-direction and y-direction I get a TypeError when I create the corresponding TensorProductSpace. I hope the code below shows the problem.

from mpi4py import MPI
from shenfun import FunctionSpace, TensorProductSpace
from mpi4py_fft.pencil import Subcomm

comm = MPI.COMM_WORLD

family = 'legendre'
x, y = symbols("x,y")

# size of discretization
n = 20
N = [n, n+1]

# bases
BX_hom = x, y = symbols("x,y")(N[0], family=family, bc=(0, 0))
BY_hom = FunctionSpace(N[1], family=family, bc=(0, 0))
BX_inhom = FunctionSpace(N[0], family=family, bc=((1-y)**2*(1+y)**2, 0)) # inhomogeneous bc for v_x at x = 1
BY_inhom = FunctionSpace(N[1], family=family, bc=(0, (1-x)**2*(1+x)**2)) # inhomogeneous bc for v_x at y = 1

# spaces
subcomms = Subcomm(MPI.COMM_WORLD, [0, 1])
T_hom = TensorProductSpace(subcomms, (BX_hom, BY_hom))

# working
T_inhom = TensorProductSpace(subcomms, (BX_hom, BY_inhom))

# non-working
# T_inhom = TensorProductSpace(subcomms, (BX_inhom, BY_inhom))

Best regards,
Thilo

Hi Thilo
You're probably just the first one to try non-homogeneous in two directions, so I'm not surprised it does not work. But I do think it should work, so I will have a look at this when I return from vacation. Meanwhile, I think you can create a much simpler minimum reproducing script, and it would also do my job easier if you update to the latest version of shenfun.
M

Hi Mikael,

I just updated the code from my recent comment.

Best regards,
Thilo

Thanks Thilo,

I have been looking into this and it turns out that it will be quite difficult to implement. The problem is mostly the forward routine, inner and padding. Frankly, I think I need to add specific routines for 2 inhomogeneous directions all over the place, and I'm a little bit reluctant to do that. Hence I need some time to see if I can figure out a more clever or generic way to do this. Will get back to you in a while.

You should now be able to use 2 non-homogeneous directions in the latest version. It is a tad preliminary, and forward does not yet work. But inner does and I seem to be able to solve this simple Poisson equation with constant rhs:

from shenfun import *
import sympy as sp

x, y = sp.symbols('x,y', real=True)

family = 'legendre'

# size of discretization
n = 40
N = [n, n]

# bases
BX_hom = FunctionSpace(N[0], family=family, bc=(0, 0))
BY_hom = FunctionSpace(N[1], family=family, bc=(0, 0))
BX_inhom = FunctionSpace(N[0], family=family, bc=((1-y)**2*(1+y)**2, 0)) # inhomogeneous bc for v_x at x = 1
BY_inhom = FunctionSpace(N[1], family=family, bc=(0, (1-x)**2*(1+x)**2)) # inhomogeneous bc for v_x at y = 1

T_inhom = TensorProductSpace(comm, (BX_inhom, BY_inhom))
T = T_inhom.get_orthogonal()

u = TrialFunction(T_inhom)
v = TestFunction(T_inhom)
M = inner(grad(u), grad(v))
b = inner(v, Array(T, val=-1))
bc_mats = extract_bc_matrices([M])
u_hat = Function(T_inhom).set_boundary_dofs()
w0 = Function(T_inhom)
for mat in bc_mats:
    b -= mat.matvec(u_hat, w0)

sol = la.SolverGeneric2ND(M)
u_hat = sol(b, u_hat)
X = T_inhom.local_mesh(True)
from matplotlib import pyplot as plt
plt.contourf(X[0], X[1], u_hat.backward())
plt.axis('equal')
plt.show()