From 2818b8a3a05bd3792cb13620dfb1e8316b45e776 Mon Sep 17 00:00:00 2001 From: David Andrs Date: Thu, 8 Oct 2026 09:07:18 -0600 Subject: [PATCH] Adding `File::get_elemental_var_table()` --- include/exodusIIcpp/file.h | 7 ++++++ include/exodusIIcpp/truth_table.h | 40 +++++++++++++++++++++++++++++++ python/src/exodusIIcpp.cpp | 3 +++ src/file.cpp | 15 ++++++++++++ test/File_test.cpp | 3 +++ 5 files changed, 68 insertions(+) create mode 100644 include/exodusIIcpp/truth_table.h diff --git a/include/exodusIIcpp/file.h b/include/exodusIIcpp/file.h index d4841ec..f1ac611 100644 --- a/include/exodusIIcpp/file.h +++ b/include/exodusIIcpp/file.h @@ -11,6 +11,7 @@ #include "exodusIIcpp/error.h" #include "exodusIIcpp/node_set.h" #include "exodusIIcpp/side_set.h" +#include "exodusIIcpp/truth_table.h" namespace fs = std::filesystem; @@ -148,6 +149,12 @@ class File { /// @return The number of side sets int get_num_side_sets() const; + /// Get elemental variable table + /// + /// @return Truth table. Rows are block indices (not IDs), columns are + /// variable indices. Both are 1-based indices! + TruthTable get_elemental_var_table() const; + /// Get the x-coordinates of nodes /// /// @return The x-coordinates of nodes diff --git a/include/exodusIIcpp/truth_table.h b/include/exodusIIcpp/truth_table.h new file mode 100644 index 0000000..efa8e8f --- /dev/null +++ b/include/exodusIIcpp/truth_table.h @@ -0,0 +1,40 @@ +// SPDX-FileCopyrightText: 2026 David Andrs +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +namespace exodusIIcpp { + +class TruthTable { +public: + ~TruthTable() { delete[] this->data; } + + /// Get value from row `i` and column `j` + /// + /// @param i Row (1-based) + /// @param j Column (1-based) + bool + operator()(int i, int j) + { + int ofst = (i - 1) * this->n_cols + (j - 1); + return this->data[ofst] == 1; + } + +private: + TruthTable(int rows, int cols) : n_cols(cols) + { + std::size_t n_elems = static_cast(rows) * static_cast(cols); + this->data = new int[n_elems]; + std::memset(this->data, 0, n_elems * sizeof(int)); + } + + int n_cols; + int * data; + + friend class File; +}; + +} // namespace exodusIIcpp diff --git a/python/src/exodusIIcpp.cpp b/python/src/exodusIIcpp.cpp index 031a07e..07b7c25 100644 --- a/python/src/exodusIIcpp.cpp +++ b/python/src/exodusIIcpp.cpp @@ -21,6 +21,8 @@ PYBIND11_MODULE(exodusIIcpp, m) .value("WRITE", exodusIIcpp::FileAccess::WRITE) .value("APPEND", exodusIIcpp::FileAccess::APPEND); + py::class_(m, "TruthTable"); + py::class_(m, "ElementBlock") .def(py::init()) .def("get_id", &ElementBlock::get_id) @@ -78,6 +80,7 @@ PYBIND11_MODULE(exodusIIcpp, m) .def("get_num_element_blocks", &File::get_num_element_blocks) .def("get_num_node_sets", &File::get_num_node_sets) .def("get_num_side_sets", &File::get_num_side_sets) + .def("get_elemental_var_table", &File::get_elemental_var_table) .def("get_x_coords", &File::get_x_coords) .def("get_y_coords", &File::get_y_coords) .def("get_z_coords", &File::get_z_coords) diff --git a/src/file.cpp b/src/file.cpp index 77f8300..d5b679b 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -247,6 +247,21 @@ File::get_num_side_sets() const return this->n_side_sets; } +TruthTable +File::get_elemental_var_table() const +{ + int num_elem_var = 0; + EXODUSIICPP_CHECK_ERROR(ex_get_variable_param(exoid, EX_ELEM_BLOCK, &num_elem_var)); + + TruthTable truth_table(this->n_elem_blks, num_elem_var); + EXODUSIICPP_CHECK_ERROR(ex_get_truth_table(this->exoid, + EX_ELEM_BLOCK, + this->n_elem_blks, + num_elem_var, + truth_table.data)); + return truth_table; +} + const std::vector & File::get_x_coords() const { diff --git a/test/File_test.cpp b/test/File_test.cpp index aa269cb..765ba81 100644 --- a/test/File_test.cpp +++ b/test/File_test.cpp @@ -387,6 +387,9 @@ TEST(FileTest, test) EXPECT_THAT(ss_cnts, ElementsAre(2, 2)); EXPECT_THAT(ss_nodes, ElementsAre(2, 3, 7, 8)); + auto ev_tab = f.get_elemental_var_table(); + EXPECT_TRUE(ev_tab(1, 3)); + f.close(); } }