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

Bug in FunctionSpace with bc as dictionary

thoeschler opened this issue · comments

Hi Mikael!

I noticed a small bug in FunctionSpace. When I run the following code

from shenfun import FunctionSpace, Function

A = FunctionSpace(10, family='legendre', bc=(1, 2, 3, 4))
B = FunctionSpace(10, family='legendre', bc={'left': [('D', 1), ('N', 3)],
                                             'right': [('D', 2), ('N', 4)]})

a = Function(A).set_boundary_dofs()
b = Function(B).set_boundary_dofs()

print(a, b)

I get

[0. 0. 0. 0. 0. 0. 1. 2. 3. 4.] [0. 0. 0. 0. 0. 0. 1. 3. 2. 4.]

alhough both functions should be the same since the first two entries in (1, 2, 3, 4) are used to specify the Dirichlet and the last two for the Neumann boundary conditions. I guess the reason for this is the following code:

elif isinstance(bc, dict):
bcs = {k.lower(): list(v) if isinstance(v[0], (tuple, list)) else [v] for k, v in bc.items()}
bc = []
key = []
if 'left' in bcs:
bcs['left'].sort()
for bci in bcs['left']:
if bci[0] == 'N':
bc.append(bci[1]/df)
elif bci[0] == 'N2':
bc.append(bci[1]/df**2)
elif bci[0] == 'N3':
bc.append(bci[1]/df**3)
else:
bc.append(bci[1])
key += ['L'+bci[0] for bci in bcs['left']]
if 'right' in bcs:
bcs['right'].sort()
for bci in bcs['right']:
if bci[0] == 'N':
bc.append(bci[1]/df)
elif bci[0] == 'N2':
bc.append(bci[1]/df**2)
elif bci[0] == 'N3':
bc.append(bci[1]/df**3)
else:
bc.append(bci[1])
key += ['R'+bci[0] for bci in bcs['right']]
return key, tuple(bc)

Herein the boundary conditions are ordered in the wrong way when converting the dict to a tuple.

If you find this to be a bug I can try to fix it myself if you want.

Best regards,
Thilo

Hi Thilo,
You're absolutely right. There is a logical mistake in there. But I'm not sure whether to fix the code above, or to switch the order of bases 2 and 3 here

class BCBiharmonic(BCBase):
@staticmethod
def short_name():
return 'BCB'
def stencil_matrix(self, N=None):
return sp.Rational(1, 30)*np.array([[15, -18, 0, 3],
[15, 18, 0, -3],
[5, -3, -5, 3],
[-5, -3, 5, 3]])

Perhaps we need to consider the whole logic to try to make it more robust?

Hi Mikael,

switching the order of the bases would definitely be the easiest way of fixing this. Also, I don't think that it is really necessary to change the whole logic since the only problem was the special ordering of the boundary conditions for the ShenBiharmonic basis. So I would simply switch the order in BCBiharmonic.

Ok, great. I will push a fix to this issue then and make sure to update the docstring with the correct order.

This was fixed in 4e36d73!