Albany::IossSTKMeshStruct::IossSTKMeshStruct( const Teuchos::RCP<Teuchos::ParameterList>& params, const Teuchos::RCP<Teuchos::ParameterList>& adaptParams_, const Teuchos::RCP<const Epetra_Comm>& comm) : GenericSTKMeshStruct(params, adaptParams_), out(Teuchos::VerboseObjectBase::getDefaultOStream()), useSerialMesh(false), periodic(params->get("Periodic BC", false)), m_hasRestartSolution(false), m_restartDataTime(-1.0), m_solutionFieldHistoryDepth(0) { params->validateParameters(*getValidDiscretizationParameters(),0); mesh_data = new stk::io::MeshData(); usePamgen = (params->get("Method","Exodus") == "Pamgen"); std::vector<std::string> entity_rank_names; // eMesh needs "FAMILY_TREE" entity if(buildEMesh) entity_rank_names.push_back("FAMILY_TREE"); #ifdef ALBANY_ZOLTAN // rebalance requires Zoltan if (params->get<bool>("Use Serial Mesh", false) && comm->NumProc() > 1){ // We are parallel but reading a single exodus file useSerialMesh = true; readSerialMesh(comm, entity_rank_names); } else #endif if (!usePamgen) { *out << "Albany_IOSS: Loading STKMesh from Exodus file " << params->get<std::string>("Exodus Input File Name") << std::endl; stk::io::create_input_mesh("exodusii", // create_input_mesh("exodusii", params->get<std::string>("Exodus Input File Name"), Albany::getMpiCommFromEpetraComm(*comm), *metaData, *mesh_data, entity_rank_names); } else { *out << "Albany_IOSS: Loading STKMesh from Pamgen file " << params->get<std::string>("Pamgen Input File Name") << std::endl; stk::io::create_input_mesh("pamgen", // create_input_mesh("pamgen", params->get<std::string>("Pamgen Input File Name"), Albany::getMpiCommFromEpetraComm(*comm), *metaData, *mesh_data, entity_rank_names); } typedef Teuchos::Array<std::string> StringArray; const StringArray additionalNodeSets = params->get("Additional Node Sets", StringArray()); for (StringArray::const_iterator it = additionalNodeSets.begin(), it_end = additionalNodeSets.end(); it != it_end; ++it) { stk::mesh::Part &newNodeSet = metaData->declare_part(*it, metaData->node_rank()); if (!stk::io::is_part_io_part(newNodeSet)) { stk::mesh::Field<double> * const distrFactorfield = metaData->get_field<stk::mesh::Field<double> >("distribution_factors"); stk::mesh::put_field(*distrFactorfield, metaData->node_rank(), newNodeSet); stk::io::put_io_part_attribute(newNodeSet); } } numDim = metaData->spatial_dimension(); stk::io::put_io_part_attribute(metaData->universal_part()); // Set element blocks, side sets and node sets const stk::mesh::PartVector & all_parts = metaData->get_parts(); std::vector<std::string> ssNames; std::vector<std::string> nsNames; int numEB = 0; for (stk::mesh::PartVector::const_iterator i = all_parts.begin(); i != all_parts.end(); ++i) { stk::mesh::Part * const part = *i ; if ( part->primary_entity_rank() == metaData->element_rank()) { if (part->name()[0] != '{') { //*out << "IOSS-STK: Element part \"" << part->name() << "\" found " << std::endl; partVec[numEB] = part; numEB++; } } else if ( part->primary_entity_rank() == metaData->node_rank()) { if (part->name()[0] != '{') { //*out << "Mesh has Node Set ID: " << part->name() << std::endl; nsPartVec[part->name()]=part; nsNames.push_back(part->name()); } } else if ( part->primary_entity_rank() == metaData->side_rank()) { if (part->name()[0] != '{') { // print(*out, "Found side_rank entity:\n", *part); ssPartVec[part->name()]=part; } } } cullSubsetParts(ssNames, ssPartVec); // Eliminate sidesets that are subsets of other sidesets #if 0 // for debugging, print out the parts now std::map<std::string, stk::mesh::Part*>::iterator it; for(it = ssPartVec.begin(); it != ssPartVec.end(); ++it){ // loop over the parts in the map // for each part in turn, get the name of parts that are a subset of it print(*out, "Found \n", *it->second); } // end debugging #endif int cub = params->get("Cubature Degree",3); int worksetSizeMax = params->get("Workset Size",50); // Get number of elements per element block using Ioss for use // in calculating an upper bound on the worksetSize. std::vector<int> el_blocks; stk::io::get_element_block_sizes(*mesh_data, el_blocks); TEUCHOS_TEST_FOR_EXCEPT(el_blocks.size() != partVec.size()); int ebSizeMax = *std::max_element(el_blocks.begin(), el_blocks.end()); int worksetSize = this->computeWorksetSize(worksetSizeMax, ebSizeMax); // Build a map to get the EB name given the index for (int eb=0; eb<numEB; eb++) this->ebNameToIndex[partVec[eb]->name()] = eb; // Construct MeshSpecsStruct if (!params->get("Separate Evaluators by Element Block",false)) { const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData(); this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub, nsNames, ssNames, worksetSize, partVec[0]->name(), this->ebNameToIndex, this->interleavedOrdering)); } else { *out << "MULTIPLE Elem Block in Ioss: DO worksetSize[eb] max?? " << std::endl; this->allElementBlocksHaveSamePhysics=false; this->meshSpecs.resize(numEB); for (int eb=0; eb<numEB; eb++) { const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[eb]).getCellTopologyData(); this->meshSpecs[eb] = Teuchos::rcp(new Albany::MeshSpecsStruct(ctd, numDim, cub, nsNames, ssNames, worksetSize, partVec[eb]->name(), this->ebNameToIndex, this->interleavedOrdering)); std::cout << "el_block_size[" << eb << "] = " << el_blocks[eb] << " name " << partVec[eb]->name() << std::endl; } } { const Ioss::Region *inputRegion = mesh_data->m_input_region; m_solutionFieldHistoryDepth = inputRegion->get_property("state_count").get_int(); } }
Albany::IossSTKMeshStruct::IossSTKMeshStruct( const Teuchos::RCP<Teuchos::ParameterList>& params, const Teuchos::RCP<Teuchos::ParameterList>& adaptParams_, const Teuchos::RCP<const Teuchos_Comm>& commT) : GenericSTKMeshStruct(params, adaptParams_), out(Teuchos::VerboseObjectBase::getDefaultOStream()), useSerialMesh(false), periodic(params->get("Periodic BC", false)), m_hasRestartSolution(false), m_restartDataTime(-1.0), m_solutionFieldHistoryDepth(0) { params->validateParameters(*getValidDiscretizationParameters(),0); usePamgen = (params->get("Method","Exodus") == "Pamgen"); const Teuchos::MpiComm<int>* mpiComm = dynamic_cast<const Teuchos::MpiComm<int>* > (commT.get()); std::vector<std::string> entity_rank_names = stk::mesh::entity_rank_names(); // eMesh needs "FAMILY_TREE" entity if(buildEMesh) { entity_rank_names.push_back("FAMILY_TREE"); } const Teuchos::MpiComm<int>* theComm = dynamic_cast<const Teuchos::MpiComm<int>* > (commT.get()); if (params->get<bool>("Use Serial Mesh", false) && commT->getSize() > 1){ // We are parallel but reading a single exodus file useSerialMesh = true; // Read a single exodus mesh on Proc 0 then rebalance it across the machine MPI_Group group_world; MPI_Group peZero; MPI_Comm peZeroComm; //MPI_Comm theComm = Albany::getMpiCommFromEpetraComm(*comm); int process_rank[1]; // the reader process process_rank[0] = 0; int my_rank = commT->getRank(); //get the group under theComm MPI_Comm_group(*theComm->getRawMpiComm(), &group_world); // create the new group. This group includes only processor zero - that is the only processor that reads the file MPI_Group_incl(group_world, 1, process_rank, &peZero); // create the new communicator - it just contains processor zero MPI_Comm_create(*theComm->getRawMpiComm(), peZero, &peZeroComm); mesh_data = Teuchos::rcp(new stk::io::StkMeshIoBroker(peZeroComm)); } else { mesh_data = Teuchos::rcp(new stk::io::StkMeshIoBroker(*theComm->getRawMpiComm())); } // Create input mesh mesh_data->set_rank_name_vector(entity_rank_names); mesh_data->set_sideset_face_creation_behavior(stk::io::StkMeshIoBroker::STK_IO_SIDESET_FACE_CREATION_CLASSIC); //StkMeshIoBroker::set_sideset_face_creation_behavior(stk::io::StkMeshIoBroker::STK_IO_SIDESET_FACE_CREATION_CLASSIC); std::string mesh_type; std::string file_name; if (!usePamgen) { *out << "Albany_IOSS: Loading STKMesh from Exodus file " << params->get<std::string>("Exodus Input File Name") << std::endl; mesh_type = "exodusII"; file_name = params->get<std::string>("Exodus Input File Name"); } else { *out << "Albany_IOSS: Loading STKMesh from Pamgen file " << params->get<std::string>("Pamgen Input File Name") << std::endl; mesh_type = "pamgen"; file_name = params->get<std::string>("Pamgen Input File Name"); } mesh_data->add_mesh_database(file_name, mesh_type, stk::io::READ_MESH); mesh_data->create_input_mesh(); metaData = mesh_data->meta_data_rcp(); // End of creating input mesh typedef Teuchos::Array<std::string> StringArray; const StringArray additionalNodeSets = params->get("Additional Node Sets", StringArray()); for (StringArray::const_iterator it = additionalNodeSets.begin(), it_end = additionalNodeSets.end(); it != it_end; ++it) { stk::mesh::Part &newNodeSet = metaData->declare_part(*it, stk::topology::NODE_RANK); if (!stk::io::is_part_io_part(newNodeSet)) { stk::mesh::Field<double> * const distrFactorfield = metaData->get_field<stk::mesh::Field<double> >(stk::topology::NODE_RANK, "distribution_factors"); stk::mesh::put_field(*distrFactorfield, newNodeSet); stk::io::put_io_part_attribute(newNodeSet); } } numDim = metaData->spatial_dimension(); stk::io::put_io_part_attribute(metaData->universal_part()); // Set element blocks, side sets and node sets const stk::mesh::PartVector & all_parts = metaData->get_parts(); std::vector<std::string> ssNames; std::vector<std::string> nsNames; int numEB = 0; for (stk::mesh::PartVector::const_iterator i = all_parts.begin(); i != all_parts.end(); ++i) { stk::mesh::Part * const part = *i ; if (!stk::mesh::is_auto_declared_part(*part)) { if ( part->primary_entity_rank() == stk::topology::ELEMENT_RANK) { //*out << "IOSS-STK: Element part \"" << part->name() << "\" found " << std::endl; partVec[numEB] = part; numEB++; } else if ( part->primary_entity_rank() == stk::topology::NODE_RANK) { //*out << "Mesh has Node Set ID: " << part->name() << std::endl; nsPartVec[part->name()]=part; nsNames.push_back(part->name()); } else if ( part->primary_entity_rank() == metaData->side_rank()) { //print(*out, "Found side_rank entity:\n", *part); ssPartVec[part->name()]=part; } } } cullSubsetParts(ssNames, ssPartVec); // Eliminate sidesets that are subsets of other sidesets #if 0 // for debugging, print out the parts now std::map<std::string, stk::mesh::Part*>::iterator it; for(it = ssPartVec.begin(); it != ssPartVec.end(); ++it){ // loop over the parts in the map // for each part in turn, get the name of parts that are a subset of it print(*out, "Found \n", *it->second); } // end debugging #endif const int cub = params->get("Cubature Degree",3); //Get Cubature Rule const std::string cub_rule_string = params->get("Cubature Rule", "GAUSS"); Intrepid2::EIntrepidPLPoly cub_rule; if (cub_rule_string == "GAUSS") cub_rule = static_cast<Intrepid2::EIntrepidPLPoly>(Intrepid2::PL_GAUSS); else if (cub_rule_string == "GAUSS_RADAU_LEFT") cub_rule = static_cast<Intrepid2::EIntrepidPLPoly>(Intrepid2::PL_GAUSS_RADAU_LEFT); else if (cub_rule_string == "GAUSS_RADAU_RIGHT") cub_rule = static_cast<Intrepid2::EIntrepidPLPoly>(Intrepid2::PL_GAUSS_RADAU_RIGHT); else if (cub_rule_string == "GAUSS_LOBATTO") cub_rule = static_cast<Intrepid2::EIntrepidPLPoly>(Intrepid2::PL_GAUSS_LOBATTO); else TEUCHOS_TEST_FOR_EXCEPTION (true, Teuchos::Exceptions::InvalidParameterValue, "Invalid Cubature Rule: " << cub_rule_string << "; valid options are GAUSS, GAUSS_RADAU_LEFT, GAUSS_RADAU_RIGHT, and GAUSS_LOBATTO"); int worksetSizeMax = params->get("Workset Size",50); // Get number of elements per element block using Ioss for use // in calculating an upper bound on the worksetSize. std::vector<int> el_blocks; get_element_block_sizes(*mesh_data, el_blocks); TEUCHOS_TEST_FOR_EXCEPT(el_blocks.size() != partVec.size()); int ebSizeMax = *std::max_element(el_blocks.begin(), el_blocks.end()); int worksetSize = this->computeWorksetSize(worksetSizeMax, ebSizeMax); // Build a map to get the EB name given the index for (int eb=0; eb<numEB; eb++) this->ebNameToIndex[partVec[eb]->name()] = eb; // Construct MeshSpecsStruct if (!params->get("Separate Evaluators by Element Block",false)) { const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[0]).getCellTopologyData(); this->meshSpecs[0] = Teuchos::rcp(new Albany::MeshSpecsStruct( ctd, numDim, cub, nsNames, ssNames, worksetSize, partVec[0]->name(), this->ebNameToIndex, this->interleavedOrdering, false, cub_rule)); } else { *out << "MULTIPLE Elem Block in Ioss: DO worksetSize[eb] max?? " << std::endl; this->allElementBlocksHaveSamePhysics=false; this->meshSpecs.resize(numEB); for (int eb=0; eb<numEB; eb++) { const CellTopologyData& ctd = *metaData->get_cell_topology(*partVec[eb]).getCellTopologyData(); this->meshSpecs[eb] = Teuchos::rcp(new Albany::MeshSpecsStruct( ctd, numDim, cub, nsNames, ssNames, worksetSize, partVec[eb]->name(), this->ebNameToIndex, this->interleavedOrdering, true, cub_rule)); //std::cout << "el_block_size[" << eb << "] = " << el_blocks[eb] << " name " << partVec[eb]->name() << std::endl; } } { const Ioss::Region& inputRegion = *(mesh_data->get_input_io_region()); m_solutionFieldHistoryDepth = inputRegion.get_property("state_count").get_int(); } }