Skip to content

Commit

Permalink
SKINNER: Add timestep filtering options
Browse files Browse the repository at this point in the history
  • Loading branch information
gsjaardema committed Aug 23, 2023
1 parent 6734b1e commit 9381d7a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
58 changes: 56 additions & 2 deletions packages/seacas/libraries/ioss/src/main/skinner.C
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
namespace {
template <typename INT> void skinner(Skinner::Interface &interFace, INT /*dummy*/);
std::string codename;
std::string version = "1.01";
std::string version = "1.02";

void transfer_field_data(Ioss::GroupingEntity *ige, Ioss::GroupingEntity *oge,
Ioss::Field::RoleType role, const std::vector<int> &ref_nodes);
Expand Down Expand Up @@ -76,6 +76,55 @@ namespace {
}
fmt::print("\t+{2:-^{0}}+{2:-^{1}}+\n", max_name, max_face, "");
}

std::vector<int> get_selected_steps(Ioss::Region &region, const Skinner::Interface &options)
{
// This routine checks all steps of the input database and selects those which
// meet the requirements specified in `options`. The returned (1-based) vector will have a
// value of `1` if the step is to be output and `0` if skipped.
int step_count = (int)region.get_property("state_count").get_int();
std::vector<int> selected_steps(step_count + 1);

// If user specified a list of times to transfer to output database,
// process the list and find the times on the input database that are
// closest to the times in the list.
if (!options.selected_times.empty()) {
int selected_step = 0;
for (auto time : options.selected_times) {
double diff = std::numeric_limits<double>::max();
for (int step = 1; step <= step_count; step++) {
double db_time = region.get_state_time(step);
double cur_diff = std::abs(db_time - time);
if (cur_diff < diff) {
diff = std::abs(db_time - time);
selected_step = step;
}
}
if (selected_step > 0) {
selected_steps[selected_step] = 1;
}
}
}
else {
// User did not select specific times to be output...
// Just select them all
for (int i = 1; i <= step_count; i++) {
selected_steps[i] = 1;
}
}

// Now, filter by min and max time...
for (int istep = 1; istep <= step_count; istep++) {
double time = region.get_state_time(istep);
if (time < options.minimum_time) {
selected_steps[istep] = 0;
}
if (time > options.maximum_time) {
selected_steps[istep] = 0;
}
}
return selected_steps;
}
} // namespace

int main(int argc, char *argv[])
Expand Down Expand Up @@ -357,11 +406,16 @@ namespace {

output_region.end_mode(Ioss::STATE_DEFINE_TRANSIENT);

auto selected_steps = get_selected_steps(region, interFace);

output_region.begin_mode(Ioss::STATE_TRANSIENT);
for (size_t istep = 1; istep <= ts_count; istep++) {
if (selected_steps[istep] != 1) {
continue;
}
double time = region.get_state_time(istep);
int ostep = output_region.add_state(time);
fmt::print(stderr, "\r\tTime step {:5d} at time {:10.5e}", istep, time);
fmt::print(stderr, "\r\tTime step {:5d} at time {:10.5e}", ostep, time);

output_region.begin_state(ostep);
region.begin_state(istep);
Expand Down
33 changes: 29 additions & 4 deletions packages/seacas/libraries/ioss/src/main/skinner_interface.C
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Ioss_GetLongOpt.h" // for GetLongOption, etc
#include "Ioss_Utils.h"
#include "skinner_interface.h"
#include "tokenize.h"
#include <cstddef> // for nullptr
#include <cstdlib> // for exit, EXIT_SUCCESS, getenv
#include <fmt/format.h>
Expand Down Expand Up @@ -56,12 +57,21 @@ void Skinner::Interface::enroll_options()
"unknown");

options_.enroll("no_output", Ioss::GetLongOption::NoValue,
"Do not produce output file, just generate the faces", nullptr);
"Do not produce output file, just generate the faces", nullptr, nullptr, true);

options_.enroll(
"output_transient", Ioss::GetLongOption::NoValue,
"Transfer nodal and element transient data from the input mesh to the output mesh.", nullptr,
nullptr, true);
"Transfer nodal and element transient data from the input mesh to the output mesh.", nullptr);

options_.enroll("Maximum_Time", Ioss::GetLongOption::MandatoryValue,
"Maximum time on input database to transfer to output database", nullptr);

options_.enroll("Minimum_Time", Ioss::GetLongOption::MandatoryValue,
"Minimum time on input database to transfer to output database", nullptr);

options_.enroll("select_times", Ioss::GetLongOption::MandatoryValue,
"comma-separated list of times that should be transferred to output database",
nullptr, nullptr, true);

options_.enroll("ignore_face_hash_ids", Ioss::GetLongOption::NoValue,
"Don't use face ids from hash of node ids; just use 1..num_face", nullptr);
Expand Down Expand Up @@ -194,6 +204,21 @@ bool Skinner::Interface::parse_options(int argc, char **argv)
statistics = options_.retrieve("statistics") != nullptr;
blocks_ = options_.retrieve("blocks") != nullptr;

maximum_time = options_.get_option_value("Maximum_Time", maximum_time);
minimum_time = options_.get_option_value("Minimum_Time", minimum_time);

{
const char *temp = options_.retrieve("select_times");
if (temp != nullptr) {
auto time_str = Ioss::tokenize(std::string(temp), ",");
for (const auto &str : time_str) {
auto time = std::stod(str);
selected_times.push_back(time);
}
Ioss::sort(selected_times.begin(), selected_times.end());
}
}

{
const char *temp = options_.retrieve("compress");
if (temp != nullptr) {
Expand Down Expand Up @@ -266,7 +291,7 @@ bool Skinner::Interface::parse_options(int argc, char **argv)
}

if (options_.retrieve("copyright") != nullptr) {
Ioss::Utils::copyright(std::cerr, "1999-2022");
Ioss::Utils::copyright(std::cerr, "1999-2023");
exit(EXIT_SUCCESS);
}

Expand Down
5 changes: 5 additions & 0 deletions packages/seacas/libraries/ioss/src/main/skinner_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ namespace Skinner {
public:
std::string decomp_method;
std::string compose_output{"default"};
double maximum_time{std::numeric_limits<double>::max()};
double minimum_time{-std::numeric_limits<double>::max()};
int compression_level{0};
bool shuffle{false};
bool debug{false};
Expand All @@ -55,5 +57,8 @@ namespace Skinner {
bool noOutput_{false};
bool outputTransient_{false};
bool blocks_{false};

//! If non-empty, then it is a list of times that should be transferred to the output file.
std::vector<double> selected_times{};
};
} // namespace Skinner

0 comments on commit 9381d7a

Please sign in to comment.