Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ejoin assemblies #390

Merged
merged 4 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions packages/seacas/applications/ejoin/EJ_SystemInterface.C
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void SystemInterface::enroll_options()
options_.enroll("version", GetLongOption::NoValue, "Print version and exit", nullptr);

options_.enroll("output", GetLongOption::MandatoryValue, "Name of output file to create",
"ejoin-out.e");
"ejoin-out.e", nullptr, true);

options_.enroll(
"extract_blocks", GetLongOption::MandatoryValue,
Expand All @@ -75,6 +75,19 @@ void SystemInterface::enroll_options()
"\t\t\t '-omit_blocks p1:1:3:4,p2:2:3:4,p5:8'",
nullptr);

options_.enroll("omit_assemblies", GetLongOption::MandatoryValue,
"If no value, then don't transfer any assemblies to output file.\n"
"\t\tIf just p#,p#,... specified, then omit assemblies on specified parts\n"
"\t\tIf p#:id1:id2,p#:id2,id4... then omit the assemblies with the specified\n"
"\t\tid in the specified parts.",
nullptr, "ALL");

options_.enroll(
"omit_part_assemblies", GetLongOption::NoValue,
"Do not create an assembly for each input part containing the blocks in that part.\n"
"\t\tDefault is to create the part assemblies.",
nullptr);

options_.enroll("omit_nodesets", GetLongOption::OptionalValue,
"If no value, then don't transfer any nodesets to output file.\n"
"\t\tIf just p#,p#,... specified, then omit sets on specified parts\n"
Expand All @@ -94,7 +107,7 @@ void SystemInterface::enroll_options()
"\t\tcreate a nodeset containing the nodes of that part\n"
"\t\tand output the nodal fields as nodeset fields instead of nodal fields.\n"
"\t\tFormat is comma-separated list of parts (1-based), or ALL",
nullptr);
nullptr, nullptr, true);

options_.enroll("match_node_ids", GetLongOption::NoValue,
"Combine nodes if their global ids match.", nullptr);
Expand All @@ -115,19 +128,20 @@ void SystemInterface::enroll_options()
#endif

options_.enroll("tolerance", GetLongOption::MandatoryValue,
"Maximum distance between two nodes to be considered colocated.", nullptr);
"Maximum distance between two nodes to be considered colocated.", nullptr,
nullptr, true);

options_.enroll(
"block_prefix", GetLongOption::MandatoryValue,
"Prefix used on the input block names of second and subsequent meshes to make them\n"
"\t\tunique. Default is 'p'. Example: block1, p1_block1, p2_block1.",
"\t\tunique. Default is 'p'. Example: block1, p2_block1, p3_block1.",
"p");

options_.enroll("offset", GetLongOption::MandatoryValue,
"Comma-separated x,y,z offset for coordinates of second and subsequent meshes.\n"
"\t\tThe offset will be multiplied by the part number-1 so:\n"
"\t\tP1: no offset; P2: 1x, 1y, 1z; P3: 2x, 2y, 2z; P(n+1): nx, ny, nz",
nullptr);
nullptr, nullptr, true);

options_.enroll("steps", GetLongOption::MandatoryValue,
"Specify subset of timesteps to transfer to output file.\n"
Expand Down Expand Up @@ -171,7 +185,7 @@ void SystemInterface::enroll_options()
"Ignore the element id maps on the input database and just use a 1..#elements id "
"map on output.\n"
"\t\tMuch faster for large models if do not need specific element global ids",
nullptr);
nullptr, nullptr, true);

options_.enroll("netcdf4", GetLongOption::NoValue,
"Create output database using the HDF5-based "
Expand Down Expand Up @@ -249,6 +263,7 @@ bool SystemInterface::parse_options(int argc, char **argv)
blockInclusions_.resize(part_count);
nsetOmissions_.resize(part_count);
ssetOmissions_.resize(part_count);
assemblyOmissions_.resize(part_count);

// Get options from environment variable also...
char *options = getenv("EJOIN_OPTIONS");
Expand Down Expand Up @@ -303,6 +318,17 @@ bool SystemInterface::parse_options(int argc, char **argv)
}
}

{
const char *temp = options_.retrieve("omit_assemblies");
if (temp != nullptr) {
parse_omissions(temp, &assemblyOmissions_, "assembly", true);
}
}

if (options_.retrieve("omit_part_assemblies") != nullptr) {
createAssemblies_ = false;
}

{
const char *temp = options_.retrieve("extract_blocks");
if (temp != nullptr) {
Expand Down
15 changes: 10 additions & 5 deletions packages/seacas/applications/ejoin/EJ_SystemInterface.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright(C) 1999-2022 National Technology & Engineering Solutions
// Copyright(C) 1999-, 20232023 National Technology & Engineering Solutions
// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
// NTESS, the U.S. Government retains certain rights in this software.
//
Expand Down Expand Up @@ -29,10 +29,12 @@ class SystemInterface
bool omit_nodesets() const { return omitNodesets_; }
bool omit_sidesets() const { return omitSidesets_; }
bool convert_nodes_to_nodesets(int part_number) const;
bool disable_field_recognition() const { return disableFieldRecognition_; }
bool ints64bit() const { return ints64bit_; }
bool use_netcdf4() const { return useNetcdf4_; }
bool ignore_element_ids() const { return ignoreElementIds_; }
bool create_assemblies() const { return createAssemblies_; }

bool disable_field_recognition() const { return disableFieldRecognition_; }
bool ints64bit() const { return ints64bit_; }
bool use_netcdf4() const { return useNetcdf4_; }
bool ignore_element_ids() const { return ignoreElementIds_; }

int compression_level() const { return compressionLevel_; }
bool zlib() const { return zlib_; }
Expand All @@ -53,6 +55,7 @@ class SystemInterface
const Omissions &block_omissions() const { return blockOmissions_; }
const Omissions &nset_omissions() const { return nsetOmissions_; }
const Omissions &sset_omissions() const { return ssetOmissions_; }
const Omissions &assembly_omissions() const { return assemblyOmissions_; }

const std::string &block_prefix() const { return blockPrefix_; }

Expand Down Expand Up @@ -96,6 +99,7 @@ class SystemInterface
bool ignoreElementIds_{false};
bool zlib_{true};
bool szip_{false};
bool createAssemblies_{true};

std::string blockPrefix_{"p"};

Expand All @@ -104,6 +108,7 @@ class SystemInterface

Omissions blockInclusions_;
Omissions blockOmissions_;
Omissions assemblyOmissions_;
Omissions nsetOmissions_;
Omissions ssetOmissions_;

Expand Down
4 changes: 2 additions & 2 deletions packages/seacas/applications/ejoin/EJ_Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

static std::array<std::string, 3> qainfo{
"ejoin",
"2022/01/24",
"1.5.7",
"2023/05/26",
"1.6.0",
};
96 changes: 93 additions & 3 deletions packages/seacas/applications/ejoin/EJoin.C
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ namespace {
const std::vector<INT> &local_node_map, SystemInterface &interFace);
void process_nset_omissions(RegionVector &part_mesh, const Omissions &omit);
void process_sset_omissions(RegionVector &part_mesh, const Omissions &omit);
void process_assembly_omissions(RegionVector &part_mesh, const Omissions &omit);

int count_omissions(Ioss::Region *region)
{
Expand Down Expand Up @@ -123,7 +124,9 @@ namespace {
} // namespace

namespace {
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region, bool debug);
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region,
bool create_assemblies, bool debug);
void transfer_assembly(Ioss::Region &region, Ioss::Region &output_region, bool debug);
void transfer_nodesets(Ioss::Region &region, Ioss::Region &output_region, bool debug);
void transfer_sidesets(Ioss::Region &region, Ioss::Region &output_region, bool debug);
void create_nodal_nodeset(Ioss::Region &region, Ioss::Region &output_region, bool debug);
Expand Down Expand Up @@ -240,6 +243,7 @@ int main(int argc, char *argv[])

process_nset_omissions(part_mesh, interFace.nset_omissions());
process_sset_omissions(part_mesh, interFace.sset_omissions());
process_assembly_omissions(part_mesh, interFace.assembly_omissions());

double time = 0.0;

Expand Down Expand Up @@ -404,7 +408,7 @@ double ejoin(SystemInterface &interFace, std::vector<Ioss::Region *> &part_mesh,

// Add element blocks, nodesets, sidesets
for (size_t p = 0; p < part_count; p++) {
transfer_elementblock(*part_mesh[p], output_region, false);
transfer_elementblock(*part_mesh[p], output_region, interFace.create_assemblies(), false);
if (interFace.convert_nodes_to_nodesets(p + 1)) {
create_nodal_nodeset(*part_mesh[p], output_region, false);
}
Expand All @@ -414,6 +418,7 @@ double ejoin(SystemInterface &interFace, std::vector<Ioss::Region *> &part_mesh,
if (!interFace.omit_sidesets()) {
transfer_sidesets(*part_mesh[p], output_region, false);
}
transfer_assembly(*part_mesh[p], output_region, false);
}

if (!interFace.information_record_parts().empty()) {
Expand Down Expand Up @@ -565,11 +570,19 @@ namespace {
return omitted;
}

void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region, bool debug)
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region,
bool create_assemblies, bool debug)
{
static int used_blocks = 0;
const std::string &prefix = region.name();

Ioss::Assembly *assem = nullptr;
if (create_assemblies) {
assem = new Ioss::Assembly(output_region.get_database(), region.name());
output_region.add(assem);
assem->property_add(Ioss::Property("name_in_output", region.name()));
}

const Ioss::ElementBlockContainer &ebs = region.get_element_blocks();
for (const auto &eb : ebs) {
if (!entity_is_omitted(eb)) {
Expand All @@ -581,6 +594,8 @@ namespace {
exit(EXIT_FAILURE);
}
}
eb->property_add(Ioss::Property("name_in_output", name));

if (debug) {
fmt::print(stderr, "{}, ", name);
}
Expand All @@ -601,6 +616,54 @@ namespace {
// Set the new property
ebn->property_add(Ioss::Property("original_topology_type", oes));
}

if (create_assemblies) {
assem->add(ebn);
}
}
}
}
}

void transfer_assembly(Ioss::Region &region, Ioss::Region &output_region, bool debug)
{
// All assemblies on the input parts will be transferred to the output mesh
// Possibly renamed if a name conflict
// Also need to update names of the entities in the assembly since they were possibly
// renamed on the output...
// TODO: handle renamed nested assemblies...
const std::string &prefix = region.name();

const Ioss::AssemblyContainer &assems = region.get_assemblies();
for (const auto &as : assems) {
if (!entity_is_omitted(as)) {
std::string name = as->name();
if (output_region.get_assembly(name) != nullptr) {
name = prefix + "_" + as->name();
if (output_region.get_assembly(name) != nullptr) {
fmt::print(stderr, "ERROR: Duplicate assemblies named '{}'\n", name);
exit(EXIT_FAILURE);
}
}
as->property_add(Ioss::Property("name_in_output", name));

if (debug) {
fmt::print(stderr, "{}, ", name);
}
size_t num_members = as->entity_count();
if (num_members > 0) {
auto member_type = as->get_member_type();
auto asn = new Ioss::Assembly(output_region.get_database(), name);
output_region.add(asn);

const auto &members = as->get_members();
for (const auto &member : members) {
auto output_name = member->get_property("name_in_output").get_string();

auto *entity = output_region.get_entity(output_name, member_type);
assert(entity != nullptr);
asn->add(entity);
}
}
}
}
Expand All @@ -621,6 +684,7 @@ namespace {
exit(EXIT_FAILURE);
}
}
fs->property_add(Ioss::Property("name_in_output", name));
if (debug) {
fmt::print(stderr, "{}, ", name);
}
Expand All @@ -633,6 +697,7 @@ namespace {
if (debug) {
fmt::print(stderr, "{}, ", fbname);
}
fb->property_add(Ioss::Property("name_in_output", fbname));
std::string fbtype = fb->topology()->name();
std::string partype = fb->parent_element_topology()->name();
size_t num_side = fb->entity_count();
Expand Down Expand Up @@ -747,6 +812,7 @@ namespace {
exit(EXIT_FAILURE);
}
}
ns->property_add(Ioss::Property("name_in_output", name));
if (debug) {
fmt::print(stderr, "{}, ", name);
}
Expand Down Expand Up @@ -1493,4 +1559,28 @@ namespace {
}
}
}

void process_assembly_omissions(RegionVector &part_mesh, const Omissions &omit)
{
size_t part_count = part_mesh.size();
for (size_t p = 0; p < part_count; p++) {
if (!omit[p].empty()) {
// Get the assemblies for this part and set the "omitted" property on the assembly
if (omit[p][0] == "ALL") {
const auto &assemblies = part_mesh[p]->get_assemblies();
for (auto &as : assemblies) {
as->property_add(Ioss::Property(std::string("omitted"), 1));
}
}
else {
for (const auto &omitted : omit[p]) {
auto *as = part_mesh[p]->get_assembly(omitted);
if (as != nullptr) {
as->property_add(Ioss::Property(std::string("omitted"), 1));
}
}
}
}
}
}
} // namespace
6 changes: 3 additions & 3 deletions packages/seacas/libraries/exodus/include/exodusII.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@
#endif

/* EXODUS version number */
#define EXODUS_VERSION "8.20"
#define EXODUS_VERSION "8.21"
#define EXODUS_VERSION_MAJOR 8
#define EXODUS_VERSION_MINOR 20
#define EXODUS_VERSION_MINOR 21
#define EXODUS_RELEASE_DATE "May 1, 2023"

#define EX_API_VERS 8.20f
#define EX_API_VERS 8.21f
#define EX_API_VERS_NODOT (100 * EXODUS_VERSION_MAJOR + EXODUS_VERSION_MINOR)
#define EX_VERS EX_API_VERS

Expand Down
Loading