libMesh/libmesh: coverage diff

Base 7aa2c3 Head #4308 b969c4
Total Total +/- New
Rate 65.12% 65.13% +0.01% 96.05%
Hits 77130 77161 +31 73
Misses 41305 41307 +2 3
Filename Stmts Miss Cover
src/mesh/exodusII_io.C +7 -1 +0.28%
src/mesh/exodusII_io_helper.C +26 +3 -0.01%
TOTAL +33 +2 +0.01%
code
coverage unchanged
code
coverage increased
code
coverage decreased
+
line added or modified

include/mesh/mesh_base.h

458  
459  
460  
461 +
462  
463  
464  
  /**
   * \returns The next unique id to be used.
   */
  unique_id_type next_unique_id() const { return _next_unique_id; }

  /**
   * Sets the next available unique id to be used.  On a

src/mesh/exodusII_io.C

134  
135  
136  
137 +
138  
139  
140  
#endif
  _allow_empty_variables(false),
  _write_complex_abs(true),
  _set_unique_ids_from_maps(false),
  _disc_bex(false)
{
  // if !LIBMESH_HAVE_EXODUS_API, we didn't use this
158  
159  
160  
161 +
162  
163  
164  
#endif
  _allow_empty_variables(false),
  _write_complex_abs(true),
  _set_unique_ids_from_maps(false),
  _disc_bex(false)
{
  // if !LIBMESH_HAVE_EXODUS_API, we didn't use this
327  
328  
329  
330 +
331  
332  
333  
334  
335  
336 +
337  
338  
339 +
340  
341  
342  
343 +
344  
345  
346  
  std::unordered_map<const Node *, Elem *> spline_nodeelem_ptrs;

  // Loop over the nodes, create Nodes with local processor_id 0.
  for (auto i : make_range(exio_helper->num_nodes))
    {
      // Determine the libmesh node id implied by "i". The
      // get_libmesh_node_id() helper function expects a 1-based
      // Exodus node id, so we construct the "implied" Exodus node id
      // from "i" by adding 1.
      auto libmesh_node_id = exio_helper->get_libmesh_node_id(/*exodus_node_id=*/i+1);

      // Catch the node that was added to the mesh
      Node * added_node = mesh.add_point (Point(exio_helper->x[i], exio_helper->y[i], exio_helper->z[i]), libmesh_node_id);

      // Sanity check: throw an error if the Mesh assigned an ID to
      // the Node which does not match the libmesh_id we just determined.
      libmesh_error_msg_if(added_node->id() != static_cast<unsigned>(libmesh_node_id),
                           "Error!  Mesh assigned node ID "
                           << added_node->id()
                           << " which is different from the (zero-based) Exodus ID "
349  
350  
351  
352 +
353  
354  
355  

      // If the _set_unique_ids_from_maps flag is true, set the
      // unique_id for "node", otherwise do nothing.
      exio_helper->conditionally_set_node_unique_id(mesh, added_node, i);

      // If we have a set of spline weights, these nodes are going to
      // be used as control points for Bezier elements, and we need
358  
359  
360  
361  
362  
363  
364  
      if (weights_exist)
        {
          const auto w = exio_helper->w[i];
          Point & p = *added_node;
          p /= w;  // Exodus Bezier Extraction stores spline nodes in projective space

          added_node->set_extra_datum<Real>(weight_index, exio_helper->w[i]);
469  
470  
471  
472 +
473  
474 +
475  
476  
477  
          // ExodusII_IO_Helper::get_libmesh_elem_id() helper function
          // expects a 1-based Exodus elem id, so we construct the
          // "implied" Exodus elem id from "j" by adding 1.
          auto libmesh_elem_id = exio_helper->get_libmesh_elem_id(/*exodus_elem_id=*/j+1);

          uelem->set_id(libmesh_elem_id);

          // Record that we have seen an element of dimension uelem->dim()
          elems_of_dimension[uelem->dim()] = true;
481  
482  
483  
484 +
485  
486  
487  
488 +
489  
490  
491  

          // If the _set_unique_ids_from_maps flag is true, set the
          // unique_id for "elem", otherwise do nothing.
          exio_helper->conditionally_set_elem_unique_id(mesh, elem, j);

          // If the Mesh assigned an ID different from the one we
          // tried to give it, we should probably error.
          libmesh_error_msg_if(elem->id() != static_cast<unsigned>(libmesh_elem_id),
                               "Error!  Mesh assigned ID "
                               << elem->id()
                               << " which is different from the (zero-based) Exodus ID "
543  
544  
545  
546 +
547  
548  
549 +
550  
551  
552 +
553  
554  
555  
              for (int k=0; k<exio_helper->num_nodes_per_elem; k++)
                {
                  // Get index into this block's connectivity array
                  int gi = elem_num * exio_helper->num_nodes_per_elem + conv.get_node_map(k);

                  // Get the 1-based Exodus node id from the "connect" array
                  auto exodus_node_id = exio_helper->connect[gi];

                  // Convert this index to a libMesh Node id
                  auto libmesh_node_id = exio_helper->get_libmesh_node_id(exodus_node_id);

                  // Set the node pointer in the Elem
                  elem->set_node(k, mesh.node_ptr(libmesh_node_id));
620  
621  
622  
623 +
624  
625  
626 +
627  
628  
629 +
630  
631  
632  
                        libmesh_vector_at(coef_vec, elem_node_index);

                      // Get the libMesh node corresponding to that row
                      const int gi = elem_num * exio_helper->bex_num_elem_cvs + spline_node_index;

                      // Get the 1-based Exodus node id from the "connect" array
                      auto exodus_node_id = exio_helper->connect[gi];

                      // Convert this index to a libMesh Node id
                      auto libmesh_node_id = exio_helper->get_libmesh_node_id(exodus_node_id);

                      if (coef != 0) // Ignore irrelevant spline nodes
                        key.emplace_back(libmesh_node_id, coef);
720  
721  
722  
723 +
724  
725  
726  
        // Call helper function to get the libmesh Elem id for the
        // e'th entry in the current elem_list.
        dof_id_type libmesh_elem_id =
          exio_helper->get_libmesh_elem_id(exio_helper->elem_list[e]);

        // Set any relevant node/edge maps for this element
        Elem & elem = mesh.elem_ref(libmesh_elem_id);
816  
817  
818  
819 +
820  
821  
822  
           // Call helper function to get the libmesh Elem id for the
           // e'th entry in the current elemset_list.
           dof_id_type libmesh_elem_id =
             exio_helper->get_libmesh_elem_id(exio_helper->elemset_list[e]);

            // Get a pointer to this Elem
            Elem * elem = mesh.elem_ptr(libmesh_elem_id);
892  
893  
894  
895 +
896 +
897 +
898  
899  
900  

        for (int i=0; i<exio_helper->num_nodes_per_set[nodeset]; ++i)
          {
            int exodus_node_id = exio_helper->node_sets_node_list[i + offset];
            auto libmesh_node_id = exio_helper->get_libmesh_node_id(exodus_node_id);
            mesh.get_boundary_info().add_node(libmesh_node_id, nodeset_id);
          }
      }
  }
963  
964  
965  
966 +
967  
968 +
969  
970  
971  
972  
973 +
974 +
975  
976  
977  
  _write_complex_abs = val;
}

void ExodusII_IO::set_unique_ids_from_maps (bool val)
{
  _set_unique_ids_from_maps = val;

  // Set this flag on the helper object as well. The helper needs to know about this
  // flag, since it sometimes needs to construct libmesh Node ids from nodal connectivity
  // arrays (see e.g. ExodusII_IO_Helper::read_edge_blocks()).
  exio_helper->set_unique_ids_from_maps = val;
}

void ExodusII_IO::use_mesh_dimension_instead_of_spatial_dimension(bool val)
{

src/mesh/exodusII_io_helper.C

286  
287  
288  
289 +
290  
291  
292  
  num_nodal_vars(0),
  num_elem_vars(0),
  verbose(v),
  set_unique_ids_from_maps(false),
  opened_for_writing(false),
  opened_for_reading(false),
  _run_only_on_proc0(run_only_on_proc0),
1409  
1410  
1411  
1412 +
1413  
1414  
1415  
1416  
1417 +
1418 +
1419  
1420  
1421  

          // Loop over indices in connectivity array, build edge elements,
          // look them up in the edge_map.
          for (auto [i, sz] = std::make_tuple(0u, connect.size()); i<sz; i+=num_nodes_per_edge)
            {
              auto edge = Elem::build(conv.libmesh_elem_type());
              for (int n=0; n<num_nodes_per_edge; ++n)
                {
                  auto exodus_node_id = this->connect[i+n];
                  dof_id_type libmesh_node_id = this->get_libmesh_node_id(exodus_node_id);
                  edge->set_node(n, mesh.node_ptr(libmesh_node_id));
                }

1868  
1869  
1870  
1871 +
1872  
1873  
1874  
    }

  // Clear out any previously read nodal variable values
  this->nodal_var_values.clear();

  std::vector<Real> unmapped_nodal_var_values(num_nodes);

1883  
1884  
1885  
1886 +
1887  
1888  
1889  
     MappedInputVector(unmapped_nodal_var_values, _single_precision).data());
  EX_CHECK_ERR(ex_err, "Error reading nodal variable values!");

  for (auto i : make_range(num_nodes))
    {
      // Determine the libmesh node id implied by "i". The
      // get_libmesh_node_id() helper function expects a 1-based
1894  
1895  
1896  
1897 +
1898  
1899  
1900 +
1901  
1902  
1903  
      // true, then calling get_libmesh_node_id(i+1) will just return
      // i, otherwise it will determine the value (with error
      // checking) using this->node_num_map.
      auto libmesh_node_id = this->get_libmesh_node_id(/*exodus_node_id=*/i+1);

      // Store the nodal value in the map.
      this->nodal_var_values[libmesh_node_id] = unmapped_nodal_var_values[i];
    }
}

2139  
2140  
2141  
2142 +
2143  
2144  
2145 +
2146  
2147  
2148  
2149  
2150  
2151 +
2152  
2153  
2154  
2155 +
2156  
2157 +
2158  
2159  
2160 +
2161  
2162 +
2163  
2164  
2165  
2166 +
2167  
2168  
2169  
2170  
2171  
2172  
2173 +
2174  
2175  
2176  
2177  
2178 +
2179 +
2180  
2181  
2182  
          // index "ex_el_num".  This function expects a one-based
          // index, so we add 1 to ex_el_num when we pass it in.
          auto libmesh_elem_id =
            this->get_libmesh_elem_id(ex_el_num + 1);

          // Store the elemental value in the map.
          elem_var_value_map[libmesh_elem_id] = block_elem_var_values[j];

          // Go to the next sequential element ID.
          ex_el_num++;
        }
    }
}



dof_id_type ExodusII_IO_Helper::get_libmesh_node_id(int exodus_node_id)
{
  return this->get_libmesh_id(exodus_node_id, this->node_num_map);
}

dof_id_type ExodusII_IO_Helper::get_libmesh_elem_id(int exodus_elem_id)
{
  return this->get_libmesh_id(exodus_elem_id, this->elem_num_map);
}

dof_id_type
ExodusII_IO_Helper::get_libmesh_id(int exodus_id,
                                   const std::vector<int> & num_map)
{
  // The input exodus_id is assumed to be a (1-based) index into
  // the {node,elem}_num_map, so in order to use exodus_id as an index
  // in C++, we need to first make it zero-based.
  auto exodus_id_zero_based =
    cast_int<dof_id_type>(exodus_id - 1);

  // Throw an informative error message rather than accessing past the
  // end of the provided num_map. If we are setting Elem unique_ids
  // based on the num_map, we don't need to do this check.
  if (!this->set_unique_ids_from_maps)
    libmesh_error_msg_if(exodus_id_zero_based >= num_map.size(),
                         "Cannot get LibMesh id for Exodus id: " << exodus_id);

  // If the user set the flag which stores Exodus node/elem ids as
2186  
2187  
2188  
2189 +
2190 +
2191 +
2192  
2193 +
2194  
2195  
2196  
2197  
2198  
2199 +
2200  
2201  
2202 +
2203 +
2204  
2205  
2206 +
2207  
2208  
2209 +
2210 +
2211  
2212  
2213 +
2214  
2215  
2216  
2217  
2218 +
2219  
2220  
2221  
2222  
2223  
2224 +
2225  
2226  
2227 +
2228  
2229  
2230  
  // *and* then subtract 1 from that because the entries in the
  // num_map are also 1-based.
  dof_id_type libmesh_id =
    this->set_unique_ids_from_maps ?
    cast_int<dof_id_type>(exodus_id_zero_based) :
    cast_int<dof_id_type>(num_map[exodus_id_zero_based] - 1);

  return libmesh_id;
}



void
ExodusII_IO_Helper::
conditionally_set_node_unique_id(MeshBase & mesh, Node * node, int zero_based_node_num_map_index)
{
  this->set_dof_object_unique_id(mesh, node, libmesh_vector_at(this->node_num_map, zero_based_node_num_map_index));
}

void
ExodusII_IO_Helper::
conditionally_set_elem_unique_id(MeshBase & mesh, Elem * elem, int zero_based_elem_num_map_index)
{
  this->set_dof_object_unique_id(mesh, elem, libmesh_vector_at(this->elem_num_map, zero_based_elem_num_map_index));
}

void
ExodusII_IO_Helper::set_dof_object_unique_id(
  MeshBase & mesh,
  DofObject * dof_object,
  int exodus_mapped_id)
{
  if (this->set_unique_ids_from_maps)
  {
    // Exodus ids are always 1-based while libmesh ids are always
    // 0-based, so to make a libmesh unique_id here, we subtract 1
    // from the exodus_mapped_id to make it 0-based.
    auto exodus_mapped_id_zero_based =
      cast_int<dof_id_type>(exodus_mapped_id - 1);

    // Set added_node's unique_id to "exodus_mapped_id_zero_based".
    dof_object->set_unique_id(cast_int<unique_id_type>(exodus_mapped_id_zero_based));

    // Normally the Mesh is responsible for setting the unique_ids
    // of Nodes/Elems in a consistent manner, so when we set the unique_id
2235  
2236  
2237  
2238 +
2239 +
2240  
2241  
2242  
    // APIs for doing this are only defined when unique ids are
    // enabled.
#ifdef LIBMESH_ENABLE_UNIQUE_ID
    unique_id_type next_unique_id = mesh.next_unique_id();
    mesh.set_next_unique_id(std::max(next_unique_id, static_cast<unique_id_type>(exodus_mapped_id_zero_based + 1)));
#else
    // Avoid compiler warnings about the unused variable
    libmesh_ignore(mesh);
2581  
2582  
2583  
2584 +
2585 +
2586  
2587 +
2588  
2589  
2590  
          // ids rather than node ids.
          if (!_add_sides)
            {
              if (this->set_unique_ids_from_maps)
                node_num_map.push_back(node.unique_id() + 1);
              else
                node_num_map.push_back(node.id() + 1);
            }

          // Also map the zero-based libmesh node id to the (1-based)
2594  
2595  
2596  
2597 +
2598  
2599  
2600  
          // an Exodus Node id given a libMesh Node id, so it does
          // involve unique_ids.
          libmesh_node_num_to_exodus[ cast_int<int>(node.id()) ] = cast_int<int>(x.size());
        } // end for (node_ptr)
    }
  else // use_discontinuous
    {
2742  
2743  
2744  
2745 +
2746  
2747  
2748  

  // Here we reserve() space so that we can push_back() onto the
  // elem_num_map in the loops below.
  this->elem_num_map.reserve(num_elem);

  // In the case of discontinuous plotting we initialize a map from
  // (element, node) pairs to the corresponding discontinuous node index.
2952  
2953  
2954  
2955 +
2956 +
2957  
2958  
2959  
  // already in the elem_num_map.
  auto next_fake_id = mesh.max_elem_id() + 1; // 1-based numbering in Exodus
#ifdef LIBMESH_ENABLE_UNIQUE_ID
  if (this->set_unique_ids_from_maps)
    next_fake_id = mesh.next_unique_id();
#endif

  for (auto & [subdomain_id, element_id_vec] : subdomain_map)
2975  
2976  
2977  
2978 +
2979  
2980 +
2981  
2982  
2983  
      // element ids to add.
      if (subdomain_id < subdomain_id_end)
      {
        connect.resize(element_id_vec.size()*num_nodes_per_elem);

        for (auto i : index_range(element_id_vec))
        {
          unsigned int elem_id = element_id_vec[i];
          libmesh_elem_num_to_exodus[elem_id] = ++libmesh_elem_num_to_exodus_counter; // 1-based indexing for Exodus
3030  
3031  
3032  
3033 +
3034 +
3035  
3036 +
3037  
3038  
3039  
          // push_back() either elem_id+1 or the current Elem's
          // unique_id+1 into the elem_num_map, depending on the value
          // of the set_unique_ids_from_maps flag.
          if (this->set_unique_ids_from_maps)
            this->elem_num_map.push_back(elem.unique_id() + 1);
          else
            this->elem_num_map.push_back(elem_id + 1);

        } // end for(i)
      }
3079  
3080  
3081  
3082 +
3083 +
3084  
3085  
3086  
        // Store num_elem_this_blk "fake" ids into the
        // elem_num_map. Use a traditional for-loop to avoid unused
        // variable warnings about the loop counter.
        for (int i=0; i<num_elem_this_blk; ++i)
          this->elem_num_map.push_back(next_fake_id++);
      }

      ++num_elem_this_blk_it;