Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Exodus IOSS properties related to field interpretation to the Catalyst IOSS Database #456

Merged
merged 10 commits into from
May 20, 2024
125 changes: 104 additions & 21 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 @@ -758,7 +766,7 @@ namespace Iocatalyst {
this->readProperties(child[detail::PROPERTIES], block);

// read fields (meta-data only)
this->readFields(child[detail::FIELDS], block);
this->readFields(child[detail::FIELDS], block, region->get_database());
}
return true;
}
Expand Down Expand Up @@ -808,8 +816,25 @@ namespace Iocatalyst {
}

template <typename GroupingEntityT>
bool readFields(const conduit_cpp::Node &&parent, GroupingEntityT *block) const
bool readFields(const conduit_cpp::Node &&parent, GroupingEntityT *block, Ioss::DatabaseIO *dbase) const
gsjaardema marked this conversation as resolved.
Show resolved Hide resolved
{
//Assumption: count = entity_count (in block)
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 +844,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 All @@ -846,7 +897,7 @@ namespace Iocatalyst {
this->readProperties(child[detail::PROPERTIES], region);

// read fields (meta-data only)
this->readFields(child[detail::FIELDS], region);
this->readFields(child[detail::FIELDS], region, region->get_database());
gsjaardema marked this conversation as resolved.
Show resolved Hide resolved
}
return true;
}
Expand All @@ -872,7 +923,7 @@ namespace Iocatalyst {
this->readProperties(child[detail::PROPERTIES], block);

// read fields (meta-data only)
this->readFields(child[detail::FIELDS], block);
this->readFields(child[detail::FIELDS], block, region->get_database());
}
return true;
}
Expand All @@ -899,7 +950,7 @@ namespace Iocatalyst {
this->readProperties(child[detail::PROPERTIES], block);

// read fields (meta-data only)
this->readFields(child[detail::FIELDS], block);
this->readFields(child[detail::FIELDS], block, region->get_database());
}
sideBlocks.clear();
return true;
Expand Down Expand Up @@ -948,7 +999,7 @@ namespace Iocatalyst {
this->readProperties(child[detail::PROPERTIES], block);

// read fields (meta-data only)
this->readFields(child[detail::FIELDS], block);
this->readFields(child[detail::FIELDS], block, region->get_database());
}
return true;
}
Expand All @@ -970,9 +1021,9 @@ namespace Iocatalyst {
block->get_node_block().property_add(parent);

// read fields (meta-data only)
this->readFields(child[detail::FIELDS], block);
this->readFields(child[detail::FIELDS], block, region->get_database());
this->readFields(child[getName(&block->get_node_block()) + detail::FS + detail::FIELDS],
&block->get_node_block());
&block->get_node_block(), region->get_database());

readZoneConnectivity(child[detail::ZONECONNECTIVITY], block);
readBoundaryConditions(child[detail::BOUNDARYCONDS], block);
Expand Down Expand Up @@ -1039,6 +1090,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 +1105,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 +1179,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 +1251,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 +1264,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 +1499,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 +1530,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 +1612,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 +1643,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
Loading