Skip to content

Commit 3cfada4

Browse files
tkordenbrockcsiefer2
authored andcommitted
Panzer: add a variant of setupExodusFile() with a vector<IossProperty> arg
* this allows the app to configure Ioss behavior * added a unit test that sets the MAXIMUM_NAME_LENGTH property for Exodus Signed-off-by: Todd Kordenbrock <[email protected]> Signed-off-by: Chris Siefert <[email protected]>
1 parent fd56e72 commit 3cfada4

File tree

4 files changed

+209
-0
lines changed

4 files changed

+209
-0
lines changed

packages/panzer/adapters-stk/src/stk_interface/Panzer_STK_Interface.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,22 @@ setupExodusFile(const std::string& filename,
649649
const bool append,
650650
const bool append_after_restart_time,
651651
const double restart_time)
652+
{
653+
std::vector<Ioss::Property> ioss_properties;
654+
setupExodusFile(filename,
655+
ioss_properties,
656+
append,
657+
append_after_restart_time,
658+
restart_time);
659+
}
660+
661+
void
662+
STK_Interface::
663+
setupExodusFile(const std::string& filename,
664+
const std::vector<Ioss::Property>& ioss_properties,
665+
const bool append,
666+
const bool append_after_restart_time,
667+
const double restart_time)
652668
{
653669
using std::runtime_error;
654670
using stk::io::StkMeshIoBroker;
@@ -664,6 +680,9 @@ setupExodusFile(const std::string& filename,
664680
meshData_->set_bulk_data(Teuchos::get_shared_ptr(bulkData_));
665681
Ioss::PropertyManager props;
666682
props.add(Ioss::Property("LOWER_CASE_VARIABLE_NAMES", "FALSE"));
683+
for ( const auto& p : ioss_properties ) {
684+
props.add(p);
685+
}
667686
if (append) {
668687
if (append_after_restart_time) {
669688
meshIndex_ = meshData_->create_output_mesh(filename, stk::io::APPEND_RESULTS,

packages/panzer/adapters-stk/src/stk_interface/Panzer_STK_Interface.hpp

+7
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,13 @@ class STK_Interface {
459459
const bool append_after_restart_time = false,
460460
const double restart_time = 0.0);
461461

462+
void
463+
setupExodusFile(const std::string& filename,
464+
const std::vector<Ioss::Property>& ioss_properties,
465+
const bool append = false,
466+
const bool append_after_restart_time = false,
467+
const double restart_time = 0.0);
468+
462469
/**
463470
* \brief Write this mesh and associated fields at the given `timestep`.
464471
*

packages/panzer/adapters-stk/test/stk_interface_test/CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,13 @@ TRIBITS_ADD_EXECUTABLE_AND_TEST(
7777
COMM serial mpi
7878
)
7979

80+
TRIBITS_ADD_EXECUTABLE_AND_TEST(
81+
tExodusIossProperties
82+
SOURCES tExodusIossProperties.cpp ${UNIT_TEST_DRIVER}
83+
NUM_MPI_PROCS 2
84+
COMM serial mpi
85+
)
86+
8087
TRIBITS_ADD_EXECUTABLE_AND_TEST(
8188
tExodusRestartAndAppend
8289
SOURCES tExodusRestartAndAppend.cpp ${UNIT_TEST_DRIVER}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
// @HEADER
2+
// *****************************************************************************
3+
// Panzer: A partial differential equation assembly
4+
// engine for strongly coupled complex multiphysics systems
5+
//
6+
// Copyright 2011 NTESS and the Panzer contributors.
7+
// SPDX-License-Identifier: BSD-3-Clause
8+
// *****************************************************************************
9+
// @HEADER
10+
11+
#include "Teuchos_ConfigDefs.hpp"
12+
#include "Teuchos_UnitTestHarness.hpp"
13+
14+
#include "Panzer_STK_Version.hpp"
15+
#include "PanzerAdaptersSTK_config.hpp"
16+
#include "Panzer_STK_Interface.hpp"
17+
#include "Panzer_STK_ExodusReaderFactory.hpp"
18+
19+
#include "Shards_BasicTopologies.hpp"
20+
21+
#include <limits> // for epsilon for tolerance in FP comparisons
22+
23+
#ifdef PANZER_HAVE_IOSS
24+
25+
// for checking test correctness
26+
#include "Ioss_DBUsage.h" // for DatabaseUsage::READ_MODEL
27+
#include "Ioss_ElementBlock.h" // for ElementBlock
28+
#include "Ioss_Field.h" // for Field, etc
29+
#include "Ioss_IOFactory.h" // for IOFactory
30+
#include "Ioss_NodeBlock.h" // for NodeBlock
31+
#include "Ioss_Property.h" // for Property
32+
#include "Ioss_Region.h" // for Region, etc
33+
34+
const std::string short_field_name = "short_element_variable_name";
35+
const std::string long_field_name = "long_element_variable_name_XXXXXXXXXXXXX";
36+
const std::string too_long_field_name = "too_long_element_variable_name_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
37+
const std::string block_name_1 = "block_1";
38+
39+
namespace panzer_stk {
40+
41+
void setCellValues(const Teuchos::RCP<panzer_stk::STK_Interface>& mesh,
42+
std::string field_name,
43+
double value)
44+
{
45+
auto cell_vals = mesh->getCellField(field_name,block_name_1);
46+
47+
auto meta_data = mesh->getMetaData();
48+
auto bulk_data = mesh->getBulkData();
49+
50+
auto cell_buckets = bulk_data->get_buckets(stk::topology::ELEM_RANK,meta_data->locally_owned_part());
51+
for (size_t bucket_i=0 ; bucket_i<cell_buckets.size() ; ++bucket_i) {
52+
stk::mesh::Bucket &cell_bucket = *cell_buckets[bucket_i];
53+
for (size_t cell_i=0 ; cell_i<cell_bucket.size() ; ++cell_i) {
54+
double * cell_data = stk::mesh::field_data(*cell_vals,cell_bucket.bucket_id(),cell_i);
55+
*cell_data = value + 0.5;
56+
}
57+
}
58+
}
59+
60+
TEUCHOS_UNIT_TEST(tExodusIossProperties, DefaultNameLength)
61+
{
62+
int numprocs = stk::parallel_machine_size(MPI_COMM_WORLD);
63+
int rank = stk::parallel_machine_rank(MPI_COMM_WORLD);
64+
out << "Running numprocs = " << numprocs << " rank = " << rank << std::endl;
65+
66+
stk::ParallelMachine pm(MPI_COMM_WORLD);
67+
const std::string restart_file = "exodus_ioss_properties_32chars.exo";
68+
const auto tolerance = std::numeric_limits<double>::epsilon() * 100.0;
69+
70+
{
71+
STK_ExodusReaderFactory f("meshes/basic.gen");
72+
auto mesh = f.buildUncommitedMesh(MPI_COMM_WORLD);
73+
74+
mesh->addCellField(short_field_name,block_name_1);
75+
mesh->addCellField(long_field_name,block_name_1);
76+
mesh->addCellField(too_long_field_name,block_name_1);
77+
78+
mesh->initialize(pm,true,false);
79+
80+
f.completeMeshConstruction(*mesh,MPI_COMM_WORLD);
81+
82+
mesh->setupExodusFile(restart_file);
83+
setCellValues(mesh,short_field_name,0.0);
84+
setCellValues(mesh,long_field_name,1.0);
85+
setCellValues(mesh,too_long_field_name,2.0);
86+
mesh->writeToExodus(0.0);
87+
}
88+
// *****************************
89+
// Read the mesh using ioss directly and confirm that the field names
90+
// are no longer than 32 characters long
91+
// *****************************
92+
{
93+
Ioss::DatabaseIO *resultsDb = Ioss::IOFactory::create("exodus", restart_file, Ioss::READ_MODEL, MPI_COMM_WORLD);
94+
Ioss::Region results(resultsDb);
95+
96+
// Number of time steps
97+
TEST_EQUALITY(results.get_property("state_count").get_int(),1);
98+
99+
// First time step value (ioss steps are 1 based)
100+
int step = 1;
101+
double db_time = results.begin_state(step);
102+
TEST_FLOATING_EQUALITY(db_time,0.0,tolerance);
103+
results.end_state(step);
104+
105+
// Cell fields exist
106+
Ioss::ElementBlock *eb = results.get_element_blocks()[0];
107+
TEST_EQUALITY(eb->field_count(Ioss::Field::TRANSIENT), 5);
108+
TEST_ASSERT(true == eb->field_exists(short_field_name));
109+
TEST_ASSERT(false == eb->field_exists(long_field_name));
110+
TEST_ASSERT(false == eb->field_exists(too_long_field_name));
111+
TEST_ASSERT(true == eb->field_exists(long_field_name.substr(0,32)));
112+
TEST_ASSERT(true == eb->field_exists(too_long_field_name.substr(0,32)));
113+
}
114+
}
115+
116+
TEUCHOS_UNIT_TEST(tExodusIossProperties, LongNameLength)
117+
{
118+
int numprocs = stk::parallel_machine_size(MPI_COMM_WORLD);
119+
int rank = stk::parallel_machine_rank(MPI_COMM_WORLD);
120+
out << "Running numprocs = " << numprocs << " rank = " << rank << std::endl;
121+
122+
stk::ParallelMachine pm(MPI_COMM_WORLD);
123+
const std::string restart_file = "exodus_ioss_properties_64chars.exo";
124+
const auto tolerance = std::numeric_limits<double>::epsilon() * 100.0;
125+
126+
{
127+
STK_ExodusReaderFactory f("meshes/basic.gen");
128+
auto mesh = f.buildUncommitedMesh(MPI_COMM_WORLD);
129+
130+
mesh->addCellField(short_field_name,block_name_1);
131+
mesh->addCellField(long_field_name,block_name_1);
132+
mesh->addCellField(too_long_field_name,block_name_1);
133+
134+
mesh->initialize(pm,true,false);
135+
136+
f.completeMeshConstruction(*mesh,MPI_COMM_WORLD);
137+
138+
std::vector<Ioss::Property> ioss_properties;
139+
ioss_properties.push_back(Ioss::Property("MAXIMUM_NAME_LENGTH", 64));
140+
141+
mesh->setupExodusFile(restart_file, ioss_properties);
142+
setCellValues(mesh,short_field_name,0.0);
143+
setCellValues(mesh,long_field_name,1.0);
144+
setCellValues(mesh,too_long_field_name,2.0);
145+
mesh->writeToExodus(0.0);
146+
}
147+
// *****************************
148+
// Read the mesh using ioss directly and confirm that the field names
149+
// are no longer than 64 characters long
150+
// *****************************
151+
{
152+
Ioss::DatabaseIO *resultsDb = Ioss::IOFactory::create("exodus", restart_file, Ioss::READ_MODEL, MPI_COMM_WORLD);
153+
Ioss::Region results(resultsDb);
154+
155+
// Number of time steps
156+
TEST_EQUALITY(results.get_property("state_count").get_int(),1);
157+
158+
// First time step value (ioss steps are 1 based)
159+
int step = 1;
160+
double db_time = results.begin_state(step);
161+
TEST_FLOATING_EQUALITY(db_time,0.0,tolerance);
162+
results.end_state(step);
163+
164+
// Cell fields exist
165+
Ioss::ElementBlock *eb = results.get_element_blocks()[0];
166+
TEST_EQUALITY(eb->field_count(Ioss::Field::TRANSIENT), 5);
167+
TEST_ASSERT(true == eb->field_exists(short_field_name));
168+
TEST_ASSERT(true == eb->field_exists(long_field_name));
169+
TEST_ASSERT(false == eb->field_exists(too_long_field_name));
170+
TEST_ASSERT(true == eb->field_exists(too_long_field_name.substr(0,64)));
171+
}
172+
}
173+
174+
} // namespace panzer_stk
175+
176+
#endif

0 commit comments

Comments
 (0)