void STK_ExodusReaderFactory::registerSidesets(STK_Interface & mesh,stk::io::MeshData & meshData) const { using Teuchos::RCP; RCP<stk::mesh::fem::FEMMetaData> 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(); // const CellTopologyData * ct = stk::mesh::fem::get_cell_topology(*part).getCellTopologyData(); const CellTopologyData * ct = metaData->get_cell_topology(*part).getCellTopologyData(); // if a side part ==> this is a sideset: now storage is recursive // on part contains all sub parts with consistent topology if(part->primary_entity_rank()==mesh.getSideRank() && ct==0 && subsets.size()>0) { TEUCHOS_TEST_FOR_EXCEPTION(subsets.size()!=1,std::runtime_error, "STK_ExodusReaderFactory::registerSidesets error - part \"" << part->name() << "\" has more than one subset"); // grab cell topology and name of subset part const stk::mesh::Part * ss_part = subsets[0]; // const CellTopologyData * ss_ct = stk::mesh::fem::get_cell_topology(*ss_part).getCellTopologyData(); const CellTopologyData * ss_ct = metaData->get_cell_topology(*ss_part).getCellTopologyData(); // only add subset parts that have no topology if(ss_ct!=0) mesh.addSideset(part->name(),ss_ct); } } }
void STK_ExodusReaderFactory::completeMeshConstruction(STK_Interface & mesh,stk::ParallelMachine parallelMach) const { PANZER_FUNC_TIME_MONITOR("panzer::STK_ExodusReaderFactory::completeMeshConstruction()"); using Teuchos::RCP; using Teuchos::rcp; if(not mesh.isInitialized()) mesh.initialize(parallelMach); // grab mesh data pointer to build the bulk data stk::mesh::MetaData & metaData = stk::mesh::fem::FEMMetaData::get_meta_data(*mesh.getMetaData()); stk::io::MeshData * meshData = const_cast<stk::io::MeshData *>(metaData.get_attribute<stk::io::MeshData>()); // if const_cast is wrong ... why does it feel so right? // I believe this is safe since we are basically hiding this object under the covers // until the mesh construction can be completed...below I cleanup the object myself. TEUCHOS_ASSERT(metaData.remove_attribute(meshData)); // remove the MeshData attribute RCP<stk::mesh::BulkData> bulkData = mesh.getBulkData(); // build mesh bulk data mesh.beginModification(); stk::io::populate_bulk_data(*bulkData, *meshData); mesh.endModification(); // put in a negative index and (like python) the restart will be from the back // (-1 is the last time step) int restartIndex = restartIndex_; if(restartIndex<0) { std::pair<int,double> lastTimeStep = meshData->m_input_region->get_max_time(); restartIndex = 1+restartIndex+lastTimeStep.first; } // populate mesh fields with specific index stk::io::process_input_request(*meshData,*bulkData,restartIndex); mesh.buildSubcells(); mesh.buildLocalElementIDs(); if(restartIndex>0) // process_input_request is a no-op if restartIndex<=0 ... thus there would be no inital time mesh.setInitialStateTime(meshData->m_input_region->get_state_time(restartIndex)); else mesh.setInitialStateTime(0.0); // no initial time to speak, might as well use 0.0 // clean up mesh data object delete meshData; // calls Stk_MeshFactory::rebalance this->rebalance(mesh); }
void STK_ExodusReaderFactory::registerElementBlocks(STK_Interface & mesh,stk::io::MeshData & meshData) const { using Teuchos::RCP; RCP<stk::mesh::fem::FEMMetaData> femMetaData = mesh.getMetaData(); // here we use the Ioss interface because they don't add // "bonus" element blocks and its easier to determine // "real" element blocks versus STK-only blocks const Ioss::ElementBlockContainer & elem_blocks = meshData.m_input_region->get_element_blocks(); for(Ioss::ElementBlockContainer::const_iterator itr=elem_blocks.begin();itr!=elem_blocks.end();++itr) { Ioss::GroupingEntity * entity = *itr; const std::string & name = entity->name(); const stk::mesh::Part * part = femMetaData->get_part(name); const CellTopologyData * ct = femMetaData->get_cell_topology(*part).getCellTopologyData(); TEUCHOS_ASSERT(ct!=0); mesh.addElementBlock(part->name(),ct); } }
void STK_ExodusReaderFactory::registerNodesets(STK_Interface & mesh,stk::io::MeshData & meshData) const { using Teuchos::RCP; RCP<stk::mesh::fem::FEMMetaData> 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 CellTopologyData * ct = metaData->get_cell_topology(*part).getCellTopologyData(); // if a side part ==> this is a sideset: now storage is recursive // on part contains all sub parts with consistent topology if(part->primary_entity_rank()==mesh.getNodeRank() && ct==0) { // only add subset parts that have no topology if(part->name()!=STK_Interface::nodesString) mesh.addNodeset(part->name()); } } }
void STK_ExodusReaderFactory::completeMeshConstruction(STK_Interface & mesh,stk_classic::ParallelMachine parallelMach) const { PANZER_FUNC_TIME_MONITOR("panzer::STK_ExodusReaderFactory::completeMeshConstruction()"); using Teuchos::RCP; using Teuchos::rcp; if(not mesh.isInitialized()) mesh.initialize(parallelMach); // grab mesh data pointer to build the bulk data stk_classic::mesh::MetaData & metaData = stk_classic::mesh::fem::FEMMetaData::get_meta_data(*mesh.getMetaData()); stk_classic::io::MeshData * meshData = const_cast<stk_classic::io::MeshData *>(metaData.get_attribute<stk_classic::io::MeshData>()); // if const_cast is wrong ... why does it feel so right? // I believe this is safe since we are basically hiding this object under the covers // until the mesh construction can be completed...below I cleanup the object myself. TEUCHOS_ASSERT(metaData.remove_attribute(meshData)); // remove the MeshData attribute RCP<stk_classic::mesh::BulkData> bulkData = mesh.getBulkData(); // build mesh bulk data mesh.beginModification(); stk_classic::io::populate_bulk_data(*bulkData, *meshData); // The following section of code is applicable if mesh scaling is // turned on from the input file. if (userMeshScaling_) { stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian>* coord_field = metaData.get_field<stk_classic::mesh::Field<double, stk_classic::mesh::Cartesian> >("coordinates"); std::vector<stk_classic::mesh::Bucket*> const all_node_buckets = bulkData->buckets(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); stk_classic::mesh::Selector select_all_local = metaData.locally_owned_part() | metaData.globally_shared_part(); std::vector<stk_classic::mesh::Bucket*> my_node_buckets; stk_classic::mesh::get_buckets(select_all_local, all_node_buckets, my_node_buckets); int mesh_dim = mesh.getDimension(); // Scale the mesh for (size_t i=0; i < my_node_buckets.size(); ++i) { stk_classic::mesh::Bucket& b = *(my_node_buckets[i]); stk_classic::mesh::BucketArray<stk_classic::mesh::Field<double,stk_classic::mesh::Cartesian> > coordinate_data(*coord_field, b); for (size_t j=0; j < b.size(); ++j) { int index = j; double inv_msf = 1.0/meshScaleFactor_; for (int k=0; k < mesh_dim; ++k) coordinate_data(k, index) = coordinate_data(k, index) * inv_msf; } } } mesh.endModification(); // put in a negative index and (like python) the restart will be from the back // (-1 is the last time step) int restartIndex = restartIndex_; if(restartIndex<0) { std::pair<int,double> lastTimeStep = meshData->m_input_region->get_max_time(); restartIndex = 1+restartIndex+lastTimeStep.first; } // populate mesh fields with specific index stk_classic::io::process_input_request(*meshData,*bulkData,restartIndex); mesh.buildSubcells(); mesh.buildLocalElementIDs(); if(restartIndex>0) // process_input_request is a no-op if restartIndex<=0 ... thus there would be no inital time mesh.setInitialStateTime(meshData->m_input_region->get_state_time(restartIndex)); else mesh.setInitialStateTime(0.0); // no initial time to speak, might as well use 0.0 // clean up mesh data object delete meshData; // calls Stk_MeshFactory::rebalance this->rebalance(mesh); }
std::pair<Teuchos::RCP<std::vector<std::size_t> >, Teuchos::RCP<std::vector<Teuchos::Tuple<double,3> > > > getLocalSideIdsAndCoords(const STK_Interface & mesh, const std::string & sideName, const std::string type_) { unsigned physicalDim = mesh.getDimension(); Teuchos::RCP<stk::mesh::MetaData> metaData = mesh.getMetaData(); Teuchos::RCP<stk::mesh::BulkData> bulkData = mesh.getBulkData(); // grab nodes owned by requested side ///////////////////////////////////////////// std::stringstream ss; ss << "Can't find part=\"" << sideName << "\"" << std::endl; stk::mesh::Part * side = metaData->get_part(sideName,ss.str().c_str()); stk::mesh::Selector mySides = (*side) & metaData->locally_owned_part(); stk::mesh::EntityRank rank; const STK_Interface::VectorFieldType * field = 0; unsigned int offset = 0; if(type_ == "coord"){ rank = mesh.getNodeRank(); field = & mesh.getCoordinatesField(); } else if(type_ == "edge"){ rank = mesh.getEdgeRank(); field = & mesh.getEdgesField(); offset = mesh.getMaxEntityId(mesh.getNodeRank()); } else if(type_ == "face"){ rank = mesh.getFaceRank(); field = & mesh.getFacesField(); offset = mesh.getMaxEntityId(mesh.getNodeRank())+mesh.getMaxEntityId(mesh.getEdgeRank()); } else { ss << "Can't do BCs of type " << type_ << std::endl; TEUCHOS_TEST_FOR_EXCEPTION(true,std::runtime_error, ss.str()) } std::vector<stk::mesh::Bucket*> const& nodeBuckets = bulkData->get_buckets(rank, mySides); // build id vector //////////////////////////////////////////// std::size_t nodeCount = 0; for(std::size_t b=0;b<nodeBuckets.size();b++) nodeCount += nodeBuckets[b]->size(); Teuchos::RCP<std::vector<std::size_t> > sideIds = Teuchos::rcp(new std::vector<std::size_t>(nodeCount)); Teuchos::RCP<std::vector<Teuchos::Tuple<double,3> > > sideCoords = Teuchos::rcp(new std::vector<Teuchos::Tuple<double,3> >(nodeCount)); // loop over node buckets for(std::size_t b=0,index=0;b<nodeBuckets.size();b++) { stk::mesh::Bucket & bucket = *nodeBuckets[b]; double const* array = stk::mesh::field_data(*field, bucket); for(std::size_t n=0;n<bucket.size();n++,index++) { (*sideIds)[index] = bulkData->identifier(bucket[n]) + offset; Teuchos::Tuple<double,3> & coord = (*sideCoords)[index]; // copy coordinates into multi vector for(std::size_t d=0;d<physicalDim;d++) coord[d] = array[physicalDim*n + d]; } } return std::make_pair(sideIds,sideCoords); }