int IEdgeAdapter::markUnrefine(const stk::mesh::Entity& element) { const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); VectorFieldType* coordField = m_eMesh.get_coordinates_field(); unsigned numSubDimNeededEntities = 0; numSubDimNeededEntities = cell_topo_data->edge_count; bool unrefAllEdges = true; for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { stk::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); double * const coord0 = stk::mesh::field_data( *coordField , node0 ); double * const coord1 = stk::mesh::field_data( *coordField , node1 ); int markInfo = mark(element, iSubDimOrd, node0, node1, coord0, coord1, 0); bool do_unref = markInfo & DO_UNREFINE; if (!do_unref) { unrefAllEdges = false; break; } } if (unrefAllEdges) return -1; else return 0; }
NodeIdsOnSubDimEntityType* NodeRegistry::getNewNodesOnSubDimEntity(const stk_classic::mesh::Entity& element, stk_classic::mesh::EntityRank& needed_entity_rank, unsigned iSubDimOrd) { EXCEPTWATCH; static SubDimCell_SDSEntityType subDimEntity; getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); static SubDimCellData empty_SubDimCellData; SubDimCellData* nodeId_elementOwnderId_ptr = getFromMapPtr(subDimEntity); SubDimCellData& nodeId_elementOwnderId = (nodeId_elementOwnderId_ptr ? *nodeId_elementOwnderId_ptr : empty_SubDimCellData); bool is_empty = nodeId_elementOwnderId_ptr == 0; if (is_empty) { if (0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); std::cout << "NodeRegistry::getNewNodesOnSubDimEntity: no node found, cell_topo = " << cell_topo.getName() << "\n subDimEntity= " << subDimEntity << "\n element= " << element << "\n element.entity_rank() = " << element.entity_rank() << "\n needed_entity_rank= " << needed_entity_rank << "\n iSubDimOrd= " << iSubDimOrd << std::endl; throw std::runtime_error("NodeRegistry::getNewNodesOnSubDimEntity: no node found"); } return 0; } NodeIdsOnSubDimEntityType& nodeId = nodeId_elementOwnderId.get<SDC_DATA_GLOBAL_NODE_IDS>(); return &nodeId; }
void TestLocalRefiner:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk_classic::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk_classic::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } // iSubDimOrd } // ineed_ent }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk_classic::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk_classic::mesh::Entity *>::iterator& element_pool, stk_classic::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk_classic::mesh::EntityId, stk_classic::mesh::EntityId, stk_classic::mesh::EntityId> tri_tuple_type; static vector<tri_tuple_type> elems(6); CellTopology cell_topo(cell_topo_data); const stk_classic::mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //stk_classic::mesh::Part & active = mesh->ActivePart(); //stk_classic::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk_classic::mesh::Part*> add_parts; std::vector<stk_classic::mesh::Part*> remove_parts; //add_parts.push_back( &active ); //FIXME //add_parts.push_back( const_cast<mesh::Part*>( eMesh.getPart(m_toTopoPartName) )); add_parts = m_toParts; /** \node[above] at (p4.side 1){2}; \node[left] at (p4.side 2){3}; \node[below] at (p4.side 3){0}; \node[right] at (p4.side 4){1}; */ double tmp_x[3]; for (int iedge = 0; iedge < 4; iedge++) { double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), tmp_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 << " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } elems[0] = tri_tuple_type(VERT_N(0), EDGE_N(0), EDGE_N(3)); elems[1] = tri_tuple_type(VERT_N(1), EDGE_N(1), EDGE_N(0)); elems[2] = tri_tuple_type(EDGE_N(0), EDGE_N(1), EDGE_N(3)); elems[3] = tri_tuple_type(VERT_N(2), EDGE_N(2), EDGE_N(1)); elems[4] = tri_tuple_type(VERT_N(3), EDGE_N(3), EDGE_N(2)); elems[5] = tri_tuple_type(EDGE_N(2), EDGE_N(3), EDGE_N(1)); // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { //stk_classic::mesh::Entity& newElement = eMesh.get_bulk_data()->declare_entity(Element, *element_id_pool, eMesh.getPart(interface_table::shards_Triangle_3) ); //stk_classic::mesh::Entity& newElement = eMesh.get_bulk_data()->declare_entity(Element, *element_id_pool, eMesh.getPart(interface_table::shards_Triangle_3) ); stk_classic::mesh::Entity& newElement = *(*element_pool); if (proc_rank_field) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } //eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); change_entity_parts(eMesh, element, newElement); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
virtual std::string getToTopoPartName() { shards::CellTopology cell_topo(getToTopology()); return cell_topo.getName(); }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk::mesh::Entity *>::iterator& element_pool, stk::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk::mesh::EntityId, stk::mesh::EntityId> line_tuple_type; static vector<line_tuple_type> elems(2); CellTopology cell_topo(cell_topo_data); const stk::mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); std::vector<stk::mesh::Part*> add_parts; std::vector<stk::mesh::Part*> remove_parts; add_parts = m_toParts; unsigned num_nodes_on_edge = new_sub_entity_nodes[m_eMesh.edge_rank()][0].size(); if (!num_nodes_on_edge) return; double coord_x[3]; for (int iedge = 0; iedge < 1; iedge++) { //double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), coord_x); //double * mp = midPoint(FACE_COORD(iedge,0), FACE_COORD(iedge,1), eMesh.get_spatial_dim(), coord_x); double * mp = midPoint(VERT_COORD(0), VERT_COORD(1), eMesh.get_spatial_dim(), coord_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } // FIXME nodeRegistry.makeCentroidCoords(*const_cast<stk::mesh::Entity *>(&element), m_primaryEntityRank, 0u); nodeRegistry.addToExistingParts(*const_cast<stk::mesh::Entity *>(&element), m_primaryEntityRank, 0u); nodeRegistry.interpolateFields(*const_cast<stk::mesh::Entity *>(&element), m_primaryEntityRank, 0u); Elem::CellTopology elem_celltopo = Elem::getCellTopology< FromTopology >(); const Elem::RefinementTopology* ref_topo_p = Elem::getRefinementTopology(elem_celltopo); const Elem::RefinementTopology& ref_topo = *ref_topo_p; #ifndef NDEBUG unsigned num_child = ref_topo.num_child(); VERIFY_OP(num_child, == , 2, "createNewElements num_child problem"); bool homogeneous_child = ref_topo.homogeneous_child(); VERIFY_OP(homogeneous_child, ==, true, "createNewElements homogeneous_child"); #endif // new_sub_entity_nodes[i][j] //const UInt * const * child_nodes() const { //const UInt * child_node_0 = ref_topo.child_node(0); typedef Elem::StdMeshObjTopologies::RefTopoX RefTopoX; RefTopoX& l2 = Elem::StdMeshObjTopologies::RefinementTopologyExtra< FromTopology > ::refinement_topology; #define CENTROID_N NN(m_primaryEntityRank,0) for (unsigned iChild = 0; iChild < 2; iChild++) { unsigned EN[2]; for (unsigned jNode = 0; jNode < 2; jNode++) { unsigned childNodeIdx = ref_topo.child_node(iChild)[jNode]; #ifndef NDEBUG unsigned childNodeIdxCheck = l2[childNodeIdx].ordinal_of_node; VERIFY_OP(childNodeIdx, ==, childNodeIdxCheck, "childNodeIdxCheck"); #endif unsigned inode=0; if (l2[childNodeIdx].rank_of_subcell == 0) inode = VERT_N(l2[childNodeIdx].ordinal_of_subcell); else if (l2[childNodeIdx].rank_of_subcell == 1) inode = EDGE_N(l2[childNodeIdx].ordinal_of_subcell); // else if (l2[childNodeIdx].rank_of_subcell == 2) // inode = CENTROID_N; EN[jNode] = inode; } elems[iChild] = line_tuple_type(EN[0], EN[1]); } #undef CENTROID_N for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk::mesh::Entity& newElement = *(*element_pool); #if 0 if (proc_rank_field && proc_rank_field->rank() == m_eMesh.edge_rank()) //&& m_eMesh.get_spatial_dim()==1) { double *fdata = stk::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } #endif stk::mesh::FieldBase * proc_rank_field_edge = m_eMesh.get_field("proc_rank_edge"); if (proc_rank_field_edge) { double *fdata = stk::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field_edge) , newElement ); fdata[0] = double(newElement.owner_rank()); //fdata[0] = 1234.56; if (0) std::cout << "P[" << m_eMesh.get_rank() << "] tmp set proc_rank_field_edge to value = " << newElement.owner_rank() << " for side element = " << newElement.identifier() << std::endl; } //eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); change_entity_parts(eMesh, element, newElement); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk_classic::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk_classic::mesh::Entity *>::iterator& element_pool, stk_classic::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk_classic::mesh::EntityId, stk_classic::mesh::EntityId, stk_classic::mesh::EntityId> tri_tuple_type; static vector<tri_tuple_type> elems(4); CellTopology cell_topo(cell_topo_data); const stk_classic::mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //stk_classic::mesh::Part & active = mesh->ActivePart(); //stk_classic::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk_classic::mesh::Part*> add_parts; std::vector<stk_classic::mesh::Part*> remove_parts; add_parts = m_toParts; //std::cout << "P["<< m_eMesh.get_rank() << "] add_parts = " << add_parts << std::endl; stk_classic::mesh::EntityRank my_rank = m_primaryEntityRank; nodeRegistry.makeCentroidCoords(*const_cast<stk_classic::mesh::Entity *>(&element), my_rank, 0u); nodeRegistry.addToExistingParts(*const_cast<stk_classic::mesh::Entity *>(&element), my_rank, 0u); nodeRegistry.interpolateFields(*const_cast<stk_classic::mesh::Entity *>(&element), my_rank, 0u); #define CENTROID_N NN(m_primaryEntityRank, 0) elems[0] = tri_tuple_type(VERT_N(0), VERT_N(1), CENTROID_N); elems[1] = tri_tuple_type(VERT_N(1), VERT_N(2), CENTROID_N); elems[2] = tri_tuple_type(VERT_N(2), VERT_N(3), CENTROID_N); elems[3] = tri_tuple_type(VERT_N(3), VERT_N(0), CENTROID_N); #undef CENTROID_N // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM /** \node[above] at (p4.side 1){2}; \node[left] at (p4.side 2){3}; \node[below] at (p4.side 3){0}; \node[right] at (p4.side 4){1}; */ #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk_classic::mesh::Entity& newElement = *(*element_pool); //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 3 " << proc_rank_field << std::endl; if (proc_rank_field && element.entity_rank() == m_eMesh.element_rank()) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); fdata[0] = double(newElement.owner_rank()); } //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 4 " << std::endl; change_entity_parts(eMesh, element, newElement); //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 5 " << std::endl; { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 6 " << std::endl; eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); //std::cout << "P["<< m_eMesh.get_rank() << "] urp tmp 7 " << std::endl; set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
// test uniform refinement using bulk data and buckets directly (not using the element color vectors) unsigned TestLocalRefiner:: doForAllElements(stk_classic::mesh::EntityRank rank, NodeRegistry::ElementFunctionPrototype function, vector< ColorerSetType >& elementColors, unsigned elementType, vector<NeededEntityType>& needed_entity_ranks, bool only_count, bool doAllElements) //bool only_count=false, bool doAllElements=true) { EXCEPTWATCH; unsigned num_elem = 0; int progress_meter_num_total = 0; if (m_doProgress) { m_doProgress = false; progress_meter_num_total = doForAllElements(rank, function, elementColors, elementType, needed_entity_ranks, true, doAllElements); m_doProgress = true; ProgressMeterData pd(ProgressMeterData::INIT, 0.0, "NodeRegistry passes"); notifyObservers(&pd); } int progress_meter_when_to_post = progress_meter_num_total / m_progress_meter_frequency; if (0 == progress_meter_when_to_post) progress_meter_when_to_post = 1; double d_progress_meter_num_total = progress_meter_num_total; percept::PerceptMesh& eMesh = m_eMesh; #if 0 stk_classic::mesh::fem::FEMMetaData& metaData = *eMesh.get_fem_meta_data(); const std::vector< stk_classic::mesh::Part * > & parts = metaData.get_parts(); unsigned nparts = parts.size(); if (1) std::cout << "Number of parts = " << nparts << std::endl; VectorFieldType* coordField = eMesh.get_coordinates_field(); #endif stk_classic::mesh::BulkData& bulkData = *eMesh.get_bulk_data(); const std::vector<stk_classic::mesh::Bucket*> & buckets = bulkData.buckets( rank ); for ( std::vector<stk_classic::mesh::Bucket*>::const_iterator k = buckets.begin() ; k != buckets.end() ; ++k ) { //if (in_surface_selector(**k)) { stk_classic::mesh::Bucket & bucket = **k ; // in case the cell topology is needed const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(bucket); shards::CellTopology cell_topo(cell_topo_data); if (cell_topo.getKey() != elementType) continue; const unsigned num_elements_in_bucket = bucket.size(); for (unsigned iElement = 0; iElement < num_elements_in_bucket; iElement++) { const stk_classic::mesh::Entity& element = bucket[iElement]; //const stk_classic::mesh::PairIterRelation& elem_nodes = element.relations( stk_classic::mesh::fem::FEMMetaData::NODE_RANK ); //const stk_classic::mesh::Entity& element = * element_p; bool elementIsGhost = m_eMesh.isGhostElement(element); if (!elementIsGhost) ++num_elem; if (!only_count && (doAllElements || elementIsGhost)) { refineMethodApply(function, element, needed_entity_ranks); } if (m_doProgress && (num_elem % progress_meter_when_to_post == 0) ) { double progress_meter_percent = 100.0*((double)num_elem)/d_progress_meter_num_total; ProgressMeterData pd(ProgressMeterData::RUNNING, progress_meter_percent, "NodeRegistry passes"); notifyObservers(&pd); } } } } if (m_doProgress) { ProgressMeterData pd(ProgressMeterData::FINI, 0.0, "NodeRegistry passes"); notifyObservers(&pd); } return num_elem; }
void TestLocalRefinerTri2:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk_classic::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); VectorFieldType* coordField = m_eMesh.get_coordinates_field(); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk_classic::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } // see how many edges are already marked int num_marked=0; if (needed_entity_rank == m_eMesh.edge_rank()) { for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); if (!is_empty) ++num_marked; } } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) if (needed_entity_rank == m_eMesh.edge_rank()) { stk_classic::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk_classic::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); double * const coord0 = stk_classic::mesh::field_data( *coordField , node0 ); double * const coord1 = stk_classic::mesh::field_data( *coordField , node1 ); // only refine diagonals of the split quads if (m_diagonals) { if ( std::abs(coord0[0]-coord1[0]) > 1.e-3 && std::abs(coord0[1]-coord1[1]) > 1.e-3 ) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } else { if ( std::abs(coord0[0]-coord1[0]) < 1.e-3 && std::abs(coord0[1]-coord1[1]) > 1.e-3 ) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } } } // iSubDimOrd } // ineed_ent }
void IEdgeAdapter:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); VectorFieldType* coordField = m_eMesh.get_coordinates_field(); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; throw std::runtime_error("IEdgeAdapter::apply can't use IEdgeAdapter for RefinerPatterns that require face nodes"); } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; throw std::runtime_error("IEdgeAdapter::apply can't use IEdgeAdapter for RefinerPatterns that require volume nodes"); } // see how many edges are already marked int num_marked=0; std::vector<int> edge_marks(numSubDimNeededEntities,0); if (needed_entity_rank == m_eMesh.edge_rank()) { for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); if (!is_empty) { edge_marks[iSubDimOrd] = 1; ++num_marked; } } } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { if (needed_entity_rank == m_eMesh.edge_rank()) { stk::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); double * const coord0 = stk::mesh::field_data( *coordField , node0 ); double * const coord1 = stk::mesh::field_data( *coordField , node1 ); int markInfo = mark(element, iSubDimOrd, node0, node1, coord0, coord1, &edge_marks); bool needNodes = (DO_REFINE & markInfo); { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, needNodes); } } } // iSubDimOrd } // ineed_ent }
void TestLocalRefinerTet_N_3_1:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk_classic::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { //static int n_seq = 400; const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //VectorFieldType* coordField = m_eMesh.get_coordinates_field(); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk_classic::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } // see how many edges are already marked int num_marked=0; if (needed_entity_rank == m_eMesh.edge_rank()) { for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); if (!is_empty) ++num_marked; } } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) if (needed_entity_rank == m_eMesh.edge_rank()) { #if 0 stk_classic::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk_classic::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); double * const coord0 = stk_classic::mesh::field_data( *coordField , node0 ); double * const coord1 = stk_classic::mesh::field_data( *coordField , node1 ); // vertical line position const double vx = 0.21; // horizontal line position const double vy = 1.21; // choose to refine or not if ( ( std::fabs(coord0[0]-coord1[0]) > 1.e-3 && ( (coord0[0] < vx && vx < coord1[0]) || (coord1[0] < vx && vx < coord0[0]) ) ) || ( std::fabs(coord0[1]-coord1[1]) > 1.e-3 && ( (coord0[1] < vy && vy < coord1[1]) || (coord1[1] < vy && vy < coord0[1]) ) ) ) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } #endif // mark only the first element if ( ((1 << iSubDimOrd) & m_edge_mark_bitcode ) && 1 == element.identifier() ) { if (1) { std::cout << "tmp TestLocalRefinerTet_N_3_1 element.identifier() = " << element.identifier() << " edge_mark_bitcode = " << m_edge_mark_bitcode << " iSubDimOrd= " << iSubDimOrd << std::endl; } (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } } // iSubDimOrd } // ineed_ent }
STKUNIT_UNIT_TEST(nodeRegistry, test_parallel_1_0) { EXCEPTWATCH; MPI_Barrier( MPI_COMM_WORLD ); // start_demo_nodeRegistry_test_parallel_1 percept::PerceptMesh eMesh(3u); unsigned p_size = eMesh.get_parallel_size(); unsigned p_rank = eMesh.get_rank(); Util::setRank(eMesh.get_rank()); eMesh.new_mesh(percept::GMeshSpec(std::string("1x1x")+toString(p_size)+std::string("|bbox:0,0,0,1,1,1"))); // prepare for adding some quadratic elements mesh::Part& block_hex_20 = eMesh.get_fem_meta_data()->declare_part("block_hex_20", eMesh.element_rank()); /// set cell topology for the part block_hex_20 mesh::fem::set_cell_topology< shards::Hexahedron<20> >( block_hex_20 ); stk_classic::io::put_io_part_attribute(block_hex_20); eMesh.commit(); eMesh.print_info(); eMesh.save_as("./cube1x1x2_hex-20-orig.e"); mesh::Part* block_hex_8 = const_cast<mesh::Part *>(eMesh.getPart("block_1")); NodeRegistry nodeRegistry(eMesh); nodeRegistry.initialize(); if (p_size <= 2) { // pick an element on the processor boundary unsigned elem_num_local = 1; unsigned elem_num_ghost = 2; if (p_size == 1) elem_num_ghost = 1; stk_classic::mesh::Entity* element_local_p = eMesh.get_bulk_data()->get_entity(eMesh.element_rank(), elem_num_local); stk_classic::mesh::Entity* element_ghost_p = eMesh.get_bulk_data()->get_entity(eMesh.element_rank(), elem_num_ghost); if (p_rank == 1) { element_local_p = eMesh.get_bulk_data()->get_entity(eMesh.element_rank(), elem_num_ghost); element_ghost_p = eMesh.get_bulk_data()->get_entity(eMesh.element_rank(), elem_num_local); } dw() << "P["<<p_rank<<"] elem_num_local = " << elem_num_local << DWENDL; dw() << "P["<<p_rank<<"] elem_num_ghost = " << elem_num_ghost << DWENDL; stk_classic::mesh::Entity& element_local = *element_local_p; stk_classic::mesh::Entity& element_ghost = *element_ghost_p; std::cout << "P["<<p_rank<<"] element_local = " << element_local << std::endl; std::cout << "P["<<p_rank<<"] element_ghost = " << element_ghost << std::endl; // choose edges to be used for new node locations (i.e., this would model a serendipity-like element with only edge Lagrange nodes) stk_classic::mesh::EntityRank stk_mesh_Edge = 1; NeededEntityType needed_entity_rank( stk_mesh_Edge, 1u); std::vector<NeededEntityType> needed_entity_ranks(1, needed_entity_rank); /* * 1st of three steps to create and associate new nodes - register need for new nodes, then check if node is remote, then get * from remote proc if necessary; finally, the local node database is ready to be queried * * The pattern is to begin the step, loop over all elements (including ghosts) and invoke the local operation * The method doForAllSubEntities is a utility for performing the operation on all the sub entities. * If more granularity is desired, the member functions can be invoked directly for a particular sub-entity. */ nodeRegistry.beginRegistration(); nodeRegistry.doForAllSubEntities(&NodeRegistry::registerNeedNewNode, element_local, needed_entity_ranks); nodeRegistry.doForAllSubEntities(&NodeRegistry::registerNeedNewNode, element_ghost, needed_entity_ranks); nodeRegistry.endRegistration(); std::cout << "P["<<p_rank<<"] nodeRegistry size = " << nodeRegistry.total_size() << std::endl; std::cout << "P["<<p_rank<<"] nodeRegistry lsize = " << nodeRegistry.local_size() << std::endl; dw() << "P["<<p_rank<<"] nodeRegistry size = " << nodeRegistry.total_size() << DWENDL; dw() << "P["<<p_rank<<"] nodeRegistry lsize = " << nodeRegistry.local_size() << DWENDL; // could do local create of elements here nodeRegistry.beginLocalMeshMods(); nodeRegistry.endLocalMeshMods(); // check if the newly requested nodes are local or remote nodeRegistry.beginCheckForRemote(); nodeRegistry.doForAllSubEntities(&NodeRegistry::checkForRemote, element_local, needed_entity_ranks); nodeRegistry.doForAllSubEntities(&NodeRegistry::checkForRemote, element_ghost, needed_entity_ranks); nodeRegistry.endCheckForRemote(); // get the new nodes from other procs if they are nonlocal nodeRegistry.beginGetFromRemote(); nodeRegistry.doForAllSubEntities(&NodeRegistry::getFromRemote, element_local, needed_entity_ranks); nodeRegistry.doForAllSubEntities(&NodeRegistry::getFromRemote, element_ghost, needed_entity_ranks); nodeRegistry.endGetFromRemote(); // now we can get the new node's id and entity unsigned iSubDimOrd = 4u; if (p_rank) { iSubDimOrd = 0u; } NodeIdsOnSubDimEntityType& nodeIds_onSE_0 = *( nodeRegistry.getNewNodesOnSubDimEntity(element_local, needed_entity_rank.first, iSubDimOrd)); stk_classic::mesh::Entity* node_0 = eMesh.get_bulk_data()->get_entity(stk_classic::mesh::fem::FEMMetaData::NODE_RANK, nodeIds_onSE_0[0]->identifier()); // should be the same node on each proc std::cout << "P[" << p_rank << "] nodeId_0 = " << nodeIds_onSE_0 << " node_0= " << node_0 << std::endl; // end_demo #if STK_ADAPT_HAVE_YAML_CPP if (p_size == 1) { if (1) { YAML::Emitter out; out << YAML::Anchor("NodeRegistry::map"); out << YAML::BeginMap; out << YAML::Key << YAML::BeginSeq << 1 << 2 << YAML::EndSeq << YAML::Value << YAML::BeginSeq << -1 << -2 << YAML::EndSeq; out << YAML::Key << 1; out << YAML::Value << 2; out << YAML::Key << 3; out << YAML::Value << 4; out << YAML::EndMap; //std::cout << "out=\n" << out.c_str() << "\n=out" << std::endl; std::string expected_result = "&NodeRegistry::map\n?\n - 1\n - 2\n:\n - -1\n - -2\n1: 2\n3: 4"; //std::cout << "out2=\n" << expected_result << std::endl; STKUNIT_EXPECT_TRUE(expected_result == std::string(out.c_str())); } YAML::Emitter yaml; std::cout << "\nnodeRegistry.serialize_write(yaml)" << std::endl; SerializeNodeRegistry::serialize_write(nodeRegistry, yaml, 0); //std::cout << yaml.c_str() << std::endl; if (!yaml.good()) { std::cout << "Emitter error: " << yaml.good() << " " <<yaml.GetLastError() << "\n"; STKUNIT_EXPECT_TRUE(false); } std::ofstream file1("out.yaml"); file1 << yaml.c_str(); file1.close(); std::ifstream file2("out.yaml"); YAML::Parser parser(file2); YAML::Node doc; try { while(parser.GetNextDocument(doc)) { std::cout << "\n read doc.Type() = " << doc.Type() << " doc.Tag()= " << doc.Tag() << " doc.size= " << doc.size() << std::endl; if (doc.Type() == YAML::NodeType::Map) { for(YAML::Iterator it=doc.begin();it!=doc.end();++it) { int key, value; std::cout << "read it.first().Type() = " << it.first().Type() << " it.first().Tag()= " << it.first().Tag() << std::endl; std::cout << "read it.second().Type() = " << it.second().Type() << " it.second().Tag()= " << it.second().Tag() << std::endl; const YAML::Node& keySeq = it.first(); for(YAML::Iterator itk=keySeq.begin();itk!=keySeq.end();++itk) { *itk >> key; std::cout << "read key= " << key << std::endl; } const YAML::Node& valSeq = it.second(); for(YAML::Iterator itv=valSeq.begin();itv!=valSeq.end();++itv) { *itv >> value; std::cout << "read value= " << value << std::endl; } } } } } catch(YAML::ParserException& e) { std::cout << e.what() << "\n"; STKUNIT_EXPECT_TRUE(false); } file2.close(); std::ifstream file3("out.yaml"); NodeRegistry nrNew(eMesh); SerializeNodeRegistry::serialize_read(nrNew, file3); YAML::Emitter yaml3; std::cout << "\nnrNew.serialize_write(yaml3)" << std::endl; SerializeNodeRegistry::serialize_write(nrNew, yaml3, 0); std::cout << yaml3.c_str() << std::endl; //exit(1); } #endif // start_demo_nodeRegistry_test_parallel_1_quadratic_elem // change element to be a serendipity quadratic element eMesh.get_bulk_data()->modification_begin(); //getCellTopologyData< shards::Node >() const CellTopologyData *const cell_topo_data =stk_classic::percept::PerceptMesh::get_cell_topology(block_hex_20); CellTopology cell_topo(cell_topo_data); for (unsigned isd = 0; isd < 12; isd++) { nodeRegistry.makeCentroidCoords(element_local, needed_entity_rank.first, isd); NodeIdsOnSubDimEntityType& nodeIds_onSE_0_loc = *( nodeRegistry.getNewNodesOnSubDimEntity(element_local, needed_entity_rank.first, isd)); stk_classic::mesh::Entity* node = eMesh.get_bulk_data()->get_entity(stk_classic::mesh::fem::FEMMetaData::NODE_RANK, nodeIds_onSE_0_loc[0]->identifier()); unsigned edge_ord = 8u + isd; //unsigned n_edge_ord = cell_topo_data->edge[isd].topology->node_count; //std::cout << "n_edge_ord = " << n_edge_ord << std::endl; edge_ord = cell_topo_data->edge[isd].node[2]; eMesh.get_bulk_data()->declare_relation(element_local, *node, edge_ord); } std::vector<stk_classic::mesh::Part*> add_parts(1, &block_hex_20); std::vector<stk_classic::mesh::Part*> remove_parts(1, block_hex_8); eMesh.get_bulk_data()->change_entity_parts( element_local, add_parts, remove_parts ); eMesh.get_bulk_data()->modification_end(); eMesh.print_info("After quadratic"); eMesh.save_as("./cube1x1x2_hex-20.e"); //exit(1); }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk::mesh::Entity *>::iterator& element_pool, stk::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk::mesh::EntityId, stk::mesh::EntityId, stk::mesh::EntityId, stk::mesh::EntityId> quad_tuple_type; static vector<quad_tuple_type> elems(4); CellTopology cell_topo(cell_topo_data); const stk::mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); //stk::mesh::Part & active = mesh->ActivePart(); //stk::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk::mesh::Part*> add_parts; std::vector<stk::mesh::Part*> remove_parts; //add_parts.push_back( &active ); //FIXME //add_parts.push_back( const_cast<mesh::Part*>( eMesh.getPart(m_toTopoPartName) )); add_parts = m_toParts; double tmp_x[3]; for (int iedge = 0; iedge < 4; iedge++) { double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), tmp_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 << " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } nodeRegistry.makeCentroidCoords(*const_cast<stk::mesh::Entity *>(&element), m_eMesh.element_rank(), 0u); // new_sub_entity_nodes[i][j] #define CENTROID_N NN(m_primaryEntityRank,0) elems[0] = quad_tuple_type(VERT_N(0), EDGE_N(0), CENTROID_N, EDGE_N(3)); elems[1] = quad_tuple_type(VERT_N(1), EDGE_N(1), CENTROID_N, EDGE_N(0)); elems[2] = quad_tuple_type(VERT_N(2), EDGE_N(2), CENTROID_N, EDGE_N(1)); elems[3] = quad_tuple_type(VERT_N(3), EDGE_N(3), CENTROID_N, EDGE_N(2)); #undef CENTROID_N // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk::mesh::Entity& newElement = *(*element_pool); if (proc_rank_field) { double *fdata = stk::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<3>()), 3); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void TestLocalRefinerTri_N_1:: refineMethodApply(NodeRegistry::ElementFunctionPrototype function, const stk::mesh::Entity& element, vector<NeededEntityType>& needed_entity_ranks) { //static int n_seq = 400; static std::vector<unsigned> random_sequence = get_random_sequence(1, 50, 50); const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); CellTopology cell_topo(cell_topo_data); const mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); //VectorFieldType* coordField = m_eMesh.get_coordinates_field(); for (unsigned ineed_ent=0; ineed_ent < needed_entity_ranks.size(); ineed_ent++) { unsigned numSubDimNeededEntities = 0; stk::mesh::EntityRank needed_entity_rank = needed_entity_ranks[ineed_ent].first; if (needed_entity_rank == m_eMesh.edge_rank()) { numSubDimNeededEntities = cell_topo_data->edge_count; } else if (needed_entity_rank == m_eMesh.face_rank()) { numSubDimNeededEntities = cell_topo_data->side_count; } else if (needed_entity_rank == m_eMesh.element_rank()) { numSubDimNeededEntities = 1; } // see how many edges are already marked int num_marked=0; if (needed_entity_rank == m_eMesh.edge_rank()) { for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); if (!is_empty) ++num_marked; } } for (unsigned iSubDimOrd = 0; iSubDimOrd < numSubDimNeededEntities; iSubDimOrd++) { /// note: at this level of granularity we can do single edge refinement, hanging nodes, etc. //SubDimCell_SDSEntityType subDimEntity; //getSubDimEntity(subDimEntity, element, needed_entity_rank, iSubDimOrd); //bool is_empty = m_nodeRegistry->is_empty( element, needed_entity_rank, iSubDimOrd); //if(1||!is_empty) if (needed_entity_rank == m_eMesh.edge_rank()) { stk::mesh::Entity & node0 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[0]].entity(); stk::mesh::Entity & node1 = *elem_nodes[cell_topo_data->edge[iSubDimOrd].node[1]].entity(); //double * const coord0 = stk::mesh::field_data( *coordField , node0 ); //double * const coord1 = stk::mesh::field_data( *coordField , node1 ); // choose to refine or not if (random_sequence[ node0.identifier() + node1.identifier() ] < node0.identifier() + node1.identifier()) { (m_nodeRegistry ->* function)(element, needed_entity_ranks[ineed_ent], iSubDimOrd, true); } } } // iSubDimOrd } // ineed_ent }