libMesh/libmesh: coverage diff

Base a20bc7 Head #4546 ebe2b5
Total Total +/- New
Rate 65.99% 66.06% +0.07% 100.00%
Hits 79543 79622 +79 132
Misses 40997 40913 -84 0
Filename Stmts Miss Cover
include/fe/fe.h +4 0 +1.47%
include/geom/cell_pyramid.h 0 -1 +5.88%
include/numerics/petsc_matrix_base.h 0 +2 -50.00%
include/numerics/petsc_mffd_matrix.h +4 +1 +5.00%
include/solvers/nonlinear_solver.h +2 +2 -3.04%
include/utils/utility.h 0 +4 -6.06%
src/base/dof_map_constraints.C +20 +19 -0.60%
src/fe/fe_hierarchic_shape_1D.C -66 0 -8.87%
src/fe/fe_hierarchic_shape_2D.C -2 0 -0.07%
src/fe/fe_hierarchic_shape_3D.C -8 -134 +11.60%
src/geom/elem.C +4 0 +0.07%
src/mesh/distributed_mesh.C 0 -2 +0.25%
src/mesh/mesh_triangle_holes.C 0 +1 -0.28%
src/numerics/petsc_matrix_shell_matrix.C +30 +26 -39.00%
src/solvers/petsc_nonlinear_solver.C +1 0 +0.08%
src/systems/nonlinear_implicit_system.C +6 -2 +3.20%
TOTAL -5 -84 +0.07%
code
coverage unchanged
code
coverage increased
code
coverage decreased
+
line added or modified

include/fe/fe.h

1578  
1579  
1580  
1581 +
1582  
1583 +
1584  
1585  
1586  
1587 +
1588  
1589 +
1590  
1591  
1592  
 * values of the finite element solution at the vertices, and scaling them would change what a nodal
 * boundary condition or a nodal output of a HIERARCHIC variable means.
 */
inline Real fe_hierarchic_bubble_scaling(const unsigned int i)
{
  libmesh_assert_greater(i, 1);

  // An even bubble differentiates to xi^(i-1)/(i-1)!, whose square integrates to 2/(2i-1) over the
  // interval. The linear term an odd bubble carries turns the i^2 of that calculation into (i-1)^2.
  const Real denominator = (i % 2) ? Real(i) - 1. : Real(i);

  return std::sqrt((2. * Real(i) - 1.) / 2.) / denominator;
}


include/geom/cell_pyramid.h

102  
103  
104  
105  
106  
107  
108  
  /**
   * \returns 5.  All pyramids have 5 faces.
   */
  virtual unsigned int n_faces() const override { return 5; }

  /**
   * \returns 10.

include/numerics/petsc_matrix_base.h

104  
105  
106  
107  
108  
109  
110  
111  
112  
  PetscMatrixBase & operator= (PetscMatrixBase &&) = delete;
  virtual ~PetscMatrixBase ();

  virtual SolverPackage solver_package() override
  {
    return PETSC_SOLVERS;
  }

  /**

include/numerics/petsc_mffd_matrix.h

110  
111  
112  
113 +
114  
115  
116 +
117 +
118 +
119 +
120  
121  
122  
123  

template <typename T>
void
PetscMFFDMatrix<T>::assign(Mat m, bool set_context)
{
  this->_mat = m;
  this->_is_initialized = true;
  this->_destroy_mat_on_exit = false;
  if (set_context)
    this->set_context();
}

template <typename T>
void

include/solvers/nonlinear_solver.h

107  
108  
109  
110 +
111  
112  
113  
114  
115  
116  
117 +
118  
119  
120  
   * the preconditioning matrix -- which may be the same object (the common case) or genuinely
   * distinct (e.g. a matrix-free operator paired with an assembled preconditioning matrix).
   */
  virtual std::pair<unsigned int, Real> solve (SparseMatrix<T> & /* jac_in */,
                                               SparseMatrix<T> & /* pre_in */,
                                               NumericVector<T> & /* x_in */,
                                               NumericVector<T> & /* r_in */,
                                               const double /* tol */,
                                               const unsigned int /* m_its */)
  {
    libmesh_not_implemented();
  }

  /**

include/utils/utility.h

271  
272  
273  
274  
275  
276  
277  
278  
279  
280  
281  
282  
// T::operator*) might do worse, so we'll specialize here.
template <typename T>
struct do_pow<6,T> {
  static inline T apply (const T & x)
  {
    const T x2 = x*x,
      x4 = x2*x2;

    return x4*x2;
  }
};

src/base/dof_map_constraints.C

205  
206  
207  
208 +
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221 +
222  
223  
224  
class AddConstraint
{
public:
  virtual ~AddConstraint() = default;

  virtual void operator()(dof_id_type dof_number,
                          const DofConstraintRow & constraint_row,
                          const Number constraint_rhs) const = 0;
};

class AddPrimalConstraint : public AddConstraint
{
private:
  DofMap                  & dof_map;

public:
  AddPrimalConstraint(DofMap & dof_map_in) : dof_map(dof_map_in) {}

  virtual void operator()(dof_id_type dof_number,
                          const DofConstraintRow & constraint_row,
238  
239  
240  
241 +
242  
243  
244  

public:
  AddAdjointConstraint(DofMap & dof_map_in, unsigned int qoi_index_in)
    : dof_map(dof_map_in), qoi_index(qoi_index_in) {}

  virtual void operator()(dof_id_type dof_number,
                          const DofConstraintRow & constraint_row,
256  
257  
258  
259 +
260  
261  
262  
263  
264  
265  
266 +
267  
268 +
269  
270 +
271  
272  
273  
274 +
275 +
276 +
277  
278  
279  
 * already constrains is skipped, as AddPrimalConstraint skips it, so that the
 * values collected are those the constraint path would have added.
 */
class CollectDirichletValues : public AddConstraint
{
private:
  const DofMap            & dof_map;
  DofConstraintValueMap   & values;

public:
  CollectDirichletValues(const DofMap & dof_map_in,
                         DofConstraintValueMap & values_in)
    : dof_map(dof_map_in), values(values_in) {}

  virtual void operator()(dof_id_type dof_number,
                          const DofConstraintRow & /*constraint_row*/,
                          const Number constraint_rhs) const
  {
    if (!dof_map.is_constrained_dof(dof_number))
      values[dof_number] = constraint_rhs;
  }
};


1573  
1574  
1575  
1576 +
1577  
1578  
1579  
  } // apply_dirichlet_impl

public:
  ConstrainDirichlet (const DofMap & dof_map_in,
                      const MeshBase & mesh_in,
                      const Real time_in,
                      const DirichletBoundaries & dirichlets_in,
1925  
1926  
1927  
1928 +
1929  
1930  
1931  
1932  
1933 +
1934  
1935 +
1936  
1937 +
1938 +
1939  
1940 +
1941 +
1942 +
1943  
1944  
1945 +
1946 +
1947  
1948  
1949 +
1950 +
1951  
1952  
1953  


#ifdef LIBMESH_ENABLE_DIRICHLET
void DofMap::compute_dirichlet_values(const DirichletBoundaries & dirichlets,
                                      const MeshBase & mesh,
                                      const Real time,
                                      DofConstraintValueMap & values) const
{
  parallel_object_only();

  values.clear();

  if (dirichlets.empty())
    return;

  if (_verify_dirichlet_bc_consistency)
    for (const auto & dirichlet : dirichlets)
      this->check_dirichlet_bcid_consistency(mesh, *dirichlet);

  // Processors only project their local elements, as the constraint path does
  ConstElemRange range (mesh.local_elements_begin(),
                        mesh.local_elements_end());

  Threads::parallel_for
    (range, ConstrainDirichlet(*this, mesh, time, dirichlets,
                               CollectDirichletValues(*this, values)));
}
#endif // LIBMESH_ENABLE_DIRICHLET

src/fe/fe_hierarchic_shape_1D.C

456  
457  
458  
459 +
460  
461 +
462 +
463  
464  
465  
      // vertices and scaled to unit H1 seminorm over the interval
    default:
      for (unsigned int n=1; n <= i; ++n)
        returnval *= xi;

      returnval = (returnval - ((i % 2) ? xi : 1.)) *
        fe_hierarchic_bubble_scaling(i);
      break;
    }

499  
500  
501  
502 +
503  
504 +
505 +
506  
507  
508  
      // contributes, under the same scaling their shape functions carry
    default:
      for (unsigned int n=1; n != i; ++n)
        returnval *= xi;

      returnval = (Real(i) * returnval - ((i % 2) ? 1. : 0.)) *
        fe_hierarchic_bubble_scaling(i);
      break;
    }

541  
542  
543  
544 +
545 +
546  
547 +
548 +
549  
550  
551  
      // Both parities differentiate twice to p (p-1) xi^(p-2), the linear term of an odd bubble
      // dropping out, under the same scaling their shape functions carry
    default:
      for (unsigned int n=2; n != i; ++n)
        returnval *= xi;

      returnval = Real(i) * (Real(i) - 1.) * returnval *
        fe_hierarchic_bubble_scaling(i);
      break;
    }

src/fe/fe_hierarchic_shape_2D.C

932  
933  
934  
935 +
936 +
937  
938  
939  
    {
      // The limit of the general expression below, in which only the bubble's leading term survives
      // and so carries the same normalization the one-dimensional bubble does
      return std::pow(edgenumerator, basisorder) *
        fe_hierarchic_bubble_scaling(basisorder);
    }
  // Experimentally, as c -> 0, n propto c, I'm still seeing good
  // behavior from the default implementation below:

src/fe/fe_hierarchic_shape_3D.C

140  
141  
142  
143 +
144 +
145  
146  
147  
      // Rotating the least node of the side to the origin leaves the
      // reflection about the diagonal through it, which is settled by
      // which of that node's two neighbors is the lesser.
      const bool flip = (side.point((min_side_node+3)%4) <
                         side.point((min_side_node+1)%4));

      switch (min_side_node) {
      case 0:
151  
152  
153  
154  
155  
156  
157  
      case 1:
        sidep(0) = -sidep(0);
        if (!flip)
          std::swap(sidep(0), sidep(1));
        break;
      case 2:
        sidep(0) = -sidep(0);
162  
163  
164  
165  
166  
167  
168  
      case 3:
        sidep(1) = -sidep(1);
        if (!flip)
          std::swap(sidep(0), sidep(1));
        break;
      default:
        libmesh_error();
254  
255  
256  
257  
258  
259  
260  
      i1 = 0;
      i2 = 0;
      if (elem->positive_edge_orientation(0))
        xi = -xi_saved;
    }
  // Edge 1
  else if (i < 8 + 2*e)
272  
273  
274  
275  
276  
277  
278  
      i1 = 1;
      i2 = 0;
      if (!elem->positive_edge_orientation(2))
        xi = -xi_saved;
    }
  // Edge 3
  else if (i < 8 + 4*e)
326  
327  
328  
329  
330  
331  
332  
      i1 = 0;
      i2 = 1;
      if (elem->positive_edge_orientation(8))
        xi = -xi_saved;
    }
  // Edge 9
  else if (i < 8 + 10*e)
344  
345  
346  
347  
348  
349  
350  
      i1 = 1;
      i2 = 1;
      if (!elem->positive_edge_orientation(10))
        xi = -xi_saved;
    }
  // Edge 11
  else if (i < 8 + 12*e)
368  
369  
370  
371  
372  
373  
374  
375  
        if (elem->positive_face_orientation(0))
          {
            // Case 1
            xi  = xi_saved;
            eta = eta_saved;
          }
        else
          {
382  
383  
384  
385  
386  
387  
388  
389  
        if (elem->positive_face_orientation(0))
          {
            // Case 3
            xi  = -eta_saved;
            eta = xi_saved;
          }
        else
          {
392  
393  
394  
395  
396  
397  
398  
399  
400  
401  
402  
403  
404  
405  
406  
407  
408  
409  
410  
411  
412  
413  
414  
415  
416  
417  
418  
419  
420  
421  
422  
423  
424  
            eta = -eta_saved;
          }

      else if (elem->point(2) == min_point)
        if (elem->positive_face_orientation(0))
          {
            // Case 5
            xi  = -xi_saved;
            eta = -eta_saved;
          }
        else
          {
            // Case 6
            xi  = -eta_saved;
            eta = -xi_saved;
          }

      else if (elem->point(1) == min_point)
        {
          if (elem->positive_face_orientation(0))
            {
              // Case 7
              xi  = eta_saved;
              eta = -xi_saved;
            }
          else
            {
              // Case 8
              xi  = -xi_saved;
              eta = eta_saved;
            }
        }
    }
435  
436  
437  
438  
439  
440  
441  
442  
        if (!elem->positive_face_orientation(1))
          {
            // Case 1
            xi   = xi_saved;
            zeta = zeta_saved;
          }
        else
          {
446  
447  
448  
449  
450  
451  
452  
453  
454  
455  
456  
457  
458  
459  
460  
461  
462  
463  
464  
465  
466  
467  
468  
469  
470  
471  
472  
473  
474  
475  
476  
          }

      else if (elem->point(1) == min_point)
        if (!elem->positive_face_orientation(1))
          {
            // Case 3
            xi   = zeta_saved;
            zeta = -xi_saved;
          }
        else
          {
            // Case 4
            xi   = -xi_saved;
            zeta = zeta_saved;
          }

      else if (elem->point(5) == min_point)
        if (!elem->positive_face_orientation(1))
          {
            // Case 5
            xi   = -xi_saved;
            zeta = -zeta_saved;
          }
        else
          {
            // Case 6
            xi   = -zeta_saved;
            zeta = -xi_saved;
          }

      else if (elem->point(4) == min_point)
478  
479  
480  
481 +
482 +
483  
484  
485  
486  
487  
488  
489  
490  
491  
          if (!elem->positive_face_orientation(1))
            {
              // Case 7
              xi   = -zeta_saved;
              zeta = xi_saved;
            }
          else
            {
              // Case 8
              xi   = xi_saved;
              zeta = -zeta_saved;
            }
        }
    }
502  
503  
504  
505  
506  
507  
508  
509  
        if (!elem->positive_face_orientation(2))
          {
            // Case 1
            eta  = eta_saved;
            zeta = zeta_saved;
          }
        else
          {
513  
514  
515  
516  
517  
518  
519  
520  
521  
522  
523  
524  
525  
526  
527  
528  
529  
530  
531  
532  
533  
534  
535  
536  
537  
          }

      else if (elem->point(2) == min_point)
        if (!elem->positive_face_orientation(2))
          {
            // Case 3
            eta  = zeta_saved;
            zeta = -eta_saved;
          }
        else
          {
            // Case 4
            eta  = -eta_saved;
            zeta = zeta_saved;
          }

      else if (elem->point(6) == min_point)
        if (!elem->positive_face_orientation(2))
          {
            // Case 5
            eta  = -eta_saved;
            zeta = -zeta_saved;
          }
        else
          {
540  
541  
542  
543  
544  
545  
546  
547  
548  
549  
550  
551  
552  
553  
554  
555  
556  
557  
558  
            zeta = -eta_saved;
          }

      else if (elem->point(5) == min_point)
        {
          if (!elem->positive_face_orientation(2))
            {
              // Case 7
              eta  = -zeta_saved;
              zeta = eta_saved;
            }
          else
            {
              // Case 8
              eta   = eta_saved;
              zeta = -zeta_saved;
            }
        }
    }
569  
570  
571  
572  
573  
574  
575  
576  
        if (elem->positive_face_orientation(3))
          {
            // Case 1
            xi   = xi_saved;
            zeta = zeta_saved;
          }
        else
          {
589  
590  
591  
592  
593  
594  
595  
596  
597  
598  
599  
600  
601  
602  
603  
604  
605  
606  
607  
608  
609  
610  
611  
612  
613  
614  
615  
616  
617  
618  
619  
620  
621  
622  
623  
624  
625  
        else
          {
            // Case 4
            xi   = xi_saved;
            zeta = -zeta_saved;
          }

      else if (elem->point(6) == min_point)
        if (elem->positive_face_orientation(3))
          {
            // Case 5
            xi   = -xi_saved;
            zeta = -zeta_saved;
          }
        else
          {
            // Case 6
            xi   = -zeta_saved;
            zeta = -xi_saved;
          }

      else if (elem->point(2) == min_point)
        {
          if (elem->positive_face_orientation(3))
            {
              // Case 7
              xi   = zeta_saved;
              zeta = -xi_saved;
            }
          else
            {
              // Case 8
              xi   = -xi_saved;
              zeta = zeta_saved;
            }
        }
    }
636  
637  
638  
639  
640  
641  
642  
643  
        if (elem->positive_face_orientation(4))
          {
            // Case 1
            eta  = eta_saved;
            zeta = zeta_saved;
          }
        else
          {
647  
648  
649  
650  
651  
652  
653  
654  
655  
656  
657  
658  
659  
660  
661  
662  
663  
664  
665  
666  
667  
668  
669  
670  
671  
          }

      else if (elem->point(4) == min_point)
        if (elem->positive_face_orientation(4))
          {
            // Case 3
            eta  = -zeta_saved;
            zeta = eta_saved;
          }
        else
          {
            // Case 4
            eta  = eta_saved;
            zeta = -zeta_saved;
          }

      else if (elem->point(7) == min_point)
        if (elem->positive_face_orientation(4))
          {
            // Case 5
            eta  = -eta_saved;
            zeta = -zeta_saved;
          }
        else
          {
674  
675  
676  
677  
678  
679  
680  
681  
682  
683  
684  
685  
686  
687  
688  
689  
690  
691  
692  
            zeta = -eta_saved;
          }

      else if (elem->point(3) == min_point)
        {
          if (elem->positive_face_orientation(4))
            {
              // Case 7
              eta   = zeta_saved;
              zeta = -eta_saved;
            }
          else
            {
              // Case 8
              eta  = -eta_saved;
              zeta = zeta_saved;
            }
        }
    }
703  
704  
705  
706  
707  
708  
709  
710  
        if (!elem->positive_face_orientation(5))
          {
            // Case 1
            xi  = xi_saved;
            eta = eta_saved;
          }
        else
          {
714  
715  
716  
717  
718  
719  
720  
721  
722  
723  
724  
725  
726  
727  
728  
729  
730  
731  
732  
733  
734  
735  
736  
737  
738  
739  
740  
741  
742  
743  
744  
          }

      else if (elem->point(5) == min_point)
        if (!elem->positive_face_orientation(5))
          {
            // Case 3
            xi  = eta_saved;
            eta = -xi_saved;
          }
        else
          {
            // Case 4
            xi  = -xi_saved;
            eta = eta_saved;
          }

      else if (elem->point(6) == min_point)
        if (!elem->positive_face_orientation(5))
          {
            // Case 5
            xi  = -xi_saved;
            eta = -eta_saved;
          }
        else
          {
            // Case 6
            xi  = -eta_saved;
            eta = -xi_saved;
          }

      else if (elem->point(7) == min_point)
746  
747  
748  
749  
750  
751  
752  
753  
754  
755  
756 +
757  
758  
759  
          if (!elem->positive_face_orientation(5))
            {
              // Case 7
              xi  = -eta_saved;
              eta = xi_saved;
            }
          else
            {
              // Case 8
              xi  = xi_saved;
              eta = -eta_saved;
            }
        }
    }
766  
767  
768  
769 +
770  
771  
772  
773  
774  
775  
776 +
777  
778  
779  
780  
781 +
782 +
783  
784 +
785 +
786 +
787  
788 +
789 +
790  
791  
792  
      i1 = cube_number_row[basisnum] + 2;
      i2 = cube_number_page[basisnum] + 2;
    }
}


// Reorder the barycentric coordinates of a triangular face of a prism, whose vertices begin at
// \p first_vertex, so that they follow the order of the face's vertices. The interior basis of a
// triangle is not symmetric in its barycentric coordinates, so a face shared between two elements
// needs them ordered the same way from both sides.
void orient_triangle_coords(const Elem & elem,
                            const unsigned int first_vertex,
                            const Point & xi_eta_saved,
                            Point & xi_eta)
{
  unsigned int face_vertex[3] = {first_vertex, first_vertex+1, first_vertex+2};
  orient_triangle(elem, face_vertex);

  const Real barycentric[3] = {1 - xi_eta_saved(0) - xi_eta_saved(1),
                               xi_eta_saved(0),
                               xi_eta_saved(1)};

  xi_eta(0) = barycentric[face_vertex[1] - first_vertex];
  xi_eta(1) = barycentric[face_vertex[2] - first_vertex];
}


879  
880  
881  
882  
883  
884  
885  

      if (elem->point(0) == min_point)
        {
          if (!elem->positive_face_orientation(1))
            {
              // Case 1: no flips needed
              i01 = s0+1; // edge to triangle side 0 numbering
888  
889  
890  
891  
892  
893  
894  
895  
          else
            {
              // Case 2: flip about 0-4 diagonal
              i01 = s1+1;
              i2 = s0;
            }
        }
      else if (elem->point(3) == min_point)
899  
900  
901  
902 +
903  
904  
905  
              // Case 3: 0->3->4->1->0 rotation
              i01 = s1+1;
              i2 = s0;
              zeta = -zeta_saved;
            }
          else
            {
911  
912  
913  
914  
915  
916  
917  
918  
919 +
920  
921  
922  
        }
      else if (elem->point(1) == min_point)
        {
          if (!elem->positive_face_orientation(1))
            {
              // Case 5: 0->1->4->3->0 rotation
              i01 = s1+1;
              i2 = s0;
              xi_eta(0) = (1-xe_fraction)*xe_scale;
            }
          else
            {
941  
942  
943  
944 +
945 +
946  
947  
948  
              // Case 8: flip about 1-3 diagonal
              i01 = s1+1;
              i2 = s0;
              xi_eta(0) = (1-xe_fraction)*xe_scale;
              zeta = -zeta_saved;
            }
        }
    }
966  
967  
968  
969  
970  
971  
972 +
973  
974  
975  
976  
977  
978  
979  
980  
981  
982  

      if (elem->point(1) == min_point)
        {
          if (!elem->positive_face_orientation(2))
            {
              // Case 1: no flips needed
              i01 = s0+1+e; // edge to triangle side 1 numbering
              i2 = s1;
            }
          else
            {
              // Case 2: flip about 1-5 diagonal
              i01 = s1+1+e;
              i2 = s0;
            }
        }
      else if (elem->point(4) == min_point)
986  
987  
988  
989 +
990  
991  
992  
              // Case 3: 1->4->5->2->1 rotation
              i01 = s1+1+e;
              i2 = s0;
              zeta = -zeta_saved;
            }
          else
            {
996  
997  
998  
999  
1000  
1001  
1002  
1003  
1004  
1005  
1006 +
1007  
1008  
1009  
1010  
1011  
1012  
1013  
1014  
1015 +
1016  
1017  
1018  
1019  
1020  
1021  
1022  
1023  
              zeta = -zeta_saved;
            }
        }
      else if (elem->point(2) == min_point)
        {
          if (!elem->positive_face_orientation(2))
            {
              // Case 5: 1->2->5->4->1 rotation
              i01 = s1+1+e;
              i2 = s0;
              const Real xe = xe_fraction;
              xi_eta(1) = xe*xe_scale;
              xi_eta(0) = xe_scale - xi_eta(1);
            }
          else
            {
              // Case 6: flip about 7-13 midline
              i01 = s0+1+e;
              i2 = s1;
              const Real xe = xe_fraction;
              xi_eta(1) = xe*xe_scale;
              xi_eta(0) = xe_scale - xi_eta(1);
            }
        }
      else if (elem->point(5) == min_point)
        {
          if (!elem->positive_face_orientation(2))
            {
1025  
1026  
1027  
1028 +
1029  
1030  
1031  
              i01 = s0+1+e;
              i2 = s1;
              zeta = -zeta_saved;
              const Real xe = xe_fraction;
              xi_eta(1) = xe*xe_scale;
              xi_eta(0) = xe_scale - xi_eta(1);
            }
1034  
1035  
1036  
1037 +
1038 +
1039  
1040  
1041  
              // Case 8: flip about 2-4 diagonal
              i01 = s1+1+e;
              i2 = s0;
              zeta = -zeta_saved;
              const Real xe = xe_fraction;
              xi_eta(1) = xe*xe_scale;
              xi_eta(0) = xe_scale - xi_eta(1);
            }
1061  
1062  
1063  
1064  
1065  
1066  
1067  

      if (elem->point(2) == min_point)
        {
          if (!elem->positive_face_orientation(3))
            {
              // Case 1: no flips needed
              i01 = s0+1+2*e; // edge to triangle side 2 numbering
1070  
1071  
1072  
1073  
1074  
1075  
1076  
1077  
          else
            {
              // Case 2: flip about 2-3 diagonal
              i01 = s1+1+2*e;
              i2 = s0;
            }
        }
      else if (elem->point(5) == min_point)
1081  
1082  
1083  
1084 +
1085  
1086  
1087  
              // Case 3: 2->5->3->0->2 rotation
              i01 = s1+1+2*e;
              i2 = s0;
              zeta = -zeta_saved;
            }
          else
            {
1093  
1094  
1095  
1096  
1097  
1098  
1099  
1100  
1101 +
1102  
1103  
1104  
1105  
        }
      else if (elem->point(0) == min_point)
        {
          if (!elem->positive_face_orientation(3))
            {
              // Case 5: 2->0->3->5->2 rotation
              i01 = s1+1+2*e;
              i2 = s0;
              const Real xe = (1-xe_fraction);
              xi_eta(1) = xe_scale - xe*xe_scale;
            }
          else
            {
1126  
1127  
1128  
1129 +
1130 +
1131  
1132  
1133  
              // Case 8: flip about 0-5 diagonal
              i01 = s1+1+2*e;
              i2 = s0;
              zeta = -zeta_saved;
              const Real xe = (1-xe_fraction);
              xi_eta(1) = xe_scale - xe*xe_scale;
            }
        }
1137  
1138  
1139  
1140 +
1141  
1142  
1143  
1144  
1145  
1146  
1147 +
1148  
1149  
1150  
    {
      i01 = i - 3 - 6*e - 3*e*e;
      i2 = 0;
      orient_triangle_coords(*elem, 0, xi_eta_saved, xi_eta);
    }
  // Face 4
  else if (i < 6 + 9*e + 3*e*e + e*(e-1))
    {
      i01 = i - 3 - 6*e - 3*e*e - e*(e-1)/2;
      i2 = 1;
      orient_triangle_coords(*elem, 3, xi_eta_saved, xi_eta);
    }
  // Internal DoFs
  else
2349  
2350  
2351  
2352 +
2353  
2354  
2355  
            if (i01 > 2 && i01 < 3u*totalorder)
              {
                // %(p-1) to find the edge number, %2 for even vs odd
                const bool odd_basis = ((i01-3)%(totalorder-1))%2;
                if (odd_basis)
                  {
                    const int tri_edge = (i01-3)/(totalorder-1);
2406  
2407  
2408  
2409 +
2410 +
2411  
2412  
2413  
              {
                // The limit of the general expression below, in which only the bubble's leading term
                // survives and so carries the same normalization the one-dimensional bubble does
                return std::pow(edgenumerator, basisorder) *
                  fe_hierarchic_bubble_scaling(basisorder);
              }

            const Real edgeval = edgenumerator / crossval;

src/geom/elem.C

3642  
3643  
3644  
3645 +
3646  
3647  
3648  
3649  
3650 +
3651  
3652 +
3653  
3654  
3655  
3656  
3657 +
3658  
3659  
3660  
bool
Elem::positive_face_orientation(const unsigned int i) const
{
  return this->face_orientation(i) % 2;
}


unsigned int
Elem::edge_orientation(const unsigned int i) const
{
  return this->positive_edge_orientation(i);
}


unsigned int
Elem::face_orientation(const unsigned int i) const
{
  libmesh_assert_less (i, this->n_faces());

3671  
3672  
3673  
3674 +
3675  
3676  
3677  
  const unsigned int v = std::distance(nodes.begin(),
                         std::min_element(nodes.begin(), nodes.begin() + N, cmp));

  return 2 * v + cmp(nodes[(v - 1 + N) % N], nodes[(v + 1) % N]);
}

bool

src/mesh/distributed_mesh.C

1605  
1606  
1607  
1608  
1609  
1610  
1611  
1612  
1613  
1614  
1615  
1616  
1617  
1618  
                      sender_could_become_owner)
                    {
                      if (it != repartitioned_node_pids.end() &&
                          pid < it->second)
                        it->second = pid;
                      else
                        repartitioned_node_pids[n] = pid;
                    }
                  else
                    if (it == repartitioned_node_pids.end())
                      repartitioned_node_pids[n] =
                        DofObject::invalid_processor_id;

                  repartitioned_node_sets_to_push[pid].insert(n);

src/mesh/mesh_triangle_holes.C

276  
277  
278  
279  
280  
281  
282  
    {
      ray_target = inside - Point(1);
      intersection_distances =
        this->find_ray_intersections(inside, ray_target);
    }

  // I'd make this an assert, but I'm not 100% confident we can't

src/numerics/petsc_matrix_shell_matrix.C

27  
28  
29  
30  
31  
32  
33  

template <typename T>
void
PetscMatrixShellMatrix<T>::init(const numeric_index_type m,
                                const numeric_index_type n,
                                const numeric_index_type m_l,
                                const numeric_index_type n_l,
35  
36  
37  
38  
39  
40  
41  
42  
43  
                                const numeric_index_type,
                                const numeric_index_type blocksize)
{
  init_shell_mat(*this, m, n, m_l, n_l, blocksize);
  this->set_context();
}

template <typename T>
void
56  
57  
58  
59 +
60  
61  
62  
63 +
64  
65  
66  
67 +
68  
69 +
70  
71  
72  
73  
74 +
75  
76 +
77  
78  
79  
80  
81 +
82  
83 +
84  
85  
86  
87  
88 +
89  
90 +
91  
92  
93  
94  
95 +
96  
97  
98  
99 +
100  
101  
102  
103  
104 +
105  
106  
107 +
108  
109  
110  
111  
112 +
113  
114 +
115  
116  
117  
118  
119 +
120  
121 +
122  
123  
124  
125  
126 +
127  
128 +
129  
130  
131  
132  
133 +
134  
135 +
136  
137  
138  
139  
140 +
141  
142 +
143  
144  
145  
146  
147 +
148  
149 +
150  
151  
152  
153  
154 +
155  
156 +
157  
158  
159  
160  
161 +
162  
163  
164  
165 +
166  
167  
168  

template <typename T>
void
PetscMatrixShellMatrix<T>::zero()
{
  // A shell matrix computes its action and stores no entries, so there is nothing to clear. This is
  // reachable through System::init_matrices(), which zeroes every matrix it initializes.
}

template <typename T>
std::unique_ptr<SparseMatrix<T>>
PetscMatrixShellMatrix<T>::zero_clone() const
{
  libmesh_error();
}

template <typename T>
std::unique_ptr<SparseMatrix<T>>
PetscMatrixShellMatrix<T>::clone() const
{
  libmesh_not_implemented();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::set(const numeric_index_type, const numeric_index_type, const T)
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::add(const numeric_index_type, const numeric_index_type, const T)
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::add_matrix(const DenseMatrix<T> &,
                                      const std::vector<numeric_index_type> &,
                                      const std::vector<numeric_index_type> &)
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::add_matrix(const DenseMatrix<T> &,
                                      const std::vector<numeric_index_type> &)
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::add(const T, const SparseMatrix<T> &)
{
  libmesh_error();
}

template <typename T>
T
PetscMatrixShellMatrix<T>::operator()(const numeric_index_type, const numeric_index_type) const
{
  libmesh_error();
}

template <typename T>
Real
PetscMatrixShellMatrix<T>::l1_norm() const
{
  libmesh_error();
}

template <typename T>
Real
PetscMatrixShellMatrix<T>::linfty_norm() const
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::print_personal(std::ostream &) const
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::get_diagonal(NumericVector<T> &) const
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::get_transpose(SparseMatrix<T> &) const
{
  libmesh_error();
}

template <typename T>
void
PetscMatrixShellMatrix<T>::get_row(numeric_index_type,
                                   std::vector<numeric_index_type> &,
                                   std::vector<T> &) const
{
  libmesh_error();
}

template class LIBMESH_EXPORT PetscMatrixShellMatrix<Number>;

src/solvers/petsc_nonlinear_solver.C

452  
453  
454  
455 +
456  
457  
458  
        Jac = &mffd_jac;
        // mffd_jac is function-local, so don't attach a context to jac here -- it would
        // dangle once mffd_jac is destroyed at the end of this call.
        mffd_jac.assign(jac, /*set_context=*/false);
      }

    // We already computed the Jacobian during the residual evaluation
698  
699  
700  
701 +
702  
703  
704  
  _default_monitor(true),
  _snesmf_reuse_base(true),
  _computing_base_vector(true),
  _setup_reuse(false)
{
}

905  
906  
907  
908 +
909  
910  
911  
912  
913 +
914  
915  
916  
                                const double        tol,     // Stopping tolerance
                                const unsigned int  m_its)
{
  return this->solve(pre_in, pre_in, x_in, r_in, tol, m_its);
}

template <typename T>
std::pair<unsigned int, Real>
PetscNonlinearSolver<T>::solve (SparseMatrix<T> &  jac_in,  // Jacobian operator matrix (Amat)
                                SparseMatrix<T> &  pre_in,  // Preconditioning matrix (Pmat)
                                NumericVector<T> & x_in,    // Solution vector
                                NumericVector<T> & r_in,    // Residual vector
923  
924  
925  
926 +
927  
928  
929  
  this->init ();

  // Make sure the data passed in are really of Petsc types
  PetscMatrixBase<T> * jac = cast_ptr<PetscMatrixBase<T> *>(&jac_in);
  PetscMatrixBase<T> * pre = cast_ptr<PetscMatrixBase<T> *>(&pre_in);
  PetscVector<T> * x   = cast_ptr<PetscVector<T> *>(&x_in);
  PetscVector<T> * r   = cast_ptr<PetscVector<T> *>(&r_in);
965  
966  
967  
968 +
969  
970  
971  
  // Only set the jacobian function if we've been provided with something to call.
  // This allows a user to set their own jacobian function if they want to
  if (this->jacobian || this->jacobian_object || this->residual_and_jacobian_object)
    LibmeshPetscCall(SNESSetJacobian (_snes, jac->mat(), pre->mat(), libmesh_petsc_snes_jacobian, this));

  // Have the Krylov subspace method use our good initial guess rather than 0
  KSP ksp;

src/systems/nonlinear_implicit_system.C

38  
39  
40  
41 +
42 +
43  
44  
45  
  nonlinear_solver          (NonlinearSolver<Number>::build(*this)),
  diff_solver               (),
  _n_nonlinear_iterations   (0),
  _final_nonlinear_residual (1.e20),
  _operator_matrix          (nullptr)
{
  // Set default parameters
  // These were chosen to match the Petsc defaults
132  
133  
134  
135  
136  
137  
138  
    es.parameters.get<unsigned int>("nonlinear solver maximum function evaluations");

  const double abs_resid_tol = parameters.have_parameter<Real>("nonlinear solver absolute residual tolerance") ?
    double(parameters.get<Real>("nonlinear solver absolute residual tolerance")) :
    double(es.parameters.get<Real>("nonlinear solver absolute residual tolerance"));

  const double rel_resid_tol = parameters.have_parameter<Real>("nonlinear solver relative residual tolerance") ?
214  
215  
216  
217  
218  
219  
220  
  else
    {
      if (this->prefix_with_name())
        nonlinear_solver->init(this->prefix().c_str());
      else
        nonlinear_solver->init();

228  
229  
230  
231 +
232 +
233 +
234 +
235 +
236  
237 +
238 +
239 +
240 +
241  
242  
243  
      // If a distinct Jacobian operator matrix has been registered (see
      // set_operator_matrix()), use it as Amat while *matrix remains the preconditioning matrix
      // (Pmat); otherwise use the ordinary single-matrix solve.
      if (_operator_matrix)
        std::tie(_n_nonlinear_iterations, _final_nonlinear_residual) =
          nonlinear_solver->solve (*_operator_matrix, *matrix, *solution, *rhs,
                                   nonlinear_solver->relative_residual_tolerance,
                                   nonlinear_solver->max_linear_iterations);
      else
        std::tie(_n_nonlinear_iterations, _final_nonlinear_residual) =
          nonlinear_solver->solve (*matrix, *solution, *rhs,
                                   nonlinear_solver->relative_residual_tolerance,
                                   nonlinear_solver->max_linear_iterations);
    }

  // Update the system after the solve