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.
 
 
 
 
 
 

270 lines
8.5 KiB

/*
* Copyright(C) 1999-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 <cassert>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <exception>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <stdexcept>
#include <string>
#include "EML_CodeTypes.h"
#include "EML_SystemInterface.h"
#include <Ionit_Initializer.h>
#include <Ioss_CodeTypes.h>
#include <Ioss_SubSystem.h>
#include <Ioss_SurfaceSplit.h>
#include <Ioss_Utils.h>
#include "add_to_log.h"
#include "fmt/ostream.h"
#ifdef SEACAS_HAVE_MPI
#include <mpi.h>
#endif
// ========================================================================
namespace {
bool file_info(const std::string &inpfile, const std::string &input_type,
SystemInterface &interFace);
void output_names(const std::string &type, const Ioss::NameList &fields,
Ioss::GroupingEntity *entity)
{
fmt::print("\n{} variables on exodus data base:\n", type);
Ioss::NameList::const_iterator IF;
for (IF = fields.begin(); IF != fields.end(); ++IF) {
std::string field_name = *IF;
const Ioss::VariableType *var_type = entity->get_field(field_name).raw_storage();
fmt::print("\t{}\t{}\n", field_name, var_type->name());
}
}
} // namespace
// ========================================================================
namespace {
std::string codename;
std::string version = "1.2";
} // namespace
int main(int argc, char *argv[])
{
#ifdef SEACAS_HAVE_MPI
MPI_Init(&argc, &argv);
#endif
time_t begin_time = time(nullptr);
std::string in_type = "exodusII";
bool ok = false;
codename = argv[0];
size_t ind = codename.find_last_of("/", codename.size());
if (ind != std::string::npos) {
codename = codename.substr(ind + 1, codename.size());
}
try {
SystemInterface::show_version();
Ioss::Init::Initializer io;
SystemInterface interFace;
ok = interFace.parse_options(argc, argv);
if (ok) {
std::string in_file = interFace.input_file();
std::string output_file = interFace.output_file();
fmt::print("Input: '{}', Type: {}\n", in_file, in_type);
fmt::print("Output: '{}', Type: matlab script\n\n", output_file);
ok = file_info(in_file, in_type, interFace);
}
std::string success = ok ? "successful" : "unsuccessful";
fmt::print("\n{} execution {}.\n", codename, success);
}
catch (std::exception &e) {
fmt::print("ERROR: (EXOMATLAB) Standard exception: {}\n", e.what());
}
time_t end_time = time(nullptr);
add_to_log(codename.c_str(), (int)(end_time - begin_time));
#ifdef SEACAS_HAVE_MPI
MPI_Finalize();
#endif
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
namespace {
bool file_info(const std::string &inpfile, const std::string &input_type,
SystemInterface &interFace)
{
//========================================================================
// INPUT ...
// NOTE: The "READ_RESTART" mode ensures that the node and element ids will be mapped.
//========================================================================
Ioss::DatabaseIO *dbi = Ioss::IOFactory::create(input_type, inpfile, Ioss::READ_RESTART,
Ioss::ParallelUtils::comm_world());
if (dbi == nullptr || !dbi->ok(true)) {
return false;
}
dbi->set_field_separator(interFace.field_suffix());
dbi->set_lower_case_variable_names(false);
// NOTE: 'region' owns 'db' pointer at this time...
Ioss::Region region(dbi, "region_1");
if (interFace.list_vars()) {
StringIdVector types_to_list = interFace.vars_to_list();
for (const auto &types : types_to_list) {
std::string type = types.first;
if (type == "all" || type == "global") {
Ioss::NameList fields = region.field_describe(Ioss::Field::REDUCTION);
output_names("Global", fields, &region);
}
if (type == "all" || type == "nodal") {
Ioss::NodeBlock *nb = region.get_node_blocks()[0];
Ioss::NameList fields = nb->field_describe(Ioss::Field::TRANSIENT);
output_names("Nodal", fields, nb);
}
}
return true;
}
Ioss::NameList fields;
StringIdVector global_vars = interFace.global_var_names();
if (!global_vars.empty()) {
if (global_vars[0].first == "all") {
region.field_describe(Ioss::Field::REDUCTION, &fields);
}
else if (global_vars[0].first == "none") {
; // do nothing. This will be used when nodal, element, ... supported
}
else {
for (const auto &global_var : global_vars) {
std::string field_name = global_var.first;
if (region.field_exists(field_name)) {
fields.push_back(field_name);
}
else {
fmt::print("WARNING: Global variable named '{}' does not exist; it will be skipped.\n",
field_name);
;
}
}
}
}
else {
region.field_describe(Ioss::Field::REDUCTION, &fields);
}
if (fields.empty()) {
fmt::print("No variables selected; no output will be written\n");
return false;
}
std::ofstream out_stream;
out_stream.open(interFace.output_file().c_str());
out_stream.setf(std::ios::scientific);
out_stream.setf(std::ios::showpoint);
fmt::print(out_stream, "% number of curves\nnvars = {}\n", fields.size() + 1);
size_t namelen = 4; // length of 'time'
Ioss::NameList::const_iterator IF;
for (IF = fields.begin(); IF != fields.end(); ++IF) {
std::string field_name = *IF;
if (field_name.length() > namelen) {
namelen = field_name.length();
}
}
fmt::print(out_stream, "names= [\n'{:<{}}';\n", "TIME", namelen);
for (IF = fields.begin(); IF != fields.end(); ++IF) {
std::string field_name = *IF;
fmt::print(out_stream, "'{:<{}}';\n", field_name, namelen);
}
fmt::print(out_stream, "];\n");
// Get number of timesteps...
int num_steps = region.get_optional_property("state_count", 0);
if (num_steps == 0) {
fmt::print(out_stream, "GENESIS file -- no time steps written\n");
return false;
}
// ========================================================================
// Calculate min and max times to extract data...
int st_min = 1;
int st_max = num_steps;
double tmin = interFace.minimum_time();
double tmax = interFace.maximum_time();
if (tmax == -1.0) {
tmax = region.get_max_time().second;
}
if (tmin > 0.0 || tmax != region.get_max_time().second) {
st_min = 0;
// Count number of active steps...
for (int i = 1; i <= num_steps; i++) {
double time = region.get_state_time(i);
if (time < tmin) {
st_min = i;
}
if (time <= tmax) {
st_max = i;
}
}
st_min++;
num_steps = st_max - st_min + 1;
}
// ========================================================================
// Output time values...
fmt::print(out_stream, "TIME = zeros(1, {});\n", num_steps);
fmt::print(out_stream, "TIME= [\n");
for (int i = st_min; i <= st_max; i++) {
double time = region.get_state_time(i);
fmt::print(out_stream, " {:13.6e}\n", time);
}
fmt::print(out_stream, "];\n");
// ========================================================================
// Output field values...
std::vector<double> data(1);
for (IF = fields.begin(); IF != fields.end(); ++IF) {
std::string field_name = *IF;
int comp_count = region.get_field(field_name).raw_storage()->component_count();
fmt::print(out_stream, "{} = zeros({}, {});\n", field_name, comp_count, num_steps);
fmt::print(out_stream, "{} = [\n", field_name);
for (int istep = st_min; istep <= st_max; istep++) {
region.begin_state(istep);
region.get_field_data(field_name, data);
for (int i = 0; i < comp_count; i++) {
fmt::print(out_stream, " {:13.6e}", data[i]);
}
fmt::print(out_stream, ";\n");
region.end_state(istep);
}
fmt::print(out_stream, "];\n");
}
fmt::print("Wrote data for {} variables at {} timesteps.\n", fields.size(),
st_max - st_min + 1);
return true;
}
} // namespace