// ======================================================================== void process_elementblocks(Ioss::Region ®ion, stk::mesh::BulkData &bulk) { const Ioss::ElementBlockContainer& elem_blocks = region.get_element_blocks(); for(Ioss::ElementBlockContainer::const_iterator it = elem_blocks.begin(); it != elem_blocks.end(); ++it) { Ioss::ElementBlock *entity = *it; if (stk::io::include_entity(entity)) { const std::string &name = entity->name(); const stk::mesh::MetaData& meta = stk::mesh::MetaData::get(bulk); stk::mesh::Part* const part = meta.get_part(name); STKIORequire(part != NULL); const stk::topology topo = part->topology(); if (topo == stk::topology::INVALID_TOPOLOGY) { std::ostringstream msg ; msg << " INTERNAL_ERROR: Part " << part->name() << " returned INVALID from get_topology()"; throw std::runtime_error( msg.str() ); } std::vector<int> elem_ids ; std::vector<int> connectivity ; entity->get_field_data("ids", elem_ids); entity->get_field_data("connectivity", connectivity); size_t element_count = elem_ids.size(); int nodes_per_elem = topo.num_nodes(); stk::mesh::EntityIdVector connectivity2(nodes_per_elem); std::vector<int>::const_iterator connBegin = connectivity.begin(); std::vector<stk::mesh::Entity> elements(element_count); for(size_t i=0; i<element_count; ++i, connBegin += nodes_per_elem) { std::copy(connBegin, connBegin + nodes_per_elem, connectivity2.begin()); elements[i] = stk::mesh::declare_element(bulk, *part, elem_ids[i], connectivity2); } // For this example, we are just taking all attribute fields // found on the io database and populating fields on the // corresponding mesh part. In practice, would probably be // selective about which attributes to use... Ioss::NameList names; entity->field_describe(Ioss::Field::ATTRIBUTE, &names); for (Ioss::NameList::const_iterator I = names.begin(); I != names.end(); ++I) { if (*I == "attribute" && names.size() > 1) continue; stk::mesh::FieldBase *field = meta.get_field<stk::mesh::FieldBase>(stk::topology::ELEMENT_RANK, *I); stk::io::field_data_from_ioss(bulk, field, elements, entity, *I); } } } }
ScratchViews::ScratchViews(const TeamHandleType& team, const stk::mesh::BulkData& bulkData, stk::topology topo, ElemDataRequests& dataNeeded) : elemNodes(nullptr), scs_areav(), dndx(), dndx_shifted(), deriv(), det_j(), scv_volume(), gijUpper(), gijLower() { /* master elements are allowed to be null if they are not required */ MasterElement *meSCS = dataNeeded.get_cvfem_surface_me(); MasterElement *meSCV = dataNeeded.get_cvfem_volume_me(); int nDim = bulkData.mesh_meta_data().spatial_dimension(); int nodesPerElem = topo.num_nodes(); int numScsIp = meSCS != nullptr ? meSCS->numIntPoints_ : 0; int numScvIp = meSCV != nullptr ? meSCV->numIntPoints_ : 0; create_needed_field_views(team, dataNeeded, bulkData, nodesPerElem); create_needed_master_element_views(team, dataNeeded, nDim, nodesPerElem, numScsIp, numScvIp); }
Entity declare_element_to_entity(BulkData & mesh, Entity elem, Entity entity, const unsigned relationOrdinal, const PartVector& parts, stk::topology entity_top) { stk::topology elem_top = mesh.bucket(elem).topology(); std::vector<unsigned> entity_node_ordinals(entity_top.num_nodes()); elem_top.sub_topology_node_ordinals(mesh.entity_rank(entity), relationOrdinal, entity_node_ordinals.begin()); const stk::mesh::Entity *elem_nodes = mesh.begin_nodes(elem); EntityVector entity_top_nodes(entity_top.num_nodes()); elem_top.sub_topology_nodes(elem_nodes, mesh.entity_rank(entity), relationOrdinal, entity_top_nodes.begin()); Permutation perm = mesh.find_permutation(elem_top, elem_nodes, entity_top, &entity_top_nodes[0], relationOrdinal); OrdinalVector ordinal_scratch; ordinal_scratch.reserve(64); PartVector part_scratch; part_scratch.reserve(64); if(!parts.empty()) { mesh.change_entity_parts(entity, parts); } const stk::mesh::ConnectivityOrdinal *side_ordinals = mesh.begin_ordinals(elem, mesh.entity_rank(entity)); unsigned num_sides = mesh.count_valid_connectivity(elem, mesh.entity_rank(entity)); bool elem_to_side_exists = false; for(unsigned i = 0; i < num_sides; ++i) { if(side_ordinals[i] == relationOrdinal) { elem_to_side_exists = true; break; } } if(!elem_to_side_exists) { mesh.declare_relation(elem, entity, relationOrdinal, perm, ordinal_scratch, part_scratch); } const unsigned num_side_nodes = mesh.count_valid_connectivity(entity, stk::topology::NODE_RANK); if(0 == num_side_nodes) { Permutation node_perm = stk::mesh::Permutation::INVALID_PERMUTATION; Entity const *elem_nodes_local = mesh.begin_nodes(elem); for(unsigned i = 0; i < entity_top.num_nodes(); ++i) { Entity node = elem_nodes_local[entity_node_ordinals[i]]; mesh.declare_relation(entity, node, i, node_perm, ordinal_scratch, part_scratch); } } else { ThrowAssertMsg(num_side_nodes == entity_top.num_nodes(), "declare_element_to_entity: " << mesh.entity_key(entity) << " already exists with different number of nodes."); } return entity; }
void fill_pre_req_data( ElemDataRequests& dataNeeded, const stk::mesh::BulkData& bulkData, stk::topology topo, stk::mesh::Entity elem, const stk::mesh::FieldBase* coordField, ScratchViews& prereqData) { int nodesPerElem = topo.num_nodes(); MasterElement *meSCS = dataNeeded.get_cvfem_surface_me(); MasterElement *meSCV = dataNeeded.get_cvfem_volume_me(); prereqData.elemNodes = bulkData.begin_nodes(elem); const FieldSet& neededFields = dataNeeded.get_fields(); for(const FieldInfo& fieldInfo : neededFields) { stk::mesh::EntityRank fieldEntityRank = fieldInfo.field->entity_rank(); unsigned scalarsDim1 = fieldInfo.scalarsDim1; bool isTensorField = fieldInfo.scalarsDim2 > 1; if (fieldEntityRank==stk::topology::ELEM_RANK) { if (isTensorField) { SharedMemView<double**>& shmemView = prereqData.get_scratch_view_2D(*fieldInfo.field); gather_elem_tensor_field(*fieldInfo.field, elem, scalarsDim1, fieldInfo.scalarsDim2, shmemView); } else { SharedMemView<double*>& shmemView = prereqData.get_scratch_view_1D(*fieldInfo.field); unsigned len = shmemView.dimension(0); double* fieldDataPtr = static_cast<double*>(stk::mesh::field_data(*fieldInfo.field, elem)); for(unsigned i=0; i<len; ++i) { shmemView(i) = fieldDataPtr[i]; } } } else if (fieldEntityRank == stk::topology::NODE_RANK) { if (isTensorField) { SharedMemView<double***>& shmemView3D = prereqData.get_scratch_view_3D(*fieldInfo.field); gather_elem_node_tensor_field(*fieldInfo.field, nodesPerElem, scalarsDim1, fieldInfo.scalarsDim2, bulkData.begin_nodes(elem), shmemView3D); } else { if (scalarsDim1 == 1) { SharedMemView<double*>& shmemView1D = prereqData.get_scratch_view_1D(*fieldInfo.field); gather_elem_node_field(*fieldInfo.field, nodesPerElem, prereqData.elemNodes, shmemView1D); } else { SharedMemView<double**>& shmemView2D = prereqData.get_scratch_view_2D(*fieldInfo.field); if (scalarsDim1 == 3) { gather_elem_node_field_3D(*fieldInfo.field, nodesPerElem, prereqData.elemNodes, shmemView2D); } else { gather_elem_node_field(*fieldInfo.field, nodesPerElem, scalarsDim1, prereqData.elemNodes, shmemView2D); } } } } else { ThrowRequireMsg(false, "Only node and element fields supported currently."); } } SharedMemView<double**>* coordsView = nullptr; if (coordField != nullptr) { coordsView = &prereqData.get_scratch_view_2D(*coordField); } const std::set<ELEM_DATA_NEEDED>& dataEnums = dataNeeded.get_data_enums(); double error = 0; for(ELEM_DATA_NEEDED data : dataEnums) { switch(data) { case SCS_AREAV: ThrowRequireMsg(meSCS != nullptr, "ERROR, meSCS needs to be non-null if SCS_AREAV is requested."); ThrowRequireMsg(coordsView != nullptr, "ERROR, coords null but SCS_AREAV requested."); meSCS->determinant(1, &((*coordsView)(0,0)), &prereqData.scs_areav(0,0), &error); break; case SCS_GRAD_OP: ThrowRequireMsg(meSCS != nullptr, "ERROR, meSCS needs to be non-null if SCS_GRAD_OP is requested."); ThrowRequireMsg(coordsView != nullptr, "ERROR, coords null but SCS_GRAD_OP requested."); meSCS->grad_op(1, &((*coordsView)(0,0)), &prereqData.dndx(0,0,0), &prereqData.deriv(0), &prereqData.det_j(0), &error); break; case SCS_SHIFTED_GRAD_OP: ThrowRequireMsg(meSCS != nullptr, "ERROR, meSCS needs to be non-null if SCS_GRAD_OP is requested."); ThrowRequireMsg(coordsView != nullptr, "ERROR, coords null but SCS_GRAD_OP requested."); meSCS->shifted_grad_op(1, &((*coordsView)(0,0)), &prereqData.dndx_shifted(0,0,0), &prereqData.deriv(0), &prereqData.det_j(0), &error); break; case SCS_GIJ: ThrowRequireMsg(meSCS != nullptr, "ERROR, meSCS needs to be non-null if SCS_GIJ is requested."); ThrowRequireMsg(coordsView != nullptr, "ERROR, coords null but SCS_GIJ requested."); meSCS->gij(&((*coordsView)(0,0)), &prereqData.gijUpper(0,0,0), &prereqData.gijLower(0,0,0), &prereqData.deriv(0)); break; case SCV_VOLUME: ThrowRequireMsg(meSCV != nullptr, "ERROR, meSCV needs to be non-null if SCV_VOLUME is requested."); ThrowRequireMsg(coordsView != nullptr, "ERROR, coords null but SCV_VOLUME requested."); meSCV->determinant(1, &((*coordsView)(0,0)), &prereqData.scv_volume(0), &error); break; default: break; } } }