Context
I am interested in extending to the ill-condionned regime the inversion of linear equations arising from inverting differential equations which have been solved via 0-splines over a mesh using the FEM toolkit in connection to this question.
For this purpose I need to compute a discrete Laplacian operator on a given mesh produced by
ToElementMesh.
Question
Given some mesh, and a discrete function associating a value at each mesh element, I would like to compute a penalty function corresponding to the integral of the Laplacian square of the function over that mesh.
$$ P(\mathbf{a}) = \int \big|\Delta \phi \big|^2 dx\,, $$
where $\mathbf{a}=({a_i}_{i\le n})$ is a vector of values on the mesh elements and $\phi(\mathbf{x})=\sum_i a_i \phi_i(\mathbf{x})$, with $\phi_i(\mathbf{x})=1$ iff $\mathbf{x}\in \mbox{cell}_i$ and $0$ otherwise.
Of course strictly speaking, as defined, $P$ is formally zero almost everywhere since the functions $\phi_i$ are constant.
What I am after is a Sparse matrix, $\cal D$, so that
$$P(\mathbf{a}) = \mathbf{a}^T\cdot \cal D \cdot \mathbf{a}. $$
I am fairly sure some element of the answer is available in the amazing answer involving the Laplace-Beltrami operator.
It would be best if the answer would work with meshes in dimension 2 and 3.
Attempt
I have implemented a test case.
mesh0 = ToElementMesh[RegionUnion[Disk[], Rectangle[{0, 0}, {2, 2}]],
MaxCellMeasure -> 0.125, AccuracyGoal -> 2]
mesh0["Wireframe"]

From the mesh I can find their centroid
idx = mesh0["MeshElements"][[1, 1]];
tt = Table[mesh0["Coordinates"][[ idx[[i]]]], {i, Length[idx]}];
center = Map[1/Length[#] Plus @@ # &, tt, {1}];
ListPlot[center, AspectRatio -> 1]

I can then compute the matrix of distances between centroids of the mesh elements
dist = DistanceMatrix[center];
If my mesh was regular I could use
s = SparseArray[{{i_, i_} -> -1, {i_, j_} /; i - j == 1 ->
2, {i_, j_} /; i - j == 2 -> -1}, {17, 15}] // Transpose;
s1 = ArrayFlatten[TensorProduct[s, s]];
pen = Transpose[s1].s1; pen // MatrixPlot

So an alternative is to compute difference of values at 3 centres, $2x_i -x_{i-1}-x_{i+1}$ and divide by the distance square between those centres as a discrete proxy for the Laplacian.
dif = SparseArray[{{nn, nn} -> 1,
{1, 1} -> 1, {i_, i_} ->
2, {i_, j_} /; i - j == 1 -> -1, {i_, j_} /;
i - j == -1 -> -1}, {nn, nn}];
idist = Inverse@DistanceMatrix[center] // SparseArray;
idist = Transpose[idist]. idiot;
pen = Transpose[idist.dif].(idist.dif); pen // MatrixPlot
This operator has the good taste to nul a constant vector, but it is
expansive to compute. May be a workaround with Nearest is in order
to make idist sparse?



laplacianandmassalso as the stiffness matrix and mass matrix of any other FEM tool. (I am about to write that into the post...) – Henrik Schumacher Mar 28 '20 at 19:33bilaplacianis{Length[pts], Length[pts]}, no? Beware that I use"MeshOrder" -> 1to definemesh0. – Henrik Schumacher Mar 28 '20 at 19:58Blockin the relevant code block; everything before that is only relevant for curves. – Henrik Schumacher Mar 28 '20 at 19:59