Skip to content

Commit 7db697b

Browse files
authored
Merge pull request #390 from sandialabs/add_ejoin_assemblies
Add ejoin assemblies
2 parents da2e11c + f5471d1 commit 7db697b

File tree

7 files changed

+191
-28
lines changed

7 files changed

+191
-28
lines changed

packages/seacas/applications/ejoin/EJ_SystemInterface.C

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void SystemInterface::enroll_options()
5555
options_.enroll("version", GetLongOption::NoValue, "Print version and exit", nullptr);
5656

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

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

78+
options_.enroll("omit_assemblies", GetLongOption::MandatoryValue,
79+
"If no value, then don't transfer any assemblies to output file.\n"
80+
"\t\tIf just p#,p#,... specified, then omit assemblies on specified parts\n"
81+
"\t\tIf p#:id1:id2,p#:id2,id4... then omit the assemblies with the specified\n"
82+
"\t\tid in the specified parts.",
83+
nullptr, "ALL");
84+
85+
options_.enroll(
86+
"omit_part_assemblies", GetLongOption::NoValue,
87+
"Do not create an assembly for each input part containing the blocks in that part.\n"
88+
"\t\tDefault is to create the part assemblies.",
89+
nullptr);
90+
7891
options_.enroll("omit_nodesets", GetLongOption::OptionalValue,
7992
"If no value, then don't transfer any nodesets to output file.\n"
8093
"\t\tIf just p#,p#,... specified, then omit sets on specified parts\n"
@@ -94,7 +107,7 @@ void SystemInterface::enroll_options()
94107
"\t\tcreate a nodeset containing the nodes of that part\n"
95108
"\t\tand output the nodal fields as nodeset fields instead of nodal fields.\n"
96109
"\t\tFormat is comma-separated list of parts (1-based), or ALL",
97-
nullptr);
110+
nullptr, nullptr, true);
98111

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

117130
options_.enroll("tolerance", GetLongOption::MandatoryValue,
118-
"Maximum distance between two nodes to be considered colocated.", nullptr);
131+
"Maximum distance between two nodes to be considered colocated.", nullptr,
132+
nullptr, true);
119133

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

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

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

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

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

321+
{
322+
const char *temp = options_.retrieve("omit_assemblies");
323+
if (temp != nullptr) {
324+
parse_omissions(temp, &assemblyOmissions_, "assembly", true);
325+
}
326+
}
327+
328+
if (options_.retrieve("omit_part_assemblies") != nullptr) {
329+
createAssemblies_ = false;
330+
}
331+
306332
{
307333
const char *temp = options_.retrieve("extract_blocks");
308334
if (temp != nullptr) {

packages/seacas/applications/ejoin/EJ_SystemInterface.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright(C) 1999-2022 National Technology & Engineering Solutions
1+
// Copyright(C) 1999-, 20232023 National Technology & Engineering Solutions
22
// of Sandia, LLC (NTESS). Under the terms of Contract DE-NA0003525 with
33
// NTESS, the U.S. Government retains certain rights in this software.
44
//
@@ -29,10 +29,12 @@ class SystemInterface
2929
bool omit_nodesets() const { return omitNodesets_; }
3030
bool omit_sidesets() const { return omitSidesets_; }
3131
bool convert_nodes_to_nodesets(int part_number) const;
32-
bool disable_field_recognition() const { return disableFieldRecognition_; }
33-
bool ints64bit() const { return ints64bit_; }
34-
bool use_netcdf4() const { return useNetcdf4_; }
35-
bool ignore_element_ids() const { return ignoreElementIds_; }
32+
bool create_assemblies() const { return createAssemblies_; }
33+
34+
bool disable_field_recognition() const { return disableFieldRecognition_; }
35+
bool ints64bit() const { return ints64bit_; }
36+
bool use_netcdf4() const { return useNetcdf4_; }
37+
bool ignore_element_ids() const { return ignoreElementIds_; }
3638

3739
int compression_level() const { return compressionLevel_; }
3840
bool zlib() const { return zlib_; }
@@ -53,6 +55,7 @@ class SystemInterface
5355
const Omissions &block_omissions() const { return blockOmissions_; }
5456
const Omissions &nset_omissions() const { return nsetOmissions_; }
5557
const Omissions &sset_omissions() const { return ssetOmissions_; }
58+
const Omissions &assembly_omissions() const { return assemblyOmissions_; }
5659

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

@@ -96,6 +99,7 @@ class SystemInterface
9699
bool ignoreElementIds_{false};
97100
bool zlib_{true};
98101
bool szip_{false};
102+
bool createAssemblies_{true};
99103

100104
std::string blockPrefix_{"p"};
101105

@@ -104,6 +108,7 @@ class SystemInterface
104108

105109
Omissions blockInclusions_;
106110
Omissions blockOmissions_;
111+
Omissions assemblyOmissions_;
107112
Omissions nsetOmissions_;
108113
Omissions ssetOmissions_;
109114

packages/seacas/applications/ejoin/EJ_Version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
static std::array<std::string, 3> qainfo{
1111
"ejoin",
12-
"2022/01/24",
13-
"1.5.7",
12+
"2023/05/26",
13+
"1.6.0",
1414
};

packages/seacas/applications/ejoin/EJoin.C

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ namespace {
8080
const std::vector<INT> &local_node_map, SystemInterface &interFace);
8181
void process_nset_omissions(RegionVector &part_mesh, const Omissions &omit);
8282
void process_sset_omissions(RegionVector &part_mesh, const Omissions &omit);
83+
void process_assembly_omissions(RegionVector &part_mesh, const Omissions &omit);
8384

8485
int count_omissions(Ioss::Region *region)
8586
{
@@ -123,7 +124,9 @@ namespace {
123124
} // namespace
124125

125126
namespace {
126-
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region, bool debug);
127+
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region,
128+
bool create_assemblies, bool debug);
129+
void transfer_assembly(Ioss::Region &region, Ioss::Region &output_region, bool debug);
127130
void transfer_nodesets(Ioss::Region &region, Ioss::Region &output_region, bool debug);
128131
void transfer_sidesets(Ioss::Region &region, Ioss::Region &output_region, bool debug);
129132
void create_nodal_nodeset(Ioss::Region &region, Ioss::Region &output_region, bool debug);
@@ -240,6 +243,7 @@ int main(int argc, char *argv[])
240243

241244
process_nset_omissions(part_mesh, interFace.nset_omissions());
242245
process_sset_omissions(part_mesh, interFace.sset_omissions());
246+
process_assembly_omissions(part_mesh, interFace.assembly_omissions());
243247

244248
double time = 0.0;
245249

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

405409
// Add element blocks, nodesets, sidesets
406410
for (size_t p = 0; p < part_count; p++) {
407-
transfer_elementblock(*part_mesh[p], output_region, false);
411+
transfer_elementblock(*part_mesh[p], output_region, interFace.create_assemblies(), false);
408412
if (interFace.convert_nodes_to_nodesets(p + 1)) {
409413
create_nodal_nodeset(*part_mesh[p], output_region, false);
410414
}
@@ -414,6 +418,7 @@ double ejoin(SystemInterface &interFace, std::vector<Ioss::Region *> &part_mesh,
414418
if (!interFace.omit_sidesets()) {
415419
transfer_sidesets(*part_mesh[p], output_region, false);
416420
}
421+
transfer_assembly(*part_mesh[p], output_region, false);
417422
}
418423

419424
if (!interFace.information_record_parts().empty()) {
@@ -565,11 +570,19 @@ namespace {
565570
return omitted;
566571
}
567572

568-
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region, bool debug)
573+
void transfer_elementblock(Ioss::Region &region, Ioss::Region &output_region,
574+
bool create_assemblies, bool debug)
569575
{
570576
static int used_blocks = 0;
571577
const std::string &prefix = region.name();
572578

579+
Ioss::Assembly *assem = nullptr;
580+
if (create_assemblies) {
581+
assem = new Ioss::Assembly(output_region.get_database(), region.name());
582+
output_region.add(assem);
583+
assem->property_add(Ioss::Property("name_in_output", region.name()));
584+
}
585+
573586
const Ioss::ElementBlockContainer &ebs = region.get_element_blocks();
574587
for (const auto &eb : ebs) {
575588
if (!entity_is_omitted(eb)) {
@@ -581,6 +594,8 @@ namespace {
581594
exit(EXIT_FAILURE);
582595
}
583596
}
597+
eb->property_add(Ioss::Property("name_in_output", name));
598+
584599
if (debug) {
585600
fmt::print(stderr, "{}, ", name);
586601
}
@@ -601,6 +616,54 @@ namespace {
601616
// Set the new property
602617
ebn->property_add(Ioss::Property("original_topology_type", oes));
603618
}
619+
620+
if (create_assemblies) {
621+
assem->add(ebn);
622+
}
623+
}
624+
}
625+
}
626+
}
627+
628+
void transfer_assembly(Ioss::Region &region, Ioss::Region &output_region, bool debug)
629+
{
630+
// All assemblies on the input parts will be transferred to the output mesh
631+
// Possibly renamed if a name conflict
632+
// Also need to update names of the entities in the assembly since they were possibly
633+
// renamed on the output...
634+
// TODO: handle renamed nested assemblies...
635+
const std::string &prefix = region.name();
636+
637+
const Ioss::AssemblyContainer &assems = region.get_assemblies();
638+
for (const auto &as : assems) {
639+
if (!entity_is_omitted(as)) {
640+
std::string name = as->name();
641+
if (output_region.get_assembly(name) != nullptr) {
642+
name = prefix + "_" + as->name();
643+
if (output_region.get_assembly(name) != nullptr) {
644+
fmt::print(stderr, "ERROR: Duplicate assemblies named '{}'\n", name);
645+
exit(EXIT_FAILURE);
646+
}
647+
}
648+
as->property_add(Ioss::Property("name_in_output", name));
649+
650+
if (debug) {
651+
fmt::print(stderr, "{}, ", name);
652+
}
653+
size_t num_members = as->entity_count();
654+
if (num_members > 0) {
655+
auto member_type = as->get_member_type();
656+
auto asn = new Ioss::Assembly(output_region.get_database(), name);
657+
output_region.add(asn);
658+
659+
const auto &members = as->get_members();
660+
for (const auto &member : members) {
661+
auto output_name = member->get_property("name_in_output").get_string();
662+
663+
auto *entity = output_region.get_entity(output_name, member_type);
664+
assert(entity != nullptr);
665+
asn->add(entity);
666+
}
604667
}
605668
}
606669
}
@@ -621,6 +684,7 @@ namespace {
621684
exit(EXIT_FAILURE);
622685
}
623686
}
687+
fs->property_add(Ioss::Property("name_in_output", name));
624688
if (debug) {
625689
fmt::print(stderr, "{}, ", name);
626690
}
@@ -633,6 +697,7 @@ namespace {
633697
if (debug) {
634698
fmt::print(stderr, "{}, ", fbname);
635699
}
700+
fb->property_add(Ioss::Property("name_in_output", fbname));
636701
std::string fbtype = fb->topology()->name();
637702
std::string partype = fb->parent_element_topology()->name();
638703
size_t num_side = fb->entity_count();
@@ -747,6 +812,7 @@ namespace {
747812
exit(EXIT_FAILURE);
748813
}
749814
}
815+
ns->property_add(Ioss::Property("name_in_output", name));
750816
if (debug) {
751817
fmt::print(stderr, "{}, ", name);
752818
}
@@ -1493,4 +1559,28 @@ namespace {
14931559
}
14941560
}
14951561
}
1562+
1563+
void process_assembly_omissions(RegionVector &part_mesh, const Omissions &omit)
1564+
{
1565+
size_t part_count = part_mesh.size();
1566+
for (size_t p = 0; p < part_count; p++) {
1567+
if (!omit[p].empty()) {
1568+
// Get the assemblies for this part and set the "omitted" property on the assembly
1569+
if (omit[p][0] == "ALL") {
1570+
const auto &assemblies = part_mesh[p]->get_assemblies();
1571+
for (auto &as : assemblies) {
1572+
as->property_add(Ioss::Property(std::string("omitted"), 1));
1573+
}
1574+
}
1575+
else {
1576+
for (const auto &omitted : omit[p]) {
1577+
auto *as = part_mesh[p]->get_assembly(omitted);
1578+
if (as != nullptr) {
1579+
as->property_add(Ioss::Property(std::string("omitted"), 1));
1580+
}
1581+
}
1582+
}
1583+
}
1584+
}
1585+
}
14961586
} // namespace

packages/seacas/libraries/exodus/include/exodusII.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@
5252
#endif
5353

5454
/* EXODUS version number */
55-
#define EXODUS_VERSION "8.20"
55+
#define EXODUS_VERSION "8.21"
5656
#define EXODUS_VERSION_MAJOR 8
57-
#define EXODUS_VERSION_MINOR 20
57+
#define EXODUS_VERSION_MINOR 21
5858
#define EXODUS_RELEASE_DATE "May 1, 2023"
5959

60-
#define EX_API_VERS 8.20f
60+
#define EX_API_VERS 8.21f
6161
#define EX_API_VERS_NODOT (100 * EXODUS_VERSION_MAJOR + EXODUS_VERSION_MINOR)
6262
#define EX_VERS EX_API_VERS
6363

0 commit comments

Comments
 (0)