PolycrystalICTools::AdjacencyMatrix<Real> PolycrystalICTools::buildNodalGrainAdjacencyMatrix( const std::map<dof_id_type, unsigned int> & node_to_grain, MooseMesh & mesh, const PeriodicBoundaries * /*pb*/, unsigned int n_grains) { // Build node to elem map std::vector<std::vector<const Elem *>> nodes_to_elem_map; MeshTools::build_nodes_to_elem_map(mesh.getMesh(), nodes_to_elem_map); AdjacencyMatrix<Real> adjacency_matrix(n_grains); const auto end = mesh.getMesh().active_nodes_end(); for (auto nl = mesh.getMesh().active_nodes_begin(); nl != end; ++nl) { const Node * node = *nl; std::map<dof_id_type, unsigned int>::const_iterator grain_it = node_to_grain.find(node->id()); mooseAssert(grain_it != node_to_grain.end(), "Node not found in map"); unsigned int my_grain = grain_it->second; std::vector<const Node *> nodal_neighbors; MeshTools::find_nodal_neighbors(mesh.getMesh(), *node, nodes_to_elem_map, nodal_neighbors); // Loop over all nodal neighbors for (unsigned int i = 0; i < nodal_neighbors.size(); ++i) { const Node * neighbor_node = nodal_neighbors[i]; std::map<dof_id_type, unsigned int>::const_iterator grain_it2 = node_to_grain.find(neighbor_node->id()); mooseAssert(grain_it2 != node_to_grain.end(), "Node not found in map"); unsigned int their_grain = grain_it2->second; if (my_grain != their_grain) /** * We've found a grain neighbor interface. In order to assign order parameters though, we * need to make sure that we build out a small buffer region to avoid literal "corner cases" * where nodes on opposite corners of a QUAD end up with the same OP because those nodes are * not nodal neighbors. To do that we'll build a halo region based on these interface nodes. * For now, we need to record the nodes inside of the grain and those outside of the grain. */ adjacency_matrix(my_grain, their_grain) = 1.; } } return adjacency_matrix; }
adjacency_matrix create_adjacency_matrix_relative(Instance &instance, int &max_level) { max_level = 0; vector<Olig> &oligs = instance.oligs; int n = instance.oligs.size(); adjacency_matrix adjacency_matrix(n, vector<int>(n)); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { adjacency_matrix[i][j] = oligs[i].sequence.length() - oligs[i].distance(oligs[j]); if (i==j) adjacency_matrix[i][j] = max_level - 1; if (adjacency_matrix[i][j] > max_level) max_level = adjacency_matrix[i][j]; } } return adjacency_matrix; }
adjacency_matrix create_adjacency_matrix(Instance &instance, int &min_level) { min_level = 16384; //FIXME - it should be a value that exceeds the length of the longest oligonucleotid in library vector<Olig> &oligs = instance.oligs; int n = instance.oligs.size(); adjacency_matrix adjacency_matrix(n, vector<int>(n)); for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { adjacency_matrix[i][j] = oligs[i].distance(oligs[j]); if (i==j) adjacency_matrix[i][j] = min_level + 1; if (adjacency_matrix[i][j] < min_level) min_level = adjacency_matrix[i][j]; } } return adjacency_matrix; }
bool graph<V,E>::isConnected() { if(vertices.size()==0) return true; matrix<int> adjacency = adjacency_matrix(); bool discovered[vertices.size()]; for(int i=0;i<vertices.size();i++) discovered[i]=false; stack<int> DFSstack; DFSstack.push(0); while(DFSstack.size()) { int now = DFSstack.top(); DFSstack.pop(); if(!discovered[now]) { discovered[now] = true; for(int i=0;i<vertices.size();i++) if(adjacency(now,i)==1) DFSstack.push(i); } } for(int i=0;i<vertices.size();i++) if(!discovered[i]) return false; return true; }
PolycrystalICTools::AdjacencyMatrix<Real> PolycrystalICTools::buildElementalGrainAdjacencyMatrix( const std::map<dof_id_type, unsigned int> & element_to_grain, MooseMesh & mesh, const PeriodicBoundaries * pb, unsigned int n_grains) { AdjacencyMatrix<Real> adjacency_matrix(n_grains); // We can't call this in the constructor, it appears that _mesh_ptr is always NULL there. mesh.errorIfDistributedMesh("advanced_op_assignment = true"); std::vector<const Elem *> all_active_neighbors; std::vector<std::set<dof_id_type>> local_ids(n_grains); std::vector<std::set<dof_id_type>> halo_ids(n_grains); std::unique_ptr<PointLocatorBase> point_locator = mesh.getMesh().sub_point_locator(); for (const auto & elem : mesh.getMesh().active_element_ptr_range()) { std::map<dof_id_type, unsigned int>::const_iterator grain_it = element_to_grain.find(elem->id()); mooseAssert(grain_it != element_to_grain.end(), "Element not found in map"); unsigned int my_grain = grain_it->second; all_active_neighbors.clear(); // Loop over all neighbors (at the the same level as the current element) for (unsigned int i = 0; i < elem->n_neighbors(); ++i) { const Elem * neighbor_ancestor = elem->topological_neighbor(i, mesh, *point_locator, pb); if (neighbor_ancestor) // Retrieve only the active neighbors for each side of this element, append them to the list // of active neighbors neighbor_ancestor->active_family_tree_by_topological_neighbor( all_active_neighbors, elem, mesh, *point_locator, pb, false); } // Loop over all active element neighbors for (std::vector<const Elem *>::const_iterator neighbor_it = all_active_neighbors.begin(); neighbor_it != all_active_neighbors.end(); ++neighbor_it) { const Elem * neighbor = *neighbor_it; std::map<dof_id_type, unsigned int>::const_iterator grain_it2 = element_to_grain.find(neighbor->id()); mooseAssert(grain_it2 != element_to_grain.end(), "Element not found in map"); unsigned int their_grain = grain_it2->second; if (my_grain != their_grain) { /** * We've found a grain neighbor interface. In order to assign order parameters though, we * need to make sure that we build out a small buffer region to avoid literal "corner cases" * where nodes on opposite corners of a QUAD end up with the same OP because those nodes are * not nodal neighbors. To do that we'll build a halo region based on these interface nodes. * For now, we need to record the nodes inside of the grain and those outside of the grain. */ // First add corresponding element and grain information local_ids[my_grain].insert(elem->id()); local_ids[their_grain].insert(neighbor->id()); // Now add opposing element and grain information halo_ids[my_grain].insert(neighbor->id()); halo_ids[their_grain].insert(elem->id()); } // adjacency_matrix[my_grain][their_grain] = 1; } } // Build up the halos std::set<dof_id_type> set_difference; for (unsigned int i = 0; i < n_grains; ++i) { std::set<dof_id_type> orig_halo_ids(halo_ids[i]); for (unsigned int halo_level = 0; halo_level < PolycrystalICTools::HALO_THICKNESS; ++halo_level) { for (std::set<dof_id_type>::iterator entity_it = orig_halo_ids.begin(); entity_it != orig_halo_ids.end(); ++entity_it) { if (true) visitElementalNeighbors( mesh.elemPtr(*entity_it), mesh.getMesh(), *point_locator, pb, halo_ids[i]); else mooseError("Unimplemented"); } set_difference.clear(); std::set_difference( halo_ids[i].begin(), halo_ids[i].end(), local_ids[i].begin(), local_ids[i].end(), std::insert_iterator<std::set<dof_id_type>>(set_difference, set_difference.begin())); halo_ids[i].swap(set_difference); } } // Finally look at the halo intersections to build the connectivity graph std::set<dof_id_type> set_intersection; for (unsigned int i = 0; i < n_grains; ++i) for (unsigned int j = i + 1; j < n_grains; ++j) { set_intersection.clear(); std::set_intersection( halo_ids[i].begin(), halo_ids[i].end(), halo_ids[j].begin(), halo_ids[j].end(), std::insert_iterator<std::set<dof_id_type>>(set_intersection, set_intersection.begin())); if (!set_intersection.empty()) { adjacency_matrix(i, j) = 1.; adjacency_matrix(j, i) = 1.; } } return adjacency_matrix; }