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.
513 lines
22 KiB
513 lines
22 KiB
2 years ago
|
// Copyright(C) 1999-2022 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 "ED_SystemInterface.h" // for SystemInterface, interFace
|
||
|
#include "Tolerance.h" // for Tolerance, etc
|
||
|
#include "exo_entity.h" // for Exo_Entity, EXOTYPE
|
||
|
#include "exodusII.h"
|
||
|
#include "fmt/color.h"
|
||
|
#include "fmt/ostream.h"
|
||
|
#include "smart_assert.h" // for SMART_ASSERT
|
||
|
#include "stringx.h" // for find_string, etc
|
||
|
#include "util.h"
|
||
|
#include <cstddef> // for size_t
|
||
|
#include <cstdio> // for nullptr
|
||
|
#include <string> // for string, char_traits, etc
|
||
|
#include <vector> // for vector
|
||
|
template <typename INT> class ExoII_Read;
|
||
|
|
||
|
namespace {
|
||
|
void build_variable_names(const char *type, std::vector<std::string> &names,
|
||
|
std::vector<Tolerance> &tols, const Tolerance &default_tol,
|
||
|
bool do_all_flag, const std::vector<std::string> &var_names1,
|
||
|
const std::vector<std::string> &var_names2, bool *diff_found);
|
||
|
|
||
|
template <typename INT>
|
||
|
void build_truth_table(EXOTYPE type, const char *label, std::vector<std::string> &names,
|
||
|
size_t num_entity, ExoII_Read<INT> &file1, ExoII_Read<INT> &file2,
|
||
|
const std::vector<std::string> &var_names1,
|
||
|
const std::vector<std::string> &var_names2, std::vector<int> &truth_tab,
|
||
|
bool quiet_flag, bool *diff_found);
|
||
|
|
||
|
void output_exodus_names(int file_id, EXOTYPE type, const std::vector<std::string> &names);
|
||
|
void output_diff_names(const char *type, const std::vector<std::string> &names);
|
||
|
void output_compare_names(const char *type, const std::vector<std::string> &names,
|
||
|
const std::vector<Tolerance> &tol, int num_vars1, int num_vars2);
|
||
|
} // namespace
|
||
|
|
||
|
template <typename INT>
|
||
|
void Build_Variable_Names(ExoII_Read<INT> &file1, ExoII_Read<INT> &file2, bool *diff_found)
|
||
|
{
|
||
|
// Build (and compare) global variable names.
|
||
|
build_variable_names("global", interFace.glob_var_names, interFace.glob_var,
|
||
|
interFace.glob_var_default, interFace.glob_var_do_all_flag,
|
||
|
file1.Global_Var_Names(), file2.Global_Var_Names(), diff_found);
|
||
|
|
||
|
// Build (and compare) nodal variable names.
|
||
|
build_variable_names("nodal", interFace.node_var_names, interFace.node_var,
|
||
|
interFace.node_var_default, interFace.node_var_do_all_flag,
|
||
|
file1.Nodal_Var_Names(), file2.Nodal_Var_Names(), diff_found);
|
||
|
|
||
|
// Build (and compare) element variable names.
|
||
|
build_variable_names("element", interFace.elmt_var_names, interFace.elmt_var,
|
||
|
interFace.elmt_var_default, interFace.elmt_var_do_all_flag,
|
||
|
file1.Element_Var_Names(), file2.Element_Var_Names(), diff_found);
|
||
|
|
||
|
// Build (and compare) element variable names.
|
||
|
if (!interFace.ignore_attributes) {
|
||
|
build_variable_names("element attribute", interFace.elmt_att_names, interFace.elmt_att,
|
||
|
interFace.elmt_att_default, interFace.elmt_att_do_all_flag,
|
||
|
file1.Element_Att_Names(), file2.Element_Att_Names(), diff_found);
|
||
|
}
|
||
|
|
||
|
// Build (and compare) nodeset variable names.
|
||
|
build_variable_names("nodeset", interFace.ns_var_names, interFace.ns_var,
|
||
|
interFace.ns_var_default, interFace.ns_var_do_all_flag, file1.NS_Var_Names(),
|
||
|
file2.NS_Var_Names(), diff_found);
|
||
|
|
||
|
// Build (and compare) sideset variable names.
|
||
|
build_variable_names("sideset", interFace.ss_var_names, interFace.ss_var,
|
||
|
interFace.ss_var_default, interFace.ss_var_do_all_flag, file1.SS_Var_Names(),
|
||
|
file2.SS_Var_Names(), diff_found);
|
||
|
|
||
|
// Build (and compare) edgeblock variable names.
|
||
|
build_variable_names("edgeblock", interFace.eb_var_names, interFace.eb_var,
|
||
|
interFace.eb_var_default, interFace.eb_var_do_all_flag, file1.EB_Var_Names(),
|
||
|
file2.EB_Var_Names(), diff_found);
|
||
|
|
||
|
// Build (and compare) faceblock variable names.
|
||
|
build_variable_names("faceblock", interFace.fb_var_names, interFace.fb_var,
|
||
|
interFace.fb_var_default, interFace.fb_var_do_all_flag, file1.FB_Var_Names(),
|
||
|
file2.FB_Var_Names(), diff_found);
|
||
|
}
|
||
|
|
||
|
template <typename INT>
|
||
|
int Create_File(ExoII_Read<INT> &file1, ExoII_Read<INT> &file2, const std::string &diffile_name,
|
||
|
bool *diff_found)
|
||
|
{
|
||
|
// Multiple modes:
|
||
|
// summary_flag == true --> Single file, output summary and variable names, return
|
||
|
// diffile_name == "" --> Dual file, output summary, variable names, check compatibility,
|
||
|
// diffile_name != "" --> Three files (2 in, 1 out)
|
||
|
// create output file which is diff of input.
|
||
|
// output summary, variable names, check compatibility
|
||
|
// quiet_flag == true --> don't output summary information
|
||
|
|
||
|
SMART_ASSERT(!interFace.summary_flag);
|
||
|
//========================================================================
|
||
|
// From here on down, have two input files and possibly 1 output file...
|
||
|
// Create output file.
|
||
|
|
||
|
int out_file_id = -1;
|
||
|
if (!diffile_name.empty()) {
|
||
|
|
||
|
// Take minimum word size for output file.
|
||
|
int iows =
|
||
|
file1.IO_Word_Size() < file2.IO_Word_Size() ? file1.IO_Word_Size() : file2.IO_Word_Size();
|
||
|
int compws = sizeof(double);
|
||
|
|
||
|
int mode = EX_CLOBBER;
|
||
|
if (sizeof(INT) == 8) {
|
||
|
mode |= EX_ALL_INT64_DB;
|
||
|
mode |= EX_ALL_INT64_API;
|
||
|
}
|
||
|
out_file_id = ex_create(diffile_name.c_str(), mode, &compws, &iows);
|
||
|
if (out_file_id < 0) {
|
||
|
Error(fmt::format("Couldn't create output file \"{}\".\n", diffile_name));
|
||
|
}
|
||
|
ex_copy(file1.File_ID(), out_file_id);
|
||
|
}
|
||
|
|
||
|
if (!interFace.quiet_flag) {
|
||
|
if (out_file_id >= 0) { // The files are to be differenced .. just list names.
|
||
|
if (interFace.coord_tol.type != ToleranceMode::IGNORE_) {
|
||
|
fmt::print("Coordinates: tol: {:8g} {}, floor: {:8g}\n", interFace.coord_tol.value,
|
||
|
interFace.coord_tol.typestr(), interFace.coord_tol.floor);
|
||
|
}
|
||
|
else {
|
||
|
fmt::print("Locations of nodes will not be considered.\n");
|
||
|
}
|
||
|
if (interFace.time_tol.type != ToleranceMode::IGNORE_) {
|
||
|
fmt::print("Time step values: tol: {:8g} {}, floor: {:8g}\n", interFace.time_tol.value,
|
||
|
interFace.time_tol.typestr(), interFace.time_tol.floor);
|
||
|
}
|
||
|
else {
|
||
|
fmt::print("Time step time values will not be differenced.\n");
|
||
|
}
|
||
|
output_diff_names("Global", interFace.glob_var_names);
|
||
|
output_diff_names("Nodal", interFace.node_var_names);
|
||
|
output_diff_names("Element", interFace.elmt_var_names);
|
||
|
output_diff_names("Element Attribute", interFace.elmt_att_names);
|
||
|
output_diff_names("Nodeset", interFace.ns_var_names);
|
||
|
output_diff_names("Sideset", interFace.ss_var_names);
|
||
|
output_diff_names("Edgeblock", interFace.eb_var_names);
|
||
|
output_diff_names("Faceblock", interFace.fb_var_names);
|
||
|
}
|
||
|
else { // The files are to be compared .. echo additional info.
|
||
|
if (Tolerance::use_old_floor) {
|
||
|
std::ostringstream info;
|
||
|
fmt::print(info, "INFO: Using old definition of floor tolerance. |a-b|<floor.\n\n");
|
||
|
DIFF_OUT(info, fmt::color::yellow);
|
||
|
}
|
||
|
if (interFace.coord_tol.type != ToleranceMode::IGNORE_) {
|
||
|
fmt::print(
|
||
|
"\nNodal coordinates will be compared:\n {:<{}} tol: {:8g} ({}), floor: {:8g}\n",
|
||
|
"...", name_length(), interFace.coord_tol.value, interFace.coord_tol.typestr(),
|
||
|
interFace.coord_tol.floor);
|
||
|
}
|
||
|
else {
|
||
|
std::ostringstream info;
|
||
|
fmt::print(info, "\nNodal coordinates will not be compared.\n");
|
||
|
DIFF_OUT(info, fmt::color::yellow);
|
||
|
}
|
||
|
|
||
|
if (interFace.time_tol.type != ToleranceMode::IGNORE_) {
|
||
|
fmt::print("Time step values will be compared:\n {:<{}} tol: {:8g} ({}), floor: {:8g}\n",
|
||
|
"...", name_length(), interFace.time_tol.value, interFace.time_tol.typestr(),
|
||
|
interFace.time_tol.floor);
|
||
|
}
|
||
|
else {
|
||
|
std::ostringstream info;
|
||
|
fmt::print(info, "Time step time values will not be compared.\n");
|
||
|
DIFF_OUT(info, fmt::color::yellow);
|
||
|
}
|
||
|
|
||
|
output_compare_names("Global", interFace.glob_var_names, interFace.glob_var,
|
||
|
file1.Num_Global_Vars(), file2.Num_Global_Vars());
|
||
|
|
||
|
output_compare_names("Nodal", interFace.node_var_names, interFace.node_var,
|
||
|
file1.Num_Nodal_Vars(), file2.Num_Nodal_Vars());
|
||
|
|
||
|
output_compare_names("Element", interFace.elmt_var_names, interFace.elmt_var,
|
||
|
file1.Num_Element_Vars(), file2.Num_Element_Vars());
|
||
|
|
||
|
output_compare_names("Element Attribute", interFace.elmt_att_names, interFace.elmt_att,
|
||
|
file1.Num_Element_Atts(), file2.Num_Element_Atts());
|
||
|
|
||
|
output_compare_names("Nodeset", interFace.ns_var_names, interFace.ns_var, file1.Num_NS_Vars(),
|
||
|
file2.Num_NS_Vars());
|
||
|
|
||
|
output_compare_names("Sideset", interFace.ss_var_names, interFace.ss_var, file1.Num_SS_Vars(),
|
||
|
file2.Num_SS_Vars());
|
||
|
if (!interFace.ignore_sideset_df && interFace.ss_df_tol.type != ToleranceMode::IGNORE_ &&
|
||
|
file1.Num_Side_Sets() > 0 && file2.Num_Side_Sets() > 0) {
|
||
|
fmt::print("Sideset Distribution Factors will be compared:\n {:<{}} tol: {:8g} ({}), "
|
||
|
"floor: {:8g}\n",
|
||
|
"...", name_length(), interFace.ss_df_tol.value, interFace.ss_df_tol.typestr(),
|
||
|
interFace.ss_df_tol.floor);
|
||
|
}
|
||
|
else {
|
||
|
if (interFace.ignore_sideset_df || interFace.ss_df_tol.type == ToleranceMode::IGNORE_) {
|
||
|
std::ostringstream info;
|
||
|
fmt::print(info, "Sideset Distribution Factors will not be compared.\n");
|
||
|
DIFF_OUT(info, fmt::color::yellow);
|
||
|
}
|
||
|
else {
|
||
|
fmt::print("No Sideset Distribution Factors on either file.\n");
|
||
|
}
|
||
|
}
|
||
|
output_compare_names("Edgeblock", interFace.eb_var_names, interFace.eb_var,
|
||
|
file1.Num_EB_Vars(), file2.Num_EB_Vars());
|
||
|
output_compare_names("Faceblock", interFace.fb_var_names, interFace.fb_var,
|
||
|
file1.Num_FB_Vars(), file2.Num_FB_Vars());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::vector<int> truth_tab;
|
||
|
build_truth_table(EX_ELEM_BLOCK, "Element Block", interFace.elmt_var_names,
|
||
|
file1.Num_Element_Blocks(), file1, file2, file1.Element_Var_Names(),
|
||
|
file2.Element_Var_Names(), truth_tab, interFace.quiet_flag, diff_found);
|
||
|
|
||
|
std::vector<int> ns_truth_tab;
|
||
|
build_truth_table(EX_NODE_SET, "Nodeset", interFace.ns_var_names, file1.Num_Node_Sets(), file1,
|
||
|
file2, file1.NS_Var_Names(), file2.NS_Var_Names(), ns_truth_tab,
|
||
|
interFace.quiet_flag, diff_found);
|
||
|
|
||
|
std::vector<int> ss_truth_tab;
|
||
|
build_truth_table(EX_SIDE_SET, "Sideset", interFace.ss_var_names, file1.Num_Side_Sets(), file1,
|
||
|
file2, file1.SS_Var_Names(), file2.SS_Var_Names(), ss_truth_tab,
|
||
|
interFace.quiet_flag, diff_found);
|
||
|
|
||
|
std::vector<int> eb_truth_tab;
|
||
|
build_truth_table(EX_EDGE_BLOCK, "Edgeblock", interFace.eb_var_names, file1.Num_Edge_Blocks(),
|
||
|
file1, file2, file1.EB_Var_Names(), file2.EB_Var_Names(), eb_truth_tab,
|
||
|
interFace.quiet_flag, diff_found);
|
||
|
|
||
|
std::vector<int> fb_truth_tab;
|
||
|
build_truth_table(EX_FACE_BLOCK, "Faceblock", interFace.fb_var_names, file1.Num_Face_Blocks(),
|
||
|
file1, file2, file1.FB_Var_Names(), file2.FB_Var_Names(), fb_truth_tab,
|
||
|
interFace.quiet_flag, diff_found);
|
||
|
|
||
|
// Put out the concatenated variable parameters here and then
|
||
|
// put out the names....
|
||
|
if (out_file_id >= 0) {
|
||
|
ex_put_all_var_param(out_file_id, interFace.glob_var_names.size(),
|
||
|
interFace.node_var_names.size(), interFace.elmt_var_names.size(),
|
||
|
truth_tab.data(), interFace.ns_var_names.size(), ns_truth_tab.data(),
|
||
|
interFace.ss_var_names.size(), ss_truth_tab.data());
|
||
|
|
||
|
output_exodus_names(out_file_id, EX_GLOBAL, interFace.glob_var_names);
|
||
|
output_exodus_names(out_file_id, EX_NODAL, interFace.node_var_names);
|
||
|
output_exodus_names(out_file_id, EX_ELEM_BLOCK, interFace.elmt_var_names);
|
||
|
output_exodus_names(out_file_id, EX_NODE_SET, interFace.ns_var_names);
|
||
|
output_exodus_names(out_file_id, EX_SIDE_SET, interFace.ss_var_names);
|
||
|
output_exodus_names(out_file_id, EX_EDGE_BLOCK, interFace.eb_var_names);
|
||
|
output_exodus_names(out_file_id, EX_FACE_BLOCK, interFace.fb_var_names);
|
||
|
}
|
||
|
return out_file_id;
|
||
|
}
|
||
|
|
||
|
namespace {
|
||
|
void output_exodus_names(int file_id, EXOTYPE type, const std::vector<std::string> &names)
|
||
|
{
|
||
|
if (!names.empty()) {
|
||
|
std::vector<char *> vars(names.size());
|
||
|
for (unsigned i = 0; i < names.size(); ++i) {
|
||
|
vars[i] = const_cast<char *>(names[i].c_str());
|
||
|
SMART_ASSERT(vars[i] != nullptr);
|
||
|
}
|
||
|
ex_put_variable_names(file_id, type, names.size(), vars.data());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void output_compare_names(const char *type, const std::vector<std::string> &names,
|
||
|
const std::vector<Tolerance> &tol, int num_vars1, int num_vars2)
|
||
|
{
|
||
|
if (!names.empty()) {
|
||
|
fmt::print("{} variables to be compared:\n", type);
|
||
|
for (unsigned v = 0; v < names.size(); ++v) {
|
||
|
if (v == 0) {
|
||
|
fmt::print(" {:<{}} tol: {:8g} ({}), floor: {:8g}\n", names[v], name_length(),
|
||
|
tol[v].value, tol[v].typestr(), tol[v].floor);
|
||
|
}
|
||
|
else {
|
||
|
fmt::print(" {:<{}} {:8g} ({}), {:8g}\n", names[v], name_length(),
|
||
|
tol[v].value, tol[v].typestr(), tol[v].floor);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if (num_vars1 == 0 && num_vars2 == 0) {
|
||
|
fmt::print("No {} variables on either file.\n", type);
|
||
|
}
|
||
|
else {
|
||
|
fmt::print("{} variables will not be compared.\n", type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void output_diff_names(const char *type, const std::vector<std::string> &names)
|
||
|
{
|
||
|
if (!names.empty()) {
|
||
|
fmt::print("{} variables to be differenced:\n", type);
|
||
|
for (auto &name : names) {
|
||
|
fmt::print("\t{}\n", name);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
fmt::print("No {} variables will be differenced.\n", type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void build_variable_names(const char *type, std::vector<std::string> &names,
|
||
|
std::vector<Tolerance> &tols, const Tolerance &default_tol,
|
||
|
bool do_all_flag, const std::vector<std::string> &var_names1,
|
||
|
const std::vector<std::string> &var_names2, bool *diff_found)
|
||
|
{
|
||
|
std::vector<std::string> x_list; // exclusion list
|
||
|
for (auto name : names) {
|
||
|
chop_whitespace(name);
|
||
|
SMART_ASSERT(!name.empty());
|
||
|
if (name[0] == '!') {
|
||
|
x_list.push_back(extract_token(name, "!")); // remove "!" & add
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (do_all_flag) {
|
||
|
auto length_name = var_names1.size();
|
||
|
for (size_t n = 0; n < length_name; ++n) {
|
||
|
const std::string &name = var_names1[n];
|
||
|
if (!interFace.summary_flag &&
|
||
|
find_string(var_names2, name, interFace.nocase_var_names) < 0) {
|
||
|
if (find_string(x_list, name, interFace.nocase_var_names) < 0) {
|
||
|
if (interFace.allowNameMismatch) {
|
||
|
x_list.push_back(name);
|
||
|
}
|
||
|
else {
|
||
|
*diff_found = true;
|
||
|
if (!interFace.quiet_flag) {
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(diff,
|
||
|
"exodiff: DIFFERENCE .. The {} variable \"{}\" is in the first file but "
|
||
|
"not the second.\n",
|
||
|
type, name);
|
||
|
DIFF_OUT(diff);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (find_string(names, name, interFace.nocase_var_names) < 0 &&
|
||
|
find_string(x_list, name, interFace.nocase_var_names) < 0) {
|
||
|
names.push_back(name);
|
||
|
tols.push_back(default_tol);
|
||
|
SMART_ASSERT(names.size() == tols.size())(names.size())(tols.size());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!interFace.noSymmetricNameCheck) {
|
||
|
length_name = var_names2.size();
|
||
|
for (size_t n = 0; n < length_name; ++n) {
|
||
|
const std::string &name = var_names2[n];
|
||
|
if (!interFace.summary_flag &&
|
||
|
find_string(var_names1, name, interFace.nocase_var_names) < 0) {
|
||
|
if (find_string(x_list, name, interFace.nocase_var_names) < 0) {
|
||
|
*diff_found = true;
|
||
|
if (!interFace.quiet_flag) {
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(diff,
|
||
|
"exodiff: DIFFERENCE .. The {} variable \"{}\" is in the second file "
|
||
|
"but not the first.\n",
|
||
|
type, name);
|
||
|
DIFF_OUT(diff);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
SMART_ASSERT(find_string(names, name, interFace.nocase_var_names) >= 0 ||
|
||
|
find_string(x_list, name, interFace.nocase_var_names) >= 0);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::vector<std::string> tmp_list;
|
||
|
std::vector<Tolerance> tmp_tols;
|
||
|
for (size_t n = 0; n < names.size(); ++n) {
|
||
|
std::string name = names[n];
|
||
|
chop_whitespace(name);
|
||
|
if (name[0] == '!') {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
int idx = find_string(var_names1, name, interFace.nocase_var_names);
|
||
|
if (idx >= 0) {
|
||
|
if (interFace.summary_flag ||
|
||
|
find_string(var_names2, name, interFace.nocase_var_names) >= 0) {
|
||
|
tmp_tols.push_back(tols[n]);
|
||
|
tmp_list.push_back(var_names1[idx]);
|
||
|
}
|
||
|
else {
|
||
|
*diff_found = true;
|
||
|
if (!interFace.quiet_flag) {
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(diff,
|
||
|
"exodiff: DIFFERENCE .. The {} variable \"{}\" is not in the second file.\n",
|
||
|
type, name);
|
||
|
DIFF_OUT(diff);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
*diff_found = true;
|
||
|
if (!interFace.quiet_flag) {
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(
|
||
|
diff,
|
||
|
"exodiff: DIFFERENCE .. Specified {} variable \"{}\" is not in the first file.\n",
|
||
|
type, name);
|
||
|
DIFF_OUT(diff);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
names = tmp_list;
|
||
|
tols = tmp_tols;
|
||
|
SMART_ASSERT(names.size() == tols.size())(names.size())(tols.size());
|
||
|
}
|
||
|
|
||
|
template <typename INT>
|
||
|
void build_truth_table(EXOTYPE type, const char *label, std::vector<std::string> &names,
|
||
|
size_t num_entity, ExoII_Read<INT> &file1, ExoII_Read<INT> &file2,
|
||
|
const std::vector<std::string> &var_names1,
|
||
|
const std::vector<std::string> &var_names2, std::vector<int> &truth_tab,
|
||
|
bool quiet_flag, bool *diff_found)
|
||
|
{
|
||
|
if (!names.empty()) {
|
||
|
int num_vars = names.size();
|
||
|
|
||
|
truth_tab.resize(num_vars * num_entity);
|
||
|
for (int i = num_vars * num_entity - 1; i >= 0; --i) {
|
||
|
truth_tab[i] = 0;
|
||
|
}
|
||
|
|
||
|
for (size_t b = 0; b < num_entity; ++b) {
|
||
|
Exo_Entity *set1 = file1.Get_Entity_by_Index(type, b);
|
||
|
Exo_Entity *set2 = nullptr;
|
||
|
if (interFace.by_name) {
|
||
|
set2 = file2.Get_Entity_by_Name(type, set1->Name());
|
||
|
}
|
||
|
else {
|
||
|
set2 = file2.Get_Entity_by_Id(type, set1->Id());
|
||
|
}
|
||
|
|
||
|
if (set2 == nullptr) {
|
||
|
if (interFace.map_flag != MapType::PARTIAL) {
|
||
|
*diff_found = true;
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(diff,
|
||
|
"exodiff: DIFFERENCE {} id {} exists in first file but not the second...\n",
|
||
|
label, set1->Id());
|
||
|
DIFF_OUT(diff);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
for (int out_idx = 0; out_idx < num_vars; ++out_idx) {
|
||
|
const std::string &name = names[out_idx];
|
||
|
int idx1 = find_string(var_names1, name, interFace.nocase_var_names);
|
||
|
int idx2 = find_string(var_names2, name, interFace.nocase_var_names);
|
||
|
if (idx1 < 0 || idx2 < 0) {
|
||
|
Error(fmt::format("Unable to find variable named '{}' on database.\n", name));
|
||
|
}
|
||
|
|
||
|
if (set1->is_valid_var(idx1)) {
|
||
|
if (set2->is_valid_var(idx2)) {
|
||
|
truth_tab[b * num_vars + out_idx] = 1;
|
||
|
}
|
||
|
else if (!quiet_flag) {
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(diff,
|
||
|
"exodiff: INFO {0} variable \"{1}\" is not saved for {0}"
|
||
|
" id {2} in the second file but is in the first (by virtue of the truth "
|
||
|
"tables). "
|
||
|
"This variable won't be considered for this {0}.\n",
|
||
|
label, name, set1->Id());
|
||
|
DIFF_OUT(diff, fmt::color::yellow);
|
||
|
}
|
||
|
}
|
||
|
else if (set2->is_valid_var(idx2) && !quiet_flag) {
|
||
|
std::ostringstream diff;
|
||
|
fmt::print(
|
||
|
diff,
|
||
|
"exodiff: INFO {0} variable \"{1}\" is not saved for {0}"
|
||
|
" id {2} in the first file but is in the second (by virtue of the truth tables). "
|
||
|
"This variable won't be considered for this {0}.\n",
|
||
|
label, name, set1->Id());
|
||
|
DIFF_OUT(diff, fmt::color::yellow);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} // End of namespace
|
||
|
|
||
|
template int Create_File(ExoII_Read<int> &file1, ExoII_Read<int> &file2,
|
||
|
const std::string &diffile_name, bool *diff_found);
|
||
|
template void Build_Variable_Names(ExoII_Read<int> &file1, ExoII_Read<int> &file2,
|
||
|
bool *diff_found);
|
||
|
|
||
|
template int Create_File(ExoII_Read<int64_t> &file1, ExoII_Read<int64_t> &file2,
|
||
|
const std::string &diffile_name, bool *diff_found);
|
||
|
template void Build_Variable_Names(ExoII_Read<int64_t> &file1, ExoII_Read<int64_t> &file2,
|
||
|
bool *diff_found);
|