Skip to content

Commit

Permalink
Add support for Exodus IOSS properties related to field interpretatio…
Browse files Browse the repository at this point in the history
…n to the Catalyst IOSS Database (sandialabs#456)

* Refactored testing infrastructure to add transient unstructured fields

* First test failing, for wrong reason

* Test Fixture completed. First failing test done.

* Added failing tests for all 5 Props. Need to update Frwrk for Sur_Split_type

* Refactored get*block() to be public

* Added failing list for SURFACE_SPLIT_TYPE. Compromises made

* Fixed conduit error related to scoping. Refactored tests a bit

* Implemented Exodus IOSS properties. Removed asserts. Finished verifying fields

* Refactored readField() to not have DatabaseIO as parameter
  • Loading branch information
ajpelle authored and tokusanya committed Jul 16, 2024
1 parent f185aa3 commit eb5eb69
Show file tree
Hide file tree
Showing 11 changed files with 710 additions and 26 deletions.
110 changes: 97 additions & 13 deletions packages/seacas/libraries/ioss/src/catalyst/Iocatalyst_DatabaseIO.C
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <tokenize.h>

#include "Ioss_CommSet.h" // for CommSet
#include "Ioss_CodeTypes.h" // for IOSS_SCALAR()
#include "Ioss_DBUsage.h" // for DatabaseUsage, etc
#include "Ioss_DatabaseIO.h" // for DatabaseIO
#include "Ioss_EdgeBlock.h" // for EdgeBlock
Expand Down Expand Up @@ -141,6 +142,8 @@ namespace Iocatalyst {
inline static const std::string RANGEEND = "m_rangeEnd";
inline static const std::string FACE = "m_face";

inline static const std::string SURFACESPLITTYPE = "surface_split_type";

std::string getValuePath(const std::string &prop)
{
return detail::PROPERTIES + detail::FS + prop + detail::FS + detail::VALUE;
Expand Down Expand Up @@ -305,12 +308,17 @@ namespace Iocatalyst {

bool defineModel(Ioss::Region *region)
{
assert(region->model_defined());
if(!region->model_defined()) {
std::ostringstream errmsg;
errmsg << "Catalyst Write in defineModel(): model isn't defined in region"<<"\n";
IOSS_ERROR(errmsg);
}

auto &node = this->DBNode;
node = conduit_cpp::Node();

node[detail::getAPISizePath()].set_int8(region->get_database()->int_byte_size_api());
node[detail::SURFACESPLITTYPE].set_int8(region->get_database()->get_surface_split_type());
RegionContainer rc;
rc.push_back(region);
this->defineEntityGroup(node[detail::REGION], rc);
Expand Down Expand Up @@ -810,6 +818,24 @@ namespace Iocatalyst {
template <typename GroupingEntityT>
bool readFields(const conduit_cpp::Node &&parent, GroupingEntityT *block) const
{
//Assumption: count = entity_count (in block)
Ioss::DatabaseIO *dbase = block->get_database();
Ioss::EntityType b_t = block->type();
bool is_entity_block = false;
if(b_t == Ioss::EntityType::ELEMENTBLOCK ||
b_t == Ioss::EntityType::EDGEBLOCK ||
b_t == Ioss::EntityType::FACEBLOCK ||
b_t == Ioss::EntityType::NODEBLOCK ||
b_t == Ioss::EntityType::SIDEBLOCK ||
b_t == Ioss::EntityType::STRUCTUREDBLOCK) {
is_entity_block = true;
}
const int FNAME_MAX_LENGTH = 255;
size_t field_count = 0;
char **field_names =
Ioss::Utils::get_name_array(parent.number_of_children(), FNAME_MAX_LENGTH);
size_t entity_count = 0;

for (conduit_index_t idx = 0, max = parent.number_of_children(); idx < max; ++idx) {
auto &&child = parent[idx];
const auto name = child.name();
Expand All @@ -819,17 +845,43 @@ namespace Iocatalyst {
const auto index = child[detail::INDEX].as_int64();
const auto storage = child[detail::STORAGE].as_string();
if (!block->field_exists(name)) {
block->field_add(
if(storage == IOSS_SCALAR() && role==Ioss::Field::TRANSIENT && is_entity_block) {
//Add to get_fields() call
char field_name[FNAME_MAX_LENGTH + 1];
Ioss::Utils::copy_string(field_name, name, FNAME_MAX_LENGTH + 1);
Ioss::Utils::copy_string(field_names[field_count++], field_name, FNAME_MAX_LENGTH + 1);
if(entity_count == 0)
entity_count = count;
}
else {
block->field_add(
Ioss::Field(name, type, storage, role, count, index).set_zero_copy_enabled());
}
}
else {
// TODO verify field details.
auto field = block->get_fieldref(name);
if (!field.has_transform()) {
// Verify field details.
auto field_block = block->get_fieldref(name);
if (!field_block.has_transform()) {
block->get_fieldref(name).set_zero_copy_enabled();
}
assert(field.get_type() == type);
auto f = block->get_fieldref(name);
auto field_conduit = Ioss::Field(name, type, storage, role, count, index).set_zero_copy_enabled();
if(field_block != field_conduit) {
std::ostringstream errmsg;
errmsg << "Catalyst Read: Field '"<<name<<"' from conduit "<<
"already exists in block '"<<block->name().c_str()<<
"' of type '"<<block->type_string()<<"' and differs from it\n";
IOSS_ERROR(errmsg);
}
}
}

//Apply Exodus Properties to Scalar Fields in Entity Blocks
if(field_count > 0) {
std::vector<Ioss::Field> fields;
Ioss::Utils::get_fields(entity_count, field_names, field_count, Ioss::Field::TRANSIENT,
dbase, nullptr, fields);
for (const auto &field : fields) {
block->field_add(field.set_zero_copy_enabled());
}
}

Expand Down Expand Up @@ -1039,6 +1091,12 @@ namespace Iocatalyst {
auto &node = this->DBNode;
region->get_database()->set_int_byte_size_api(
static_cast<Ioss::DataSize>(node[detail::getAPISizePath()].as_int8()));
const auto write_split_type =
static_cast<Ioss::SurfaceSplitType>(node[detail::SURFACESPLITTYPE].as_int8());
if(write_split_type != region->get_database()->get_surface_split_type()) {
static_cast<DatabaseIO*>(region->get_database())->set_split_type_changed(true);
}

auto tpath = detail::REGION + detail::FS + detail::TIME;
if (node.has_path(tpath)) {
region->add_state(node[tpath].to_float64());
Expand All @@ -1048,8 +1106,14 @@ namespace Iocatalyst {
this->readEntityGroup<Ioss::ElementBlock>(node[detail::ELEMENTBLOCKS], region);
this->readEntityGroup<Ioss::EdgeBlock>(node[detail::EDGEBLOCKS], region);
this->readEntityGroup<Ioss::FaceBlock>(node[detail::FACEBLOCKS], region);
this->readEntityGroup<Ioss::SideBlock>(node[detail::SIDEBLOCKS], region);
this->readEntityGroup<Ioss::SideSet>(node[detail::SIDESETS], region);

bool surface_split_changed =
static_cast<DatabaseIO*>(region->get_database())->split_type_changed();
if(!surface_split_changed) {
this->readEntityGroup<Ioss::SideBlock>(node[detail::SIDEBLOCKS], region);
this->readEntityGroup<Ioss::SideSet>(node[detail::SIDESETS], region);
}

this->readEntityGroup<Ioss::NodeSet>(node[detail::NODESETS], region);
this->readEntityGroup<Ioss::EdgeSet>(node[detail::EDGESETS], region);
this->readEntityGroup<Ioss::FaceSet>(node[detail::FACESETS], region);
Expand Down Expand Up @@ -1116,11 +1180,19 @@ namespace Iocatalyst {

bool DatabaseIO::end_nl(Ioss::State state)
{
assert(this->dbState == state);
if(this->dbState != state) {
std::ostringstream errmsg;
errmsg << "Catalyst: dbState != state in end_nl"<<"\n";
IOSS_ERROR(errmsg);
}

if (!is_input()) {
auto region = this->get_region();
assert(region != nullptr);
if(region == nullptr) {
std::ostringstream errmsg;
errmsg << "Catalyst: region is nullptr in end_nl"<<"\n";
IOSS_ERROR(errmsg);
}

auto &impl = (*this->Impl.get());
switch (state) {
Expand Down Expand Up @@ -1180,7 +1252,11 @@ namespace Iocatalyst {
void DatabaseIO::read_meta_data_nl()
{
auto region = this->get_region();
assert(region != nullptr);
if(region == nullptr) {
std::ostringstream errmsg;
errmsg << "Catalyst: region is nullptr in read_meta_data_nl()"<<"\n";
IOSS_ERROR(errmsg);
}

auto &impl = (*this->Impl.get());
impl.readModel(region);
Expand All @@ -1189,7 +1265,11 @@ namespace Iocatalyst {
void DatabaseIO::get_step_times_nl()
{
auto region = this->get_region();
assert(region != nullptr);
if(region == nullptr) {
std::ostringstream errmsg;
errmsg << "Catalyst: region is nullptr in get_step_times_nl()"<<"\n";
IOSS_ERROR(errmsg);
}

auto &impl = (*this->Impl.get());
impl.readTime(region);
Expand Down Expand Up @@ -1420,6 +1500,7 @@ namespace Iocatalyst {
int64_t DatabaseIO::get_field_internal(const Ioss::SideBlock *sb, const Ioss::Field &field,
void *data, size_t data_size) const
{
if(split_type_changed()) { return -1; }
auto &impl = (*this->Impl.get());
return impl.getField(detail::SIDEBLOCKS, sb, field, data, data_size);
}
Expand Down Expand Up @@ -1450,6 +1531,7 @@ namespace Iocatalyst {
int64_t DatabaseIO::get_field_internal(const Ioss::SideSet *ss, const Ioss::Field &field,
void *data, size_t data_size) const
{
if(split_type_changed()) { return -1; }
auto &impl = (*this->Impl.get());
return impl.getField(detail::SIDESETS, ss, field, data, data_size);
}
Expand Down Expand Up @@ -1531,6 +1613,7 @@ namespace Iocatalyst {
int64_t DatabaseIO::get_zc_field_internal(const Ioss::SideBlock *sb, const Ioss::Field &field,
void **data, size_t *data_size) const
{
if(split_type_changed()) { return -1; }
auto &impl = (*this->Impl.get());
return impl.getFieldZeroCopy(detail::SIDEBLOCKS, sb, field, data, data_size);
}
Expand Down Expand Up @@ -1561,6 +1644,7 @@ namespace Iocatalyst {
int64_t DatabaseIO::get_zc_field_internal(const Ioss::SideSet *ss, const Ioss::Field &field,
void **data, size_t *data_size) const
{
if(split_type_changed()) { return -1; }
auto &impl = (*this->Impl.get());
return impl.getFieldZeroCopy(detail::SIDESETS, ss, field, data, data_size);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ namespace Iocatalyst {

std::string get_catalyst_dump_dir() const;

void set_split_type_changed(bool split_type_changed) { split_type_c = split_type_changed; }
IOSS_NODISCARD bool split_type_changed() const { return split_type_c; }

private:
bool open_group_nl(const std::string & /* group_name */) override { return false; }
bool create_subgroup_nl(const std::string & /* group_name */) override { return false; }
Expand Down Expand Up @@ -202,5 +205,6 @@ namespace Iocatalyst {
class ImplementationT;
std::unique_ptr<ImplementationT> Impl;
bool useDeepCopy;
bool split_type_c{false};
};
} // namespace Iocatalyst
Original file line number Diff line number Diff line change
Expand Up @@ -291,4 +291,24 @@ namespace Iocatalyst {
return (extents.i + offset) * (extents.j + offset) * (extents.k + offset);
}

std::map<std::string, double>* BlockMesh::getTransientCellFieldMap()
{
return &(this->transientCellFields);
}

std::map<std::string, double>* BlockMesh::getTransientPointFieldMap()
{
return &(this->transientPointFields);
}

void BlockMesh::addTransientCellField(std::string f_name, double f_value)
{
this->transientCellFields.insert({ f_name, f_value });
}

void BlockMesh::addTransientPointField(std::string f_name, double f_value)
{
this->transientPointFields.insert({ f_name, f_value });
}

} // namespace Iocatalyst
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ namespace Iocatalyst {
static Extent getCoordsForID(ID id, Extent bounds);
static ID getIDfromCoords(Extent coords, Extent bounds);

void addTransientCellField(std::string f_name, double f_value);
void addTransientPointField(std::string f_name, double f_value);

std::map<std::string, double>* getTransientCellFieldMap();
std::map<std::string, double>* getTransientPointFieldMap();

private:
Partition partition;
Extent origin;
Expand All @@ -98,6 +104,9 @@ namespace Iocatalyst {
int getNumInBlockMesh(unsigned int offset) const;
ID id;
static ID _id;

std::map<std::string, double> transientCellFields;
std::map<std::string, double> transientPointFields;
};

} // namespace Iocatalyst
Loading

0 comments on commit eb5eb69

Please sign in to comment.