Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

320 lines
9.6 KiB

// Copyright(C) 2021, 2022, 2023 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.
//
// See packages/seacas/LICENSE for details
#include <exception>
#include <fstream>
#include <iterator>
#include <string>
#include "add_to_log.h"
#include "fmt/chrono.h"
#include "fmt/color.h"
#include "fmt/ostream.h"
#include "time_stamp.h"
#include "tokenize.h"
#include <exodusII.h>
#include <Ionit_Initializer.h>
#include <Ioss_MemoryUtils.h>
#include <Ioss_ParallelUtils.h>
#include <Ioss_SmartAssert.h>
#include <Ioss_Utils.h>
#include "Grid.h"
#include "ZE_SystemInterface.h"
#ifdef SEACAS_HAVE_MPI
#include <mpi.h>
#endif
//! \file
namespace {
Grid define_lattice(SystemInterface &interFace, Ioss::ParallelUtils &pu);
} // namespace
std::string tsFormat = "[{:%H:%M:%S}]";
unsigned int debug_level = 0;
template <typename INT> double zellij(SystemInterface &interFace, INT dummy);
int main(int argc, char *argv[])
{
#ifdef SEACAS_HAVE_MPI
MPI_Init(&argc, &argv);
#endif
Ioss::ParallelUtils pu{};
int my_rank = pu.parallel_rank();
try {
if (my_rank == 0) {
SystemInterface::show_version();
#ifdef SEACAS_HAVE_MPI
fmt::print("\tParallel Capability Enabled.\n");
#else
fmt::print("\tParallel Capability Not Enabled.\n");
#endif
}
Ioss::Init::Initializer io;
SystemInterface interFace(my_rank);
bool ok = interFace.parse_options(argc, argv);
if (!ok) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: Problems parsing command line arguments.\n\n");
exit(EXIT_FAILURE);
}
debug_level = interFace.debug();
if (debug_level & 1) {
ex_opts(EX_VERBOSE | EX_DEBUG);
}
else {
ex_opts(0);
}
double time = 0.0;
if (interFace.ints32bit()) {
time = zellij(interFace, 0);
}
else {
time = zellij(interFace, static_cast<int64_t>(0));
}
if (my_rank == 0) {
fmt::print("\n Zellij execution successful.\n");
add_to_log(argv[0], time);
}
#ifdef SEACAS_HAVE_MPI
MPI_Finalize();
#endif
}
catch (std::exception &e) {
fmt::print(stderr, fmt::fg(fmt::color::red), "ERROR: Standard exception: {}\n", e.what());
}
}
template <typename INT> double zellij(SystemInterface &interFace, INT /*dummy*/)
{
double begin = Ioss::Utils::timer();
Ioss::ParallelUtils pu{};
if (debug_level & 2) {
fmt::print(stderr, "{} Begin Execution\n", time_stamp(tsFormat));
}
auto grid = define_lattice(interFace, pu);
grid.generate_sidesets();
grid.set_coordinate_offsets();
grid.decompose(interFace.decomp_method());
if (debug_level & 2) {
fmt::print(stderr, "{} Lattice Decomposed\n", time_stamp(tsFormat));
}
// All unit cells have been mapped into the IxJ grid, now calculate all node / element offsets
// and the global node and element counts...
//
// Iterate through the grid starting with (0,0) and accumulate node and element counts...
grid.process(interFace, (INT)0);
/*************************************************************************/
// EXIT program
if (debug_level & 2) {
fmt::print(stderr, "{} Execution Complete\n", time_stamp(tsFormat));
}
double end = Ioss::Utils::timer();
double hwm = (double)Ioss::MemoryUtils::get_hwm_memory_info() / 1024.0 / 1024.0;
if (pu.parallel_rank() == 0) {
fmt::print("\n Total Execution Time = {:.5} seconds.\n", end - begin);
fmt::print(" High-Water Memory Use = {:.3} MiBytes.\n", hwm);
}
return (end - begin);
}
namespace {
Grid define_lattice(SystemInterface &interFace, Ioss::ParallelUtils &pu)
{
int my_rank = pu.parallel_rank();
Grid grid(interFace);
if (debug_level & 2) {
pu.progress("Defining Unit Cells...");
}
std::string filename = interFace.lattice();
std::ifstream input(filename, std::ios::in);
if (!input.is_open()) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: Could not open/access lattice file '{}'\n", filename);
exit(EXIT_FAILURE);
}
bool in_dictionary{false};
bool in_lattice{false};
std::string line;
while (getline(input, line)) {
if (line.empty()) {
continue;
}
auto tokens = Ioss::tokenize(line, " ");
if (tokens[0] == "BEGIN_DICTIONARY") {
SMART_ASSERT(!in_lattice && !in_dictionary);
in_dictionary = true;
}
else if (tokens[0] == "END_DICTIONARY") {
SMART_ASSERT(!in_lattice && in_dictionary);
in_dictionary = false;
if (debug_level & 2) {
pu.progress("Unit Cells Defined...");
}
}
else if (in_dictionary) {
if (tokens.size() != 2) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: There are {} entries on a lattice dictionary line; there should be "
"only 2:\n\t'{}'.\n\n",
tokens.size(), line);
exit(EXIT_FAILURE);
}
grid.add_unit_cell(tokens[0], tokens[1], interFace.ints32bit());
}
else if (tokens[0] == "BEGIN_LATTICE") {
SMART_ASSERT(!in_lattice && !in_dictionary);
in_lattice = true;
break;
}
}
if (!in_lattice) {
fmt::print(
stderr, fmt::fg(fmt::color::red),
"\nERROR: Reached end of input file without finding a 'BEGIN_LATTICE' command\n\n");
exit(EXIT_FAILURE);
}
// Tokenize line to get I J K size of lattice
auto tokens = Ioss::tokenize(line, " ");
SMART_ASSERT(tokens[0] == "BEGIN_LATTICE")(tokens[0])(line);
if (tokens.size() != 4) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: The 'BEGIN_LATTICE' line has incorrect syntax. It should be "
"'BEGIN_LATTICE I J K'\n"
"\tThe line was '{}'\n\n",
line);
exit(EXIT_FAILURE);
}
SMART_ASSERT(tokens.size() == 4)(tokens.size())(line);
int II = std::stoi(tokens[1]);
int JJ = std::stoi(tokens[2]);
int KK = std::stoi(tokens[3]);
SMART_ASSERT(KK == 1);
if (interFace.repeat() > 1) {
II *= interFace.repeat();
JJ *= interFace.repeat();
}
grid.set_extent(II, JJ, KK);
grid.handle_file_count();
if (my_rank == 0) {
fmt::print("\n Lattice:\tUnit Cells: {},\tGrid Size: {} x {} x {}\n",
fmt::group_digits(grid.unit_cells().size()), fmt::group_digits(II),
fmt::group_digits(JJ), fmt::group_digits(KK));
}
if (interFace.ranks() > 1) {
fmt::print(" \t[{}] Ranks: {}, Outputting {} ranks starting at rank {}.\n", my_rank,
fmt::group_digits(interFace.ranks()), fmt::group_digits(interFace.rank_count()),
fmt::group_digits(interFace.start_rank()));
}
// Now process the lattice portion of the lattice file...
size_t row{0};
while (getline(input, line)) {
if (line.empty()) {
continue;
}
tokens = Ioss::tokenize(line, " ");
if (tokens[0] == "END_LATTICE") {
SMART_ASSERT(in_lattice && !in_dictionary);
in_lattice = false;
// Check row count to make sure matches 'J' size of lattice
if (row != grid.JJ()) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: Only {} rows of the {} x {} lattice were defined.\n\n", row, II, JJ);
exit(EXIT_FAILURE);
}
break;
}
else if (in_lattice) {
// TODO: Currently assumes that each row in the lattice is defined on a single row;
// This will need to be relaxed since a lattice of 5000x5000 would result in
// lines that are too long and would be easier to split a row over multiple lines...
if (tokens.size() * interFace.repeat() != grid.II()) {
fmt::print(
stderr, fmt::fg(fmt::color::red),
"\nERROR: Line {} of the lattice definition has {} entries. It should have {}.\n\n",
row + 1, tokens.size() * interFace.repeat(), grid.II());
exit(EXIT_FAILURE);
}
if (row >= grid.JJ()) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: There are too many rows in the lattice definition. The lattice is "
"{} x {}.\n\n",
grid.II(), grid.JJ());
exit(EXIT_FAILURE);
}
if (tokens.size() * interFace.repeat() != grid.II()) {
fmt::print(stderr, fmt::fg(fmt::color::red),
"\nERROR: In row {}, there is an incorrect number of entries. There should "
"be {}, but found {}.\n",
row + 1, grid.II(), tokens.size() * interFace.repeat());
exit(EXIT_FAILURE);
}
auto repeat = interFace.repeat();
for (int j = 0; j < repeat; j++) {
size_t col = 0;
for (auto &key : tokens) {
for (int i = 0; i < repeat; i++) {
if (!grid.initialize(col++, row, key)) {
fmt::print(
stderr, fmt::fg(fmt::color::red),
"\nERROR: In row {}, column {}, the lattice specifies a unit cell ({}) that "
"has not been defined.\n\n",
row + 1, col + 1, key);
exit(EXIT_FAILURE);
}
}
}
row++;
}
}
}
if (debug_level & 2) {
fmt::print(stderr, "{} Lattice Defined\n", time_stamp(tsFormat));
}
return grid;
}
} // namespace