Computing heat diffusion creates weird results I am trying to model heat diffusion on the surface of a mesh. I annexed the most important bits of theory about this topic as screenshots on the question see the bottom.
The crux of the issue is we are solving a linear system $(M - tL_C)u = \delta_y$. In this case $M$ is a diagonal matrix, $L_C$ is the discrete Laplace operator, $t$ is a constant time step equal to some epsilon and $\delta_y$ is a sparse vector with only one non-zero entry which is equal to 1.
My expectation is that, upon solving this system and drawing the resulting vertex distances, I get a fading from white to black starting at the source vertex and slowly fading away as the vertices go away from the source. I am however seeing this:

Which looks like random noise to me, as if I messed up the calculation.
I implemented the solver using Eigen, this is the snippet:
Eigen::DiagonalMatrix&lt;float, Eigen::Dynamic&gt; areas(sources.size());
    Eigen::SparseMatrix&lt;float&gt; laplace_operator(sources.size(), sources.size());

    for(uint i = 0; i &lt; sources.size(); i++)
        laplace_operator.insert(i, i) = 0;

    areas.setZero();

    for(uint e = 0; e &lt; mesh.Edges().size(); e += 2)
    {
        const auto&amp; edge = mesh.Edges()[e];
        const uint i = edge.Vert().ID();
        const uint j = edge.Pair().Vert().ID();

        const Eigen::Vector3f e1 = -edge.Next().Dir().normalized();
        const Eigen::Vector3f e2 = edge.Prev().Dir().normalized();

        const float alpha = acos(e1.dot(e2));

        const Eigen::Vector3f p1 = -edge.Pair().Next().Dir().normalized();
        const Eigen::Vector3f p2 = edge.Pair().Prev().Dir().normalized();

        const float beta = acos(p1.dot(p2));

        const float laplace_coeff = -0.5f * ((1.f / tan(alpha)) + (1.f / tan(beta)));

        laplace_operator.insert(i, j) = laplace_coeff;
        laplace_operator.insert(j, i) = laplace_coeff;

        laplace_operator.coeffRef(i, i) -= laplace_coeff;
        laplace_operator.coeffRef(j, j) -= laplace_coeff;
    }

    uint count = 0;
    for(auto&amp; v: mesh.Verts())
    {
        std::vector&lt;HMesh&lt;VertexData&gt;::MFace*&gt; faces = v.ContainingFaces();
        for(auto f: faces)
        {
            areas.diagonal()[count] += f-&gt;Area();
        }

        areas.diagonal()[count] /= 3.f;

        count++;
    }

    SparseLU&lt;SparseMatrix&lt;float&gt;, COLAMDOrdering&lt;int&gt; &gt; solver;

    const Eigen::SparseMatrix&lt;float&gt; a =
        Eigen::SparseMatrix&lt;float&gt;(areas) - 0.01 * laplace_operator;
    solver.analyzePattern(a);
    solver.factorize(a);

    return solver.solve(sources);

I have checked and sources is indeed a sparse vector with a singular source vertex set to 1 so the input is correct. The mesh operations that fetch values are very tested and they are returning what is expected, so I know the error is in the logic of this function.
I suspect my mistake might be creating the laplace operator, but I am not sure.
I messed up I am doing a double negative and that is causing the problem:
const float laplace_coeff = -0.5f * ((1.f / tan(alpha)) + (1.f / tan(beta)));
This should be positive.