diff --git a/packages/seacas/libraries/ioss/src/catalyst/Iocatalyst_DatabaseIO.C b/packages/seacas/libraries/ioss/src/catalyst/Iocatalyst_DatabaseIO.C index d682ff764e..e4c0b8f35d 100644 --- a/packages/seacas/libraries/ioss/src/catalyst/Iocatalyst_DatabaseIO.C +++ b/packages/seacas/libraries/ioss/src/catalyst/Iocatalyst_DatabaseIO.C @@ -816,8 +816,104 @@ namespace Iocatalyst { return true; } + std::vector getScalarNamesFromNonScalarField(const Ioss::Field &field) const + { + int ncomp = field.get_component_count(Ioss::Field::InOut::INPUT); + std::vector fnames; + for(int i=1; i<=ncomp; i++){ + fnames.push_back(field.get_component_name(i, Ioss::Field::InOut::INPUT)); + } + return fnames; + } + + template + std::vector getInterweavedScalarDataFromConduitNode(const std::vector fnames, conduit_cpp::Node &node) const + { + int ncomp = fnames.size(); + auto &&t_node = node[fnames[0] + detail::FS + detail::VALUE]; + int num_get = t_node.number_of_elements(); + std::vector vals(ncomp*num_get); + + for(int i=0; i(child_value.element_ptr(0))[i]; + } + } + return vals; + } + + template + void addFieldNodeAndDataToConduitNode(const Ioss::Field &field, void *data, conduit_cpp::Node &node) const + { + int ncomp = field.get_component_count(Ioss::Field::InOut::INPUT); + int num_get = field.raw_count(); + node[field.get_name()] = conduit_cpp::Node(); + auto &&f_node = node[field.get_name()]; + f_node[detail::ROLE].set(static_cast(field.get_role())); + f_node[detail::TYPE].set(static_cast(field.get_type())); + f_node[detail::COUNT].set(static_cast(field.raw_count())); + f_node[detail::INDEX].set(static_cast(field.get_index())); + f_node[detail::COMPONENTCOUNT].set(static_cast(ncomp)); + f_node[detail::STORAGE].set(field.raw_storage()->name()); + f_node[detail::VALUE].set(static_cast< T *>(data), ncomp * num_get); + } + + void combineScalarFieldsInConduitNodeToNonScalarField( + const Ioss::Field &field, conduit_cpp::Node &node) const + { + std::vector fnames = + this->getScalarNamesFromNonScalarField(field); + + switch (field.get_type()) { + case Ioss::Field::BasicType::DOUBLE: + this->addFieldNodeAndDataToConduitNode( + field, + this->getInterweavedScalarDataFromConduitNode(fnames, node).data(), + node + ); + break; + + case Ioss::Field::BasicType::INT32: + this->addFieldNodeAndDataToConduitNode( + field, + this->getInterweavedScalarDataFromConduitNode(fnames, node).data(), + node + ); + break; + + case Ioss::Field::BasicType::INT64: + this->addFieldNodeAndDataToConduitNode( + field, + this->getInterweavedScalarDataFromConduitNode(fnames, node).data(), + node + ); + break; + + case Ioss::Field::BasicType::CHARACTER: + this->addFieldNodeAndDataToConduitNode( + field, + this->getInterweavedScalarDataFromConduitNode(fnames, node).data(), + node + ); + break; + default: + std::ostringstream errmsg; + fmt::print(errmsg, "ERROR in {} on read: {}, unsupported field type: {}\n", __func__, + field.get_name(), field.type_string()); + IOSS_ERROR(errmsg); + } + + //Remove Related Scalars from Conduit Node + for(int i=0; i - bool readFields(const conduit_cpp::Node &&parent, GroupingEntityT *block) const + bool readFields(conduit_cpp::Node &&parent, GroupingEntityT *block) const { // Assumption: count = entity_count (in block) Ioss::DatabaseIO *dbase = block->get_database(); @@ -878,6 +974,12 @@ namespace Iocatalyst { for (const auto &field : fields) { block->field_add(field.set_zero_copy_enabled()); } + + for (const auto &field : fields) { + if(field.raw_storage()->name() != IOSS_SCALAR()) { + this->combineScalarFieldsInConduitNodeToNonScalarField(field, parent); + } + } } return true; diff --git a/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_BlockMeshSet.C b/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_BlockMeshSet.C index 10fa7f5721..9a7d870851 100644 --- a/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_BlockMeshSet.C +++ b/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_BlockMeshSet.C @@ -434,6 +434,7 @@ namespace Iocatalyst { values.push_back(itr->second + j*0.1); } elemBlock->put_field_data(itr->first, values); + values.clear(); } } @@ -449,6 +450,7 @@ namespace Iocatalyst { values.push_back(itr->second + j*0.1); } nodeBlock->put_field_data(itr->first, values); + values.clear(); } } diff --git a/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_DatabaseIOTest.h b/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_DatabaseIOTest.h index 62572ed949..ec5c63ac2a 100644 --- a/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_DatabaseIOTest.h +++ b/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_DatabaseIOTest.h @@ -63,6 +63,7 @@ class IOCATALYST_EXPORT Iocatalyst_DatabaseIOTest : public ::testing::Test void *data; size_t dataSize; g->get_field_data(name, &data, &dataSize); + ASSERT_GT(dataSize, 0) << "DataSize is not greater than 0 for field "<(data); std::vector zcBuffer(b, b + field.get_size()); EXPECT_EQ(dcBuffer, zcBuffer); diff --git a/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_ElementBlockTest.C b/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_ElementBlockTest.C index afcbaa9141..9c8fec4c2d 100644 --- a/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_ElementBlockTest.C +++ b/packages/seacas/libraries/ioss/src/catalyst_tests/Iocatalyst_ElementBlockTest.C @@ -4,10 +4,18 @@ // // See packages/seacas/LICENSE for details -#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include -#include TEST_F(Iocatalyst_DatabaseIOTest, WriteThreeElementBlocksWith24Cells) @@ -92,6 +100,8 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_ENABLE_FIELD_RECOGNITION_ON) auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); + checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks()); + bool exo_foo_exists = exo_elemBlock->field_exists("foo"); bool cat_foo_exists = cat_elemBlock->field_exists("foo"); EXPECT_TRUE(exo_foo_exists); @@ -99,6 +109,17 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_ENABLE_FIELD_RECOGNITION_ON) if(exo_foo_exists && cat_foo_exists) EXPECT_TRUE(exo_elemBlock->get_field("foo") == cat_elemBlock->get_field("foo")); + //Check field data for equality + auto cat_field = cat_elemBlock->get_fieldref("foo"); + std::vector dcBuffer(cat_field.get_size()); + cat_elemBlock->get_field_data("foo", Data(dcBuffer), dcBuffer.size()); + + exo_reg.begin_state(1); + auto exo_field = exo_elemBlock->get_fieldref("foo"); + std::vector deBuffer(exo_field.get_size()); + exo_elemBlock->get_field_data("foo", Data(deBuffer), deBuffer.size()); + EXPECT_EQ(dcBuffer, deBuffer); + //Check foo_x doesn't exist bool exo_foo_x_exists = exo_elemBlock->field_exists("foo_x"); bool cat_foo_x_exists = cat_elemBlock->field_exists("foo_x"); @@ -135,6 +156,8 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_ENABLE_FIELD_RECOGNITION_OFF) auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); + checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks()); + bool exo_foo_x_exists = exo_elemBlock->field_exists("foo_x"); bool cat_foo_x_exists = cat_elemBlock->field_exists("foo_x"); EXPECT_TRUE(exo_foo_x_exists); @@ -173,12 +196,15 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_ON) auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); + checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks()); + bool exo_foo_1_exists = exo_elemBlock->field_exists("foo_1"); bool cat_foo_1_exists = cat_elemBlock->field_exists("foo_1"); EXPECT_TRUE(exo_foo_1_exists); EXPECT_TRUE(cat_foo_1_exists); if(exo_foo_1_exists && cat_foo_1_exists) EXPECT_TRUE(exo_elemBlock->get_field("foo_1") == cat_elemBlock->get_field("foo_1")); + } TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_OFF) @@ -186,8 +212,8 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_OFF) Iocatalyst::BlockMesh bm; setBlockMeshSize(2, 2, 2); - bm.addTransientCellField("foo_1", 2); - bm.addTransientCellField("foo_2", 3); + bm.addTransientCellField("foo_1", 3); + bm.addTransientCellField("foo_2", 2); bm.addTransientCellField("foo_3", 4); @@ -209,12 +235,26 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_OFF) auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); + checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks()); + bool exo_foo_exists = exo_elemBlock->field_exists("foo"); bool cat_foo_exists = cat_elemBlock->field_exists("foo"); EXPECT_TRUE(exo_foo_exists); EXPECT_TRUE(cat_foo_exists); if(exo_foo_exists && cat_foo_exists) EXPECT_TRUE(exo_elemBlock->get_field("foo") == cat_elemBlock->get_field("foo")); + + //Check field data for equality + auto cat_field = cat_elemBlock->get_fieldref("foo"); + std::vector dcBuffer(cat_field.get_size()); + cat_elemBlock->get_field_data("foo", Data(dcBuffer), dcBuffer.size()); + + exo_reg.begin_state(1); + auto exo_field = exo_elemBlock->get_fieldref("foo"); + std::vector deBuffer(exo_field.get_size()); + exo_elemBlock->get_field_data("foo", Data(deBuffer), deBuffer.size()); + EXPECT_EQ(dcBuffer, deBuffer); + } TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_SUFFIX_SEPARATOR) @@ -249,6 +289,8 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_SUFFIX_SEPARATOR) auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); + checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks()); + bool exo_foo_x_exists = exo_elemBlock->field_exists("foo_x"); bool cat_foo_x_exists = cat_elemBlock->field_exists("foo_x"); EXPECT_TRUE(exo_foo_x_exists); @@ -262,6 +304,17 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_SUFFIX_SEPARATOR) EXPECT_TRUE(cat_bar_exists); if(exo_bar_exists && cat_bar_exists) EXPECT_TRUE(exo_elemBlock->get_field("bar") == cat_elemBlock->get_field("bar")); + + //Check bar field data for equality + auto cat_field = cat_elemBlock->get_fieldref("bar"); + std::vector dcBuffer(cat_field.get_size()); + cat_elemBlock->get_field_data("bar", Data(dcBuffer), dcBuffer.size()); + + exo_reg.begin_state(1); + auto exo_field = exo_elemBlock->get_fieldref("bar"); + std::vector deBuffer(exo_field.get_size()); + exo_elemBlock->get_field_data("bar", Data(deBuffer), deBuffer.size()); + EXPECT_EQ(dcBuffer, deBuffer); } @@ -294,12 +347,25 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_STRIP_TRAILING_UNDERSCORE) auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID())); + checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks()); + bool exo_foo_exists = exo_elemBlock->field_exists("foo"); bool cat_foo_exists = cat_elemBlock->field_exists("foo"); EXPECT_TRUE(exo_foo_exists); EXPECT_TRUE(cat_foo_exists); if(exo_foo_exists && cat_foo_exists) EXPECT_TRUE(exo_elemBlock->get_field("foo") == cat_elemBlock->get_field("foo")); + + //Check field data for equality + auto cat_field = cat_elemBlock->get_fieldref("foo"); + std::vector dcBuffer(cat_field.get_size()); + cat_elemBlock->get_field_data("foo", Data(dcBuffer), dcBuffer.size()); + + exo_reg.begin_state(1); + auto exo_field = exo_elemBlock->get_fieldref("foo"); + std::vector deBuffer(exo_field.get_size()); + exo_elemBlock->get_field_data("foo", Data(deBuffer), deBuffer.size()); + EXPECT_EQ(dcBuffer, deBuffer); } @@ -325,6 +391,7 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_SURFACE_SPLIT_TYPE) Ioss::Region cat_reg(cat_d); Ioss::SideSetContainer cat_sideSets = cat_reg.get_sidesets(); + checkEntityContainerZeroCopyFields(cat_sideSets); EXPECT_TRUE(cat_sideSets.empty())<<"Cat sidesets not empty when different SURFACE_SPLIT_TYPE";