ufc::finite_element::evaluate_reference_basis_derivatives returns wrong values

Issue #154 new
Prof Garth Wells created an issue

The FFC generated UFC function ufc::finite_element::evaluate_reference_basis_derivatives is returning wrong results. For a P1 basis, I would expect all derivatives to be +1/-1, or 0. However, in 2D the function returns some two, and in 3D some threes.

Code to reproduce attached.

Comments (12)

  1. Jan Blechta

    I would expect all derivatives to be +1/-1

    I would expect also 0.5**-0.5 on reference triangle.

  2. Chris Richardson

    Not related to that change. The code for evaluate_reference_basis_derivatives is in ffc/uflacs/backends/ufc/evalderivs.py

  3. Prof Garth Wells reporter

    @blechta Why would you expect 0.5**-0.5? It's P1 on the triangle reference triangle (0, 0), (1, 0), (0, 1).

  4. Chris Richardson

    The 2017.1.0 release of ffc produces the same result (before merging Martin's changes, I think).

  5. Prof Garth Wells reporter

    It looks like the loop:

            for (std::size_t r = 0; r < num_derivatives; ++r)
            {
                // Declare derivative matrix (of polynomial basis).
                double dmats[3][3];
                // Initialize dmats.
                std::size_t comb = combinations[order - 1][r][0];
                for (std::size_t t = 0; t < 3; ++t)
                    for (std::size_t u = 0; u < 3; ++u)
                        dmats[t][u] = dmats0[comb][t][u];
                // Looping derivative order to generate dmats.
    

    needs to be brought inside the loop:

                case 0:
                    // Compute reference derivatives for dof 0.
                    for (std::size_t r = 0; r < num_derivatives; ++r)
                    {
    

    I.e.,

                case 0:
                    // Compute reference derivatives for dof 0.
                    for (std::size_t r = 0; r < num_derivatives; ++r)
                    {
    
                // Declare derivative matrix (of polynomial basis).
                double dmats[3][3];
                // Initialize dmats.
                std::size_t comb = combinations[order - 1][r][0];
                for (std::size_t t = 0; t < 3; ++t)
                    for (std::size_t u = 0; u < 3; ++u)
                        dmats[t][u] = dmats0[comb][t][u];
                // Looping derivative order to generate dmats.
    
  6. Log in to comment