Skip to content

Commit f89e06b

Browse files
committed
ExodusII_IO: Fix write_element_data_from_discontinuous_nodal_data()
There was an issue with subdomain restricted variables. I previously did not realize that they would still show up in the discontinuous solution vector (as zero padding) so I was not indexing correctly in that case. This fix should also be cherry-picked onto v1.4.0 since this API is present in that version. Refs libMesh#2029. Refs libMesh#2010.
1 parent e67f42e commit f89e06b

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

src/mesh/exodusII_io.C

+31-13
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,14 @@ ExodusII_IO::write_element_data_from_discontinuous_nodal_data
849849

850850
// A new data structure for keeping track of a list of variable names
851851
// that are in the discontinous solution vector on each subdomain. Used
852-
// for indexing.
852+
// for indexing. Note: if a variable was inactive at the System level,
853+
// an entry for it will still be in the discontinuous solution vector,
854+
// but it will just have a value of zero. On the other hand, when we
855+
// create the derived variable names some of them are "inactive" on
856+
// different subdomains in the sense that they don't exist at all, i.e.
857+
// there is no zero padding for them. We need to be able to distinguish
858+
// between these two types in order to do the indexing into this vector
859+
// correctly.
853860
std::map<subdomain_id_type, std::vector<std::string>>
854861
subdomain_to_var_names;
855862

@@ -884,20 +891,31 @@ ExodusII_IO::write_element_data_from_discontinuous_nodal_data
884891
libmesh_error_msg("Variable " << orig_name << " somehow not found in var_names array.");
885892
auto var_id = std::distance(var_names.begin(), var_loc);
886893

887-
// This derived variable only has a chance of being active
888-
// on the current subdomain if the original variable was
889-
// active on this subdomain.
890-
bool orig_var_active =
891-
(vars_active_subdomains[var_id].empty() ||
892-
vars_active_subdomains[var_id].count(sbd_id));
893-
894-
// If the var was originally active, check whether the
895-
// elements in this subdomain have enough nodes for the
896-
// corresponding derived variable to be active.
897-
if (orig_var_active && node_id < vertices_per_elem_this_sbd)
894+
// The derived_var will only be active if this subdomain has
895+
// enough vertices for that to be the case.
896+
if (node_id < vertices_per_elem_this_sbd)
898897
{
899-
derived_vars_active_subdomains[derived_var_id].insert(sbd_id);
898+
// Regardless of whether the original variable was not active on this subdomain,
899+
// the discontinuous solution vector will have zero padding for it, and
900+
// we will need to account for it. Therefore it should still be added to
901+
// the subdomain_to_var_names data structure!
900902
subdomain_to_var_names[sbd_id].push_back(derived_name);
903+
904+
// If the original variable was not active on the
905+
// current subdomain, it should not be added to the
906+
// derived_vars_active_subdomains data structure, since
907+
// it will not be written to the Exodus file.
908+
909+
// Determine if the original variable was active on the
910+
// current subdomain.
911+
bool orig_var_active =
912+
(vars_active_subdomains[var_id].empty() ||
913+
vars_active_subdomains[var_id].count(sbd_id));
914+
915+
// And only if it was, add it to the
916+
// derived_vars_active_subdomains data structure.
917+
if (orig_var_active)
918+
derived_vars_active_subdomains[derived_var_id].insert(sbd_id);
901919
}
902920
} // end loop over subdomain_id_to_vertices_per_elem
903921
} // end loop over derived_var_names

0 commit comments

Comments
 (0)