Skip to content

Commit

Permalink
Panzer: Add edge/face blocks to STK_ExodusReaderFactory (#8779)
Browse files Browse the repository at this point in the history
PANZER: Add missing getEdgeBlockNames() and getFaceBlockNames() to STK_Interface
PANZER: Add Exodus edge/face block support to ExodusReaderFactory
 - Edge/Face Blocks from the input will be registered in the imported mesh
 - Edge/Face Blocks will be created if they don't exist in the input mesh
 - Added ParameterList options to control the import/creation of Edge/Face Blocks
 - Options default to disabled
 - Added test cases
  • Loading branch information
tkordenbrock authored Feb 19, 2021
1 parent af2a851 commit b0046d0
Show file tree
Hide file tree
Showing 9 changed files with 527 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,16 @@ int getMeshDimension(const std::string & meshStr,

STK_ExodusReaderFactory::STK_ExodusReaderFactory()
: fileName_(""), restartIndex_(0), isExodus_(true), userMeshScaling_(false), keepPerceptData_(false),
keepPerceptParentElements_(false), meshScaleFactor_(0.0), levelsOfRefinement_(0)
keepPerceptParentElements_(false), meshScaleFactor_(0.0), levelsOfRefinement_(0),
createEdgeBlocks_(false), createFaceBlocks_(false)
{ }

STK_ExodusReaderFactory::STK_ExodusReaderFactory(const std::string & fileName,
const int restartIndex,
const bool isExodus)
: fileName_(fileName), restartIndex_(restartIndex), isExodus_(isExodus), userMeshScaling_(false),
keepPerceptData_(false), keepPerceptParentElements_(false), meshScaleFactor_(0.0), levelsOfRefinement_(0)
: fileName_(fileName), restartIndex_(restartIndex), isExodus_(isExodus), userMeshScaling_(false),
keepPerceptData_(false), keepPerceptParentElements_(false), meshScaleFactor_(0.0), levelsOfRefinement_(0),
createEdgeBlocks_(false), createFaceBlocks_(false)
{ }

Teuchos::RCP<STK_Interface> STK_ExodusReaderFactory::buildMesh(stk::ParallelMachine parallelMach) const
Expand Down Expand Up @@ -154,6 +156,15 @@ Teuchos::RCP<STK_Interface> STK_ExodusReaderFactory::buildUncommitedMesh(stk::Pa
registerSidesets(*mesh);
registerNodesets(*mesh);

if (createEdgeBlocks_) {
registerEdgeBlocks(*mesh);
}
if (createFaceBlocks_ && mesh->getMetaData()->spatial_dimension() > 2) {
registerFaceBlocks(*mesh);
}

buildMetaData(parallelMach, *mesh);

mesh->addPeriodicBCs(periodicBCVec_);

return mesh;
Expand Down Expand Up @@ -230,6 +241,21 @@ void STK_ExodusReaderFactory::completeMeshConstruction(STK_Interface & mesh,stk:

mesh.buildSubcells();
mesh.buildLocalElementIDs();
if (createEdgeBlocks_) {
mesh.buildLocalEdgeIDs();
}
if (createFaceBlocks_ && mesh.getMetaData()->spatial_dimension() > 2) {
mesh.buildLocalFaceIDs();
}

mesh.beginModification();
if (createEdgeBlocks_) {
addEdgeBlocks(mesh);
}
if (createFaceBlocks_ && mesh.getMetaData()->spatial_dimension() > 2) {
addFaceBlocks(mesh);
}
mesh.endModification();

if (userMeshScaling_) {
stk::mesh::Field<double,stk::mesh::Cartesian>* coord_field =
Expand Down Expand Up @@ -288,6 +314,14 @@ void STK_ExodusReaderFactory::setParameterList(const Teuchos::RCP<Teuchos::Param
if(!paramList->isParameter("Keep Percept Parent Elements"))
paramList->set<bool>("Keep Percept Parent Elements", false);

if(!paramList->isParameter("Create Edge Blocks"))
// default to false to prevent massive exodiff test failures
paramList->set<bool>("Create Edge Blocks", false);

if(!paramList->isParameter("Create Face Blocks"))
// default to false to prevent massive exodiff test failures
paramList->set<bool>("Create Face Blocks", false);

paramList->validateParameters(*getValidParameters(),0);

setMyParamList(paramList);
Expand Down Expand Up @@ -316,6 +350,10 @@ void STK_ExodusReaderFactory::setParameterList(const Teuchos::RCP<Teuchos::Param
keepPerceptParentElements_ = paramList->get<bool>("Keep Percept Parent Elements");

levelsOfRefinement_ = paramList->get<int>("Levels of Uniform Refinement");

createEdgeBlocks_ = paramList->get<bool>("Create Edge Blocks");

createFaceBlocks_ = paramList->get<bool>("Create Face Blocks");
}

//! From ParameterListAcceptor
Expand Down Expand Up @@ -349,6 +387,12 @@ Teuchos::RCP<const Teuchos::ParameterList> STK_ExodusReaderFactory::getValidPara
validParams->set("Keep Percept Data",false,"Keep the Percept mesh after uniform refinement is applied");

validParams->set("Keep Percept Parent Elements",false,"Keep the parent element information in the Percept data");

// default to false to prevent massive exodiff test failures
validParams->set("Create Edge Blocks",false,"Create or copy edge blocks in the mesh");

// default to false to prevent massive exodiff test failures
validParams->set("Create Face Blocks",false,"Create or copy face blocks in the mesh");
}

return validParams.getConst();
Expand Down Expand Up @@ -444,6 +488,125 @@ void STK_ExodusReaderFactory::registerNodesets(STK_Interface & mesh) const
}
}

void STK_ExodusReaderFactory::registerEdgeBlocks(STK_Interface & mesh) const
{
using Teuchos::RCP;

RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
const stk::mesh::PartVector & parts = metaData->get_parts();

stk::mesh::PartVector::const_iterator partItr;
for(partItr=parts.begin();partItr!=parts.end();++partItr) {
const stk::mesh::Part * part = *partItr;
const stk::mesh::PartVector & subsets = part->subsets();
shards::CellTopology cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*part));
const CellTopologyData * ct = cellTopo.getCellTopologyData();

if(part->primary_entity_rank()==mesh.getEdgeRank() && ct==0 && subsets.size()>0) {
TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error,
"STK_ExodusReaderFactory::registerEdgeBlocks error - part \"" << part->name() <<
"\" has more than one subset");

if (stk::io::has_edge_block_part_attribute(*part) && stk::io::get_edge_block_part_attribute(*part)) {
// grab cell topology and name of subset part
const stk::mesh::Part * edge_part = subsets[0];
shards::CellTopology edge_cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*edge_part));
const CellTopologyData * edge_ct = edge_cellTopo.getCellTopologyData();

// only add subset parts that have no topology
if(edge_ct!=0) {
mesh.addEdgeBlock(part->name(),edge_ct);
}
}
}
}
}

void STK_ExodusReaderFactory::registerFaceBlocks(STK_Interface & mesh) const
{
using Teuchos::RCP;

RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();
const stk::mesh::PartVector & parts = metaData->get_parts();

stk::mesh::PartVector::const_iterator partItr;
for(partItr=parts.begin();partItr!=parts.end();++partItr) {
const stk::mesh::Part * part = *partItr;
const stk::mesh::PartVector & subsets = part->subsets();
shards::CellTopology cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*part));
const CellTopologyData * ct = cellTopo.getCellTopologyData();

if(part->primary_entity_rank()==mesh.getFaceRank() && ct==0 && subsets.size()>0) {
TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error,
"STK_ExodusReaderFactory::registerFaceBlocks error - part \"" << part->name() <<
"\" has more than one subset");

if (stk::io::has_face_block_part_attribute(*part) && stk::io::get_face_block_part_attribute(*part)) {
// grab cell topology and name of subset part
const stk::mesh::Part * face_part = subsets[0];
shards::CellTopology face_cellTopo = stk::mesh::get_cell_topology(metaData->get_topology(*face_part));
const CellTopologyData * face_ct = face_cellTopo.getCellTopologyData();

// only add subset parts that have no topology
if(face_ct!=0) {
mesh.addFaceBlock(part->name(),face_ct);
}
}
}
}
}

// Pre-Condition: call beginModification() before entry
// Post-Condition: call endModification() after exit
void STK_ExodusReaderFactory::addEdgeBlocks(STK_Interface & mesh) const
{
stk::mesh::Part * edge_block = mesh.getEdgeBlock(panzer_stk::STK_Interface::edgeBlockString);

Teuchos::RCP<stk::mesh::BulkData> bulkData = mesh.getBulkData();
Teuchos::RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();

std::vector<stk::mesh::Entity> edges;
bulkData->get_entities(mesh.getEdgeRank(),metaData->locally_owned_part(),edges);
mesh.addEntitiesToEdgeBlock(edges, edge_block);
}

// Pre-Condition: call beginModification() before entry
// Post-Condition: call endModification() after exit
void STK_ExodusReaderFactory::addFaceBlocks(STK_Interface & mesh) const
{
stk::mesh::Part * face_block = mesh.getFaceBlock(panzer_stk::STK_Interface::faceBlockString);

Teuchos::RCP<stk::mesh::BulkData> bulkData = mesh.getBulkData();
Teuchos::RCP<stk::mesh::MetaData> metaData = mesh.getMetaData();

std::vector<stk::mesh::Entity> faces;
bulkData->get_entities(mesh.getFaceRank(),metaData->locally_owned_part(),faces);
mesh.addEntitiesToFaceBlock(faces, face_block);
}

void STK_ExodusReaderFactory::buildMetaData(stk::ParallelMachine /* parallelMach */, STK_Interface & mesh) const
{
std::vector<std::string> block_names;
mesh.getElementBlockNames(block_names);

const CellTopologyData *ctd = mesh.getCellTopology(block_names[0])->getCellTopologyData();

if (createEdgeBlocks_) {
auto ep = mesh.getEdgeBlock(panzer_stk::STK_Interface::edgeBlockString);
if (ep == 0) {
const CellTopologyData * edge_ctd = shards::CellTopology(ctd).getBaseCellTopologyData(1,0);
mesh.addEdgeBlock(panzer_stk::STK_Interface::edgeBlockString, edge_ctd);
}
}
if (createFaceBlocks_ && mesh.getMetaData()->spatial_dimension() > 2) {
auto fp = mesh.getFaceBlock(panzer_stk::STK_Interface::faceBlockString);
if (fp == 0) {
const CellTopologyData * face_ctd = shards::CellTopology(ctd).getBaseCellTopologyData(2,0);
mesh.addFaceBlock(panzer_stk::STK_Interface::faceBlockString, face_ctd);
}
}
}

}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ class STK_ExodusReaderFactory : public STK_MeshFactory {
*
* \param[in] parallelMach Descriptor for machine to build this mesh on.
*
* \returns Pointer to <code>STK_Interface</code> object with
* \returns Pointer to <code>STK_Interface</code> object with
* <code>isModifiable()==false</code>.
*/
*/
virtual Teuchos::RCP<STK_Interface> buildMesh(stk::ParallelMachine parallelMach) const;

/** This builds all the meta data of the mesh. Does not call metaData->commit.
Expand Down Expand Up @@ -132,6 +132,13 @@ class STK_ExodusReaderFactory : public STK_MeshFactory {
void registerElementBlocks(STK_Interface & mesh,stk::io::StkMeshIoBroker & meshData) const;
void registerSidesets(STK_Interface & mesh) const;
void registerNodesets(STK_Interface & mesh) const;
void registerEdgeBlocks(STK_Interface & mesh) const;
void registerFaceBlocks(STK_Interface & mesh) const;

void addEdgeBlocks(STK_Interface & mesh) const;
void addFaceBlocks(STK_Interface & mesh) const;

void buildMetaData(stk::ParallelMachine parallelMach, STK_Interface & mesh) const;

std::string fileName_;
int restartIndex_;
Expand All @@ -153,6 +160,12 @@ class STK_ExodusReaderFactory : public STK_MeshFactory {

//! Number of levels of inline uniform mesh refinement to be applied to exodus mesh
int levelsOfRefinement_;

//! Did the user request to create missing edge blocks
bool createEdgeBlocks_;

//! Did the user request to create missing face blocks
bool createFaceBlocks_;
};

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1413,7 +1413,7 @@ void STK_Interface::getSidesetNames(std::vector<std::string> & names) const
names.clear();

// fill vector with automagically ordered string values
std::map<std::string, stk::mesh::Part*>::const_iterator sideItr; // Element blocks
std::map<std::string, stk::mesh::Part*>::const_iterator sideItr; // Side sets
for(sideItr=sidesets_.begin();sideItr!=sidesets_.end();++sideItr)
names.push_back(sideItr->first);
}
Expand All @@ -1423,11 +1423,31 @@ void STK_Interface::getNodesetNames(std::vector<std::string> & names) const
names.clear();

// fill vector with automagically ordered string values
std::map<std::string, stk::mesh::Part*>::const_iterator nodeItr; // Element blocks
std::map<std::string, stk::mesh::Part*>::const_iterator nodeItr; // Node sets
for(nodeItr=nodesets_.begin();nodeItr!=nodesets_.end();++nodeItr)
names.push_back(nodeItr->first);
}

void STK_Interface::getEdgeBlockNames(std::vector<std::string> & names) const
{
names.clear();

// fill vector with automagically ordered string values
std::map<std::string, stk::mesh::Part*>::const_iterator edgeBlockItr; // Edge blocks
for(edgeBlockItr=edgeBlocks_.begin();edgeBlockItr!=edgeBlocks_.end();++edgeBlockItr)
names.push_back(edgeBlockItr->first);
}

void STK_Interface::getFaceBlockNames(std::vector<std::string> & names) const
{
names.clear();

// fill vector with automagically ordered string values
std::map<std::string, stk::mesh::Part*>::const_iterator faceBlockItr; // Face blocks
for(faceBlockItr=faceBlocks_.begin();faceBlockItr!=faceBlocks_.end();++faceBlockItr)
names.push_back(faceBlockItr->first);
}

std::size_t STK_Interface::elementLocalId(stk::mesh::Entity elmt) const
{
return elementLocalId(bulkData_->identifier(elmt));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,10 +640,28 @@ class STK_Interface {
* in lexiographic order (uses the sorting built into the std::map).
* This method can only be called after <code>initialize</code>.
*
* \param[in,out] names Vector of names of the element blocks.
* \param[in,out] names Vector of names of the node sets.
*/
void getNodesetNames(std::vector<std::string> & name) const;

/** Get a vector containing the names of the edge blocks.
* This function always returns the current set of edge blocks
* in lexiographic order (uses the sorting built into the std::map).
* This method can only be called after <code>initialize</code>.
*
* \param[in,out] names Vector of names of the edge blocks.
*/
void getEdgeBlockNames(std::vector<std::string> & names) const;

/** Get a vector containing the names of the face blocks.
* This function always returns the current set of face blocks
* in lexiographic order (uses the sorting built into the std::map).
* This method can only be called after <code>initialize</code>.
*
* \param[in,out] names Vector of names of the face blocks.
*/
void getFaceBlockNames(std::vector<std::string> & names) const;

//! Get a pointer to the locally owned part
stk::mesh::Part * getOwnedPart() const
{ return &getMetaData()->locally_owned_part(); } // I don't like the pointer access here, but it will do for now!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ TRIBITS_ADD_EXECUTABLE(
# This test appears to have fallen into disrepair. #3719

TRIBITS_COPY_FILES_TO_BINARY_DIR(stk_interface_copy
SOURCE_FILES basic.gen basic.gen.2.0 basic.gen.2.1
SOURCE_FILES basic.gen basic.gen.2.0 basic.gen.2.1 basic3d.gen basic3d.gen.2.0 basic3d.gen.2.1
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/meshes"
DEST_DIR "${CMAKE_CURRENT_BINARY_DIR}/meshes"
EXEDEPS tExodusReaderFactory
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit b0046d0

Please sign in to comment.