libMesh/libmesh: coverage diff

Base 332933 Head #4250 d9a2b9
Total Total +/- New
Rate 64.79% 64.79% -0.00% 82.33%
Hits 76453 76488 +35 177
Misses 41544 41567 +23 38
Filename Stmts Miss Cover
include/base/dof_map.h +58 +3 -0.02%
include/base/variable.h -11 0 +100.00%
include/systems/system.h -27 0 -9.78%
src/base/dof_map.C +111 +29 -0.93%
src/mesh/mesh_refinement.C 0 +2 -0.29%
src/mesh/mesh_triangle_holes.C 0 +1 -0.27%
src/systems/system.C -73 -12 -1.19%
TOTAL +58 +23 -0.00%
code
coverage unchanged
code
coverage increased
code
coverage decreased
+
line added or modified

include/base/dof_map.h

2859  
2860  
2861  
2862 +
2863  
2864 +
2865  
2866  
2867  
2868 +
2869  
2870 +
2871  
2872 +
2873 +
2874  
2875 +
2876  
2877  
2878  
2879 +
2880  
2881  
2882  
2883 +
2884 +
2885  
2886 +
2887  
2888 +
2889  
2890 +
2891 +
2892  
2893 +
2894  
2895  
2896 +
2897 +
2898 +
2899 +
2900 +
2901  
2902 +
2903  
2904 +
2905 +
2906 +
2907  
2908 +
2909 +
2910 +
2911  
2912  
2913  
2914 +
2915 +
2916 +
2917  
2918 +
2919 +
2920  
2921  
2922  
2923 +
2924  
2925  
2926 +
2927  
2928 +
2929  
2930  
2931  
2932 +
2933  
2934 +
2935  
2936 +
2937  
2938  
2939  
2940 +
2941  
2942 +
2943  
2944  
2945  
2946 +
2947  
2948 +
2949 +
2950  
2951  
2952 +
2953  
2954 +
2955 +
2956  
2957 +
2958 +
2959  
2960  
2961  
2962  
2963 +
2964  
2965  
2966 +
2967  
2968  
2969  
2970 +
2971  
2972 +
2973  
2974  
2975 +
2976  
2977 +
2978  
2979  
2980 +
2981  
2982 +
2983 +
2984 +
2985  
2986  
2987  
}

inline const std::pair<unsigned int, unsigned int> &
DofMap::get_variable_array(const unsigned int vi) const
{
  auto it = std::upper_bound(
      _array_variables.begin(),
      _array_variables.end(),
      vi,
      [](unsigned int value, const std::pair<unsigned int, unsigned int> & b) { return value < b.first; });

  libmesh_assert_msg(it != _array_variables.begin(),
                     "Passed in " << std::to_string(vi) << " is not in any of our array variables");
  --it;
  libmesh_assert_msg(vi < it->second,
                     "Passed in " << std::to_string(vi) << " is not in any of our array variables");
  return *it;
}

template <typename DofIndicesFunctor>
void DofMap::array_dof_indices(const DofIndicesFunctor & functor,
                               std::vector<dof_id_type> & di,
                               const unsigned int vn) const
{
  const auto [begin, end] = this->get_variable_array(vn);
  functor(di, begin);

  const unsigned int count = end - begin;
  // We make count, which could be >> ntest, the inner index in hopes of vectorization
  if (count > 1)
    {
      const dof_id_type component_size = di.size();
      di.resize(count * component_size);

      const auto pack_container = [&di,
                                   component_size](const unsigned int j,
                                                   const std::vector<dof_id_type> & j_dof_indices,
                                                   const unsigned int stride) {
        if (&j_dof_indices != &di)
          libmesh_assert(j_dof_indices.size() == component_size);
        for (const auto i : make_range(component_size))
          di[j * component_size + i] = j_dof_indices[i] + stride * j;
      };
      pack_container(0, di, 0);

      const auto & fe_type = _variable_groups[libmesh_map_find(_var_to_vg, vn)].type();
      if (const bool lagrange = fe_type.family == LAGRANGE;
          lagrange || (FEInterface::get_continuity(fe_type) == DISCONTINUOUS))
        {
          const auto stride = lagrange ? 1 : component_size;
          for (const auto j : make_range((unsigned int)1, count))
            pack_container(j, di, stride);
        }
      else
        {
          static thread_local std::vector<dof_id_type> work_dof_indices;
          unsigned int j = 1;
          for (const auto i : make_range(begin + 1, end))
            {
              functor(work_dof_indices, i);
              pack_container(j++, work_dof_indices, 0);
            }
        }
    }
}

inline
unsigned int DofMap::n_vars() const
{
  return cast_int<unsigned int>(_variables.size());
}

inline
const std::string & DofMap::variable_name (const unsigned int i) const
{
  libmesh_assert_less (i, _variables.size());

  return _variables[i].name();
}

inline
bool DofMap::identify_variable_groups () const
{
  return _identify_variable_groups;
}

inline
void DofMap::identify_variable_groups (const bool ivg)
{
  _identify_variable_groups = ivg;
}

inline
unsigned int DofMap::n_components(const MeshBase & mesh) const
{
  if (_variables.empty())
    return 0;

  const Variable & last = _variables.back();
  return last.first_scalar_number() + last.n_components(mesh);
}

inline
unsigned int
DofMap::variable_scalar_number (unsigned int var_num,
                                unsigned int component) const
{
  return _variables[var_num].first_scalar_number() + component;
}

inline
const FEType & DofMap::variable_type (std::string_view var) const
{
  return _variables[this->variable_number(var)].type();
}

inline bool DofMap::has_variable(std::string_view var) const
{
  return _variable_numbers.count(var);
}

inline unsigned int DofMap::variable_number(std::string_view var) const
{
  auto var_num = libmesh_map_find(_variable_numbers, var);
  libmesh_assert_equal_to(_variables[var_num].name(), var);
  return var_num;
}

} // namespace libMesh

src/base/dof_map.C

916  
917  
918  
919 +
920  
921  
922  
  _variable_groups.clear();
  _var_to_vg.clear();
  _variable_group_numbers.clear();
  _array_variables.clear();
  _first_scalar_df.clear();
  this->clear_send_list();
  this->clear_sparsity();
1940  
1941  
1942  
1943 +
1944 +
1945 +
1946  
1947  
1948  
    bool all_discontinuous_dofs = true;

    // We may call this method even without ever having initialized our data
      for (auto var : index_range(this->_variables))
        if (FEInterface::get_continuity(this->variable_type(var)) !=  DISCONTINUOUS)
          all_discontinuous_dofs = false;

    if (all_discontinuous_dofs)
      implicit_neighbor_dofs = true;
2330  
2331  
2332  
2333 +
2334  
2335 +
2336  
2337  
2338  
2339  
2340 +
2341 +
2342 +
2343 +
2344 +
2345 +
2346  
2347 +
2348  
2349  
2350  
2351  
2352 +
2353 +
2354 +
2355 +
2356  
2357  
2358  
2359  
         std::vector<dof_id_type> & dof_indices,
         const dof_id_type dof) { dof_indices.push_back(dof); },
      p_level);
}

void DofMap::array_dof_indices(const Elem * const elem,
                               std::vector<dof_id_type> & di,
                               const unsigned int vn,
                               int p_level) const
{
  auto dof_indices_functor = [elem, p_level, this](std::vector<dof_id_type> & functor_di,
                                                   const unsigned int functor_vn) {
    this->dof_indices(elem, functor_di, functor_vn, p_level);
  };
  this->array_dof_indices(dof_indices_functor, di, vn);
}

void DofMap::array_dof_indices(const Node * const node,
                               std::vector<dof_id_type> & di,
                               const unsigned int vn) const
{
  auto dof_indices_functor = [node, this](std::vector<dof_id_type> & functor_di,
                                          const unsigned int functor_vn) {
    this->dof_indices(node, functor_di, functor_vn);
  };
  this->array_dof_indices(dof_indices_functor, di, vn);
}

void DofMap::dof_indices (const Node * const node,
                          std::vector<dof_id_type> & di) const
3139  
3140  
3141  
3142 +
3143  
3144  
3145  
3146  
3147 +
3148  
3149 +
3150 +
3151 +
3152  
3153 +
3154 +
3155  
3156  
3157  
3158 +
3159 +
3160  
3161 +
3162  
3163  
3164  
3165  
3166  
3167  
3168 +
3169  
3170  
3171  
3172 +
3173 +
3174  
3175  
3176  
3177  
3178 +
3179  
3180  
3181 +
3182 +
3183  
3184  
3185 +
3186  
3187  
3188  
3189 +
3190  
3191 +
3192  
3193  
3194  
    _sc->reinit();
}

unsigned int DofMap::add_variable(System & sys,
                                  std::string_view var,
                                  const FEType & type,
                                  const std::set<subdomain_id_type> * const active_subdomains)
{
  parallel_object_only(); // Not strictly needed, but the only safe way to keep in sync

  libmesh_assert(this->comm().verify(std::string(var)));
  libmesh_assert(this->comm().verify(type));
  libmesh_assert(this->comm().verify((active_subdomains == nullptr)));

  if (active_subdomains)
    libmesh_assert(this->comm().verify(active_subdomains->size()));

  // Make sure the variable isn't there already
  // or if it is, that it's the type we want
  for (auto v : make_range(this->n_vars()))
    if (this->variable_name(v) == var)
      {
        if (this->variable_type(v) == type)
          {
            // Check whether the existing variable's active subdomains also matches
            // the incoming variable's active subdomains. If they don't match, then
            // either it is an error by the user or the user is trying to change the
            // subdomain restriction after the variable has already been added, which
            // is not supported.
            const Variable & existing_var = this->variable(v);

            // Check whether active_subdomains is not provided/empty and the existing_var is
            // implicitly_active()
            bool check1 = (!active_subdomains || active_subdomains->empty()) &&
                          existing_var.implicitly_active();

            // Check if the provided active_subdomains is equal to the existing_var's
            // active_subdomains
            bool check2 =
                (active_subdomains && (*active_subdomains == existing_var.active_subdomains()));

            // If either of these checks passed, then we already have this variable
            if (check1 || check2)
              return _variables[v].number();
          }

        libmesh_error_msg("ERROR: incompatible variable "
                          << var << " has already been added for this system!");
      }

  libmesh_assert(!sys.is_initialized());

  if (this->n_variable_groups())
    {
      // Optimize for VariableGroups here - if the user is adding multiple
      // variables of the same FEType and subdomain restriction, catch
3196  
3197  
3198  
3199 +
3200  
3201 +
3202  
3203  
3204  
3205 +
3206  
3207  
3208 +
3209 +
3210  
3211  
3212 +
3213 +
3214 +
3215  
3216  
3217 +
3218 +
3219  
3220 +
3221  
3222 +
3223 +
3224  
3225  
3226  
3227 +
3228  
3229 +
3230  
3231 +
3232  
3233 +
3234 +
3235 +
3236 +
3237 +
3238 +
3239  
3240 +
3241  
3242  
3243  
3244  
3245 +
3246 +
3247  
3248  
3249 +
3250  
3251  
3252  
3253  
3254 +
3255  
3256 +
3257  
3258 +
3259 +
3260 +
3261  
3262 +
3263 +
3264  
3265  
3266  
3267 +
3268  
3269 +
3270  
3271 +
3272 +
3273  
3274 +
3275 +
3276  
3277 +
3278  
3279  
3280  
3281  
3282 +
3283  
3284  
3285  
      //
      // start by setting this flag to whatever the user has requested
      // and then consider the conditions which should negate it.
      bool should_be_in_vg = this->identify_variable_groups();

      VariableGroup & vg = _variable_groups.back();

      // get a pointer to their subdomain restriction, if any.
      const std::set<subdomain_id_type> * const their_active_subdomains(
          vg.implicitly_active() ? nullptr : &vg.active_subdomains());

      // Different types?
      if (vg.type() != type)
        should_be_in_vg = false;

      // they are restricted, we aren't?
      if (their_active_subdomains &&
          (!active_subdomains || (active_subdomains && active_subdomains->empty())))
        should_be_in_vg = false;

      // they aren't restricted, we are?
      if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
        should_be_in_vg = false;

      if (their_active_subdomains && active_subdomains)
        // restricted to different sets?
        if (*their_active_subdomains != *active_subdomains)
          should_be_in_vg = false;

      // OK, after all that, append the variable to the vg if none of the conditions
      // were violated
      if (should_be_in_vg)
        {
          const unsigned int vn = this->n_vars();

          std::string varstr(var);

          _variable_numbers[varstr] = vn;
          vg.append(std::move(varstr));
          _variables.push_back(vg(vg.n_variables() - 1));
          const unsigned int vgn = _variable_groups.size() - 1;
          _variable_group_numbers.push_back(vgn);
          _var_to_vg.emplace(vn, vgn);

          return vn;
        }
    }

  // otherwise, fall back to adding a single variable group
  return this->add_variables(
      sys, std::vector<std::string>(1, std::string(var)), type, active_subdomains);
}

unsigned int DofMap::add_variables(System & sys,
                                   const std::vector<std::string> & vars,
                                   const FEType & type,
                                   const std::set<subdomain_id_type> * const active_subdomains)
{
  parallel_object_only(); // Not strictly needed, but the only safe way to keep in sync

  libmesh_assert(!sys.is_initialized());

  libmesh_assert(this->comm().verify(vars.size()));
  libmesh_assert(this->comm().verify(type));
  libmesh_assert(this->comm().verify((active_subdomains == nullptr)));

  if (active_subdomains)
    libmesh_assert(this->comm().verify(active_subdomains->size()));

  // Make sure the variable isn't there already
  // or if it is, that it's the type we want
  for (auto ovar : vars)
    {
      libmesh_assert(this->comm().verify(ovar));

      for (auto v : make_range(this->n_vars()))
        if (this->variable_name(v) == ovar)
          {
            if (this->variable_type(v) == type)
              return _variables[v].number();

            libmesh_error_msg("ERROR: incompatible variable "
                              << ovar << " has already been added for this system!");
          }
    }

  if (this->n_variable_groups())
    {
      // Optimize for VariableGroups here - if the user is adding multiple
      // variables of the same FEType and subdomain restriction, catch
3287  
3288  
3289  
3290 +
3291  
3292 +
3293  
3294  
3295  
3296 +
3297  
3298  
3299 +
3300 +
3301  
3302  
3303 +
3304 +
3305 +
3306  
3307  
3308 +
3309 +
3310  
3311 +
3312  
3313 +
3314 +
3315  
3316  
3317  
3318 +
3319  
3320 +
3321 +
3322  
3323 +
3324  
3325 +
3326  
3327 +
3328  
3329 +
3330 +
3331 +
3332 +
3333  
3334 +
3335  
3336  
3337  
3338 +
3339  
3340 +
3341  
3342  
3343  
3344 +
3345  
3346 +
3347  
3348  
3349 +
3350 +
3351  
3352  
3353 +
3354  
3355 +
3356 +
3357 +
3358 +
3359 +
3360  
3361  
3362 +
3363  
3364  
3365  
      //
      // start by setting this flag to whatever the user has requested
      // and then consider the conditions which should negate it.
      bool should_be_in_vg = this->identify_variable_groups();

      VariableGroup & vg = _variable_groups.back();

      // get a pointer to their subdomain restriction, if any.
      const std::set<subdomain_id_type> * const their_active_subdomains(
          vg.implicitly_active() ? nullptr : &vg.active_subdomains());

      // Different types?
      if (vg.type() != type)
        should_be_in_vg = false;

      // they are restricted, we aren't?
      if (their_active_subdomains &&
          (!active_subdomains || (active_subdomains && active_subdomains->empty())))
        should_be_in_vg = false;

      // they aren't restricted, we are?
      if (!their_active_subdomains && (active_subdomains && !active_subdomains->empty()))
        should_be_in_vg = false;

      if (their_active_subdomains && active_subdomains)
        // restricted to different sets?
        if (*their_active_subdomains != *active_subdomains)
          should_be_in_vg = false;

      // If after all that none of the conditions were violated,
      // append the variables to the vg and we're done
      if (should_be_in_vg)
        {
          unsigned int vn = this->n_vars();
          const unsigned int vgn = _variable_groups.size() - 1;

          for (auto ovar : vars)
            {
              vn = this->n_vars();

              vg.append(ovar);

              _variables.push_back(vg(vg.n_variables() - 1));
              _variable_numbers[ovar] = vn;
              _variable_group_numbers.push_back(vgn);
              _var_to_vg.emplace(vn, vgn);
            }
          return vn;
        }
    }

  const unsigned int curr_n_vars = this->n_vars();

  const unsigned int next_first_component = this->n_components(sys.get_mesh());

  // We weren't able to add to an existing variable group, so
  // add a new variable group to the list
  _variable_groups.push_back(
      (active_subdomains == nullptr)
          ? VariableGroup(&sys, vars, curr_n_vars, next_first_component, type)
          : VariableGroup(&sys, vars, curr_n_vars, next_first_component, type, *active_subdomains));

  const VariableGroup & vg(_variable_groups.back());
  const unsigned int vgn = _variable_groups.size() - 1;

  // Add each component of the group individually
  for (auto v : make_range(vars.size()))
    {
      const unsigned int vn = curr_n_vars + v;
      _variables.push_back(vg(v));
      _variable_numbers[vars[v]] = vn;
      _variable_group_numbers.push_back(vgn);
      _var_to_vg.emplace(vn, vgn);
    }

  libmesh_assert_equal_to((curr_n_vars + vars.size()), this->n_vars());

  // BSK - Defer this now to System::init_data() so we can detect
  // VariableGroups 12/28/2012
3367  
3368  
3369  
3370 +
3371  
3372  
3373 +
3374  
3375  
3376  
3377  
3378 +
3379 +
3380 +
3381 +
3382 +
3383  
3384  
3385 +
3386  
3387 +
3388  
3389 +
3390 +
3391 +
3392 +
3393  
3394  
3395  
  // _dof_map->add_variable_group (vg);

  // Return the number of the new variable
  return cast_int<unsigned int>(curr_n_vars + vars.size() - 1);
}

unsigned int DofMap::add_variable_array (System & sys,
                                         const std::vector<std::string> & vars,
                                         const FEType & type,
                                         const std::set<subdomain_id_type> * const active_subdomains)
{
  const unsigned int count = cast_int<unsigned int>(vars.size());
  const unsigned int last_var = this->add_variables(sys, vars, type, active_subdomains);
  const unsigned int first_var = last_var + 1 - count;
  _array_variables.push_back({first_var, first_var + count});
  return last_var;
}

void DofMap::get_all_variable_numbers(std::vector<unsigned int> & all_variable_numbers) const
{
  all_variable_numbers.resize(n_vars());

  unsigned int count = 0;
  for (auto vn : _variable_numbers)
    all_variable_numbers[count++] = vn.second;
}

template LIBMESH_EXPORT bool DofMap::is_evaluable<Elem>(const Elem &, unsigned int) const;
template LIBMESH_EXPORT bool DofMap::is_evaluable<Node>(const Node &, unsigned int) const;

src/mesh/mesh_refinement.C

1272  
1273  
1274  
1275  
1276  
1277  
1278  
1279  
                              if (neighbor->p_level() < my_p_level &&
                                  neighbor->p_refinement_flag() != Elem::REFINE)
                                {
                                  neighbor->set_p_refinement_flag(Elem::REFINE);
                                  level_one_satisfied = false;
                                  compatible_with_coarsening = false;
                                }
                              if (neighbor->p_level() == my_p_level &&

src/mesh/mesh_triangle_holes.C

270  
271  
272  
273  
274  
275  
276  
    {
      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/systems/system.C

1343  
1344  
1345  
1346 +
1347  
1348  
1349  
                                   const FEType & type,
                                   const std::set<subdomain_id_type> * const active_subdomains)
{
  return this->get_dof_map().add_variable(*this, var, type, active_subdomains);
}


1364  
1365  
1366  
1367 +
1368  
1369  
1370  
                                    const FEType & type,
                                    const std::set<subdomain_id_type> * const active_subdomains)
{
  return this->get_dof_map().add_variables(*this, vars, type, active_subdomains);
}


1379  
1380  
1381  
1382 +
1383  
1384  
1385  
1386 +
1387  
1388  
1389  
1390  
1391 +
1392  
1393  
1394  
1395  
1396 +
1397  
1398  
1399  
1400  
1401 +
1402  
1403  
1404  
                             active_subdomains);
}

unsigned int System::add_variable_array (const std::vector<std::string> & vars,
                                         const FEType & type,
                                         const std::set<subdomain_id_type> * const active_subdomains)
{
  return this->get_dof_map().add_variable_array(*this, vars, type, active_subdomains);
}

bool System::has_variable (std::string_view var) const
{
  return this->get_dof_map().has_variable(var);
}

unsigned int System::variable_number (std::string_view var) const
{
  return this->get_dof_map().variable_number(var);
}

void System::get_all_variable_numbers(std::vector<unsigned int> & all_variable_numbers) const
{
  this->get_dof_map().get_all_variable_numbers(all_variable_numbers);
}


2651  
2652  
2653  
2654 +
2655  
2656 +
2657  
2658  
2659 +
2660  
2661 +
2662  
2663  
2664 +
2665  
2666 +
2667  
2668  
2669 +
2670  
2671 +
2672 +
2673  
2674 +
2675  
2676 +
2677  
2678  
2679 +
2680  
2681 +
2682  
2683  
2684 +
2685  
2686 +
2687  
2688  
2689 +
2690  
2691 +
2692  
2693  
2694  
2695 +
2696  
2697  
2698 +
2699  
2700  
2701 +
2702  
2703 +
2704  
2705  
2706 +
2707  
2708 +
2709  
2710  
2711  
  return this->get_dof_map().has_static_condensation();
}

unsigned int System::n_vars() const
{
  return this->get_dof_map().n_vars();
}

const std::string & System::variable_name (const unsigned int i) const
{
  return this->get_dof_map().variable_name(i);
}

bool System::identify_variable_groups () const
{
  return this->get_dof_map().identify_variable_groups();
}

void System::identify_variable_groups (const bool ivg)
{
  this->get_dof_map().identify_variable_groups(ivg);
}

unsigned int System::n_components() const
{
  return this->get_dof_map().n_components(this->get_mesh());
}

unsigned int System::n_variable_groups() const
{
  return this->get_dof_map().n_variable_groups();
}

const Variable & System::variable (const unsigned int i) const
{
  return this->get_dof_map().variable(i);
}

const VariableGroup & System::variable_group (const unsigned int vg) const
{
  return this->get_dof_map().variable_group(vg);
}

unsigned int
System::variable_scalar_number (unsigned int var_num,
                                unsigned int component) const
{
  return this->get_dof_map().variable_scalar_number(var_num, component);
}

const FEType & System::variable_type (const unsigned int i) const
{
  return this->get_dof_map().variable_type(i);
}

const FEType & System::variable_type (std::string_view var) const
{
  return this->get_dof_map().variable_type(var);
}

} // namespace libMesh