P[x_, y_] := x y
eq = Laplacian[Laplacian[w[x, y], {x, y}], {x, y}] == P[x, y];
bc = {w[0, y] == w[1, y] == w[x, 0] == w[x, 1] == 0,
Derivative[2, 0][w][0, y] == Derivative[2, 0][w][1, y] ==
Derivative[0, 2][w][x, 0] == Derivative[0, 2][w][x, 1] == 0} /.
Equal[a__, b_] :> Thread[{a} == b];
{bcy, bcx} = GatherBy[Flatten@bc, FreeQ[#, _[0 | 1, y]] &];
domain = {0, 1};
points = 25;
grid = Array[# &, points, domain];
difforder = 4;
(*Definition of pdetoae isn't included in this code piece,
please find it in the link above.*)
ptoafunc = pdetoae[w[x, y], {grid, grid}, difforder];
var = Outer[w, grid, grid] // Flatten;
del = #[[3 ;; -3]] &;
ae = del /@ del@ptoafunc@eq;
aebcx = ptoafunc@bcx;
aebcy = del /@ ptoafunc@bcy;
var = Outer[w, grid, grid] // Flatten;
{b, m} = CoefficientArrays[{ae, aebcx, aebcy} // Flatten, var];
sollst = LinearSolve[m, -N@b];
Remark
If you have difficulty in understanding the usage of
del
, the following is an alternative way for calculatingsollst
:fullsys = ptoafunc@{eq, bcx, bcy} // Flatten; {b, m} = CoefficientArrays[fullsys, var]; sollst = LeastSquares[m, -N@b]; // AbsoluteTiming
Notice this approach is slower.
sol = ListInterpolation[Partition[sollst, points], {grid, grid}];
Plot3D[sol[x, y], {x, ##}, {y, ##}] & @@ domain