| Base 54e0d5 | Head #4557 17737b | ||||
|---|---|---|---|---|---|
| Total | Total | +/- | New | ||
| Rate | 65.99% | 66.00% | +0.01% | 100.00% | |
| Hits | 79562 | 79591 | +29 | 42 | |
| Misses | 40996 | 40996 | - | 0 | |
| Filename | Stmts | Miss | Cover |
|---|---|---|---|
| src/mesh/exodusII_io_helper.C | +29 | +1 | +0.08% |
| src/mesh/replicated_mesh.C | 0 | -1 | +0.22% |
| TOTAL | +29 | 0 | +0.01% |
codecodecode+
852 853 854 855 856 857 858 859 860 |
if (old_n) { *old_n = p; old_n->processor_id() = proc_id; return old_n; } Node * n = Node::build(p, id).release(); |
1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 |
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); |
212 213 214 215 + 216 + 217 + 218 219 220 |
// (for example a mix of C0POLYHEDRON and HEX8 cells) is split across // multiple blocks rather than written as a single, invalid block. std::map<subdomain_id_type, std::map<ElemType, std::vector<unsigned int>>> elems_by_subdomain_type; subdomain_id_type max_subdomain_id = 0; bool have_elems = false; for (const auto & elem : mesh.active_element_ptr_range()) { |
224 225 226 227 + 228 + 229 + 230 + 231 + 232 233 234 |
if (elem->infinite()) continue; const subdomain_id_type sbd_id = elem->subdomain_id(); elems_by_subdomain_type[sbd_id][elem->type()].push_back(elem->id()); max_subdomain_id = have_elems ? std::max(max_subdomain_id, sbd_id) : sbd_id; have_elems = true; } // Assign a block id to each (subdomain, element type) group. The // first element type in each subdomain keeps the subdomain id as its |
236 237 238 239 + 240 + 241 242 + 243 244 + 245 + 246 247 + 248 249 + 250 + 251 + 252 253 254 255 256 257 + 258 + 259 260 261 262 263 264 + 265 + 266 267 + 268 + 269 270 271 |
// exactly as before. Any additional element types in the same // subdomain get synthesized block ids allocated above all existing // subdomain ids. std::map<subdomain_id_type, std::vector<unsigned int>> subdomain_map; subdomain_id_type next_synth_block_id = have_elems ? max_subdomain_id + 1 : 0; for (auto & [sbd_id, type_map] : elems_by_subdomain_type) { bool first_type = true; for (auto & [elem_t, elem_ids] : type_map) { libmesh_ignore(elem_t); const subdomain_id_type block_id = first_type ? sbd_id : next_synth_block_id++; first_type = false; subdomain_map[block_id] = std::move(elem_ids); } } // Real element blocks occupy the ids below subdomain_id_end; any // blocks synthesized for visualization sides are numbered after them. if (!subdomain_map.empty()) subdomain_id_end = subdomain_map.rbegin()->first + 1; // If we've been asked to add side elements, those go in their own // blocks. We don't have any ids to list for elements that don't // explicitly exist in the mesh, but we add an entry to keep track of // the number of elements we'll add in each new block. if (add_sides) for (const auto & elem : mesh.active_element_ptr_range()) { if (elem->infinite()) continue; for (auto s : elem->side_index_range()) { |
273 274 275 276 + 277 278 279 280 281 + 282 283 + 284 285 286 287 288 289 + 290 291 292 |
continue; const subdomain_id_type side_block_id = cast_int<subdomain_id_type>(subdomain_id_end + elem->side_type(s)); // Guard the invariant above (also catches subdomain_id_type // overflow wrapping a side block id back down onto an // element block id). libmesh_assert_greater_equal(side_block_id, subdomain_id_end); auto & marker = subdomain_map[side_block_id]; if (marker.empty()) marker.push_back(1); else ++marker[0]; } } // Allocate optional block IDs after both mesh subdomains and any blocks // synthesized for visualization sides. |
3066 3067 3068 3069 + 3070 + 3071 3072 + 3073 3074 + 3075 3076 3077 3078 3079 3080 3081 + 3082 + 3083 + 3084 + 3085 3086 3087 3088 3089 + 3090 + 3091 + 3092 + 3093 + 3094 + 3095 + 3096 3097 3098 |
// detect such synthesized blocks from the mismatch between the // block id and the actual subdomain of the elements it holds. const subdomain_id_type elem_subdomain_id = mesh.elem_ref(element_id_vec[0]).subdomain_id(); const bool is_synthesized_block = (subdomain_id != elem_subdomain_id); std::string block_name = mesh.subdomain_name(elem_subdomain_id); if (is_synthesized_block) { // Prefix the (original) subdomain's name with the element // type, so the synthesized block is identifiable and its // name stays distinct from the block that kept the // subdomain id. This block becomes its own subdomain when // the file is read back in. const std::string type_suffix = Utility::enum_to_string<ElemType>(elem_t); block_name = block_name.empty() ? (std::to_string(elem_subdomain_id) + "_" + type_suffix) : (block_name + "_" + type_suffix); // Informational: keep it to one rank so parallel (Nemesis) // writes don't repeat it once per processor. // NOTE might miss logs if only occurs on other ranks if (this->processor_id() == 0) libMesh::out << "ExodusII_IO: subdomain " << elem_subdomain_id << " contains more than one element type; writing its " << type_suffix << " elements to a new block \"" << block_name << "\" (block id " << subdomain_id << "), which will be read back as a separate subdomain." << std::endl; } if (block_name.empty() && elem_t == C0POLYGON) |
483 484 485 486 487 488 489 |
// if the node already exists, then assign new (x,y,z) values if (n) *n = p; // otherwise build a new node, put it in the right spot, and return // a valid pointer. else |