/* Takes a pointer to the grid and indexes of the full cell. Updates all open adjacent neighbors as being filled and calls itself for the updated neighbors recursively */ void update_neighbors(grid *gd, int i, int j) { if (i > 0 && gd->cells[i - 1][j] == SITE_OPEN) { gd->cells[i - 1][j] = SITE_FULL; update_neighbors(gd, i - 1, j); } if (j > 0 && gd->cells[i][j - 1] == SITE_OPEN) { gd->cells[i][j - 1] = SITE_FULL; update_neighbors(gd, i, j - 1); } if (i + 1 < gd->height && gd->cells[i + 1][j] == SITE_OPEN) { gd->cells[i + 1][j] = SITE_FULL; update_neighbors(gd, i + 1, j); } if (j + 1 < gd->width && gd->cells[i][j + 1] == SITE_OPEN) { gd->cells[i][j + 1] = SITE_FULL; update_neighbors(gd, i, j + 1); } }
/* Fills the structure with the flow recursively (propagates the FULL site state to all open sites that are adjacent to the FULL cells) */ void flow_recursive(grid *gd) { int i, j; for (i = 0; i < gd->height; i++) for (j = 0; j < gd->width; j++) if (gd->cells[i][j] == SITE_FULL) update_neighbors(gd, i, j); }
void mesh::add_triangle(const glm::vec3& a, const glm::vec3& b, const glm::vec3& c) { int index_a = find_index(a); int index_b = find_index(b); int index_c = find_index(c); index_a = update_vertex(a, index_a); index_b = update_vertex(b, index_b); index_c = update_vertex(c, index_c); triangles.push_back(glm::ivec3(index_a, index_b, index_c)); glm::vec3 normal(glm::normalize(glm::cross((b - a), (c - a)))); face_normals.push_back(normal); int tri_index = static_cast<int>(triangles.size()) - 1; update_neighbors(index_a, tri_index); update_neighbors(index_b, tri_index); update_neighbors(index_c, tri_index); }
counter move_one_polyhedron(int id, polyhedron *p, int N, const double periodic[3], const double walls[3], bool real_walls, double neighborR, double dist, double angwidth, int max_neighbors, double dr) { const double len[3] = {periodic[0]+walls[0], periodic[1]+walls[1], periodic[2]+walls[2]}; polyhedron temp = random_move(p[id], dist, angwidth, len); counter move; move.totalmoves ++; if (in_cell(temp, walls, real_walls)) { bool overlaps = overlaps_with_any(temp, p, periodic); if (!overlaps) { const bool get_new_neighbors = (periodic_diff(temp.pos, temp.neighbor_center, periodic).normsquared() > sqr(neighborR/2.0)); if (get_new_neighbors) { // If we've moved too far, then the overlap test may have given a false // negative. So we'll find our new neighbors, and check against them. // If we still don't overlap, then we'll have to update the tables // of our neighbors that have changed. temp.neighbors = new int[max_neighbors]; update_neighbors(temp, id, p, N, neighborR + 2*dr, periodic); move.updates ++; // However, for this check (and this check only), we don't need to // look at all of our neighbors, only our new ones. // fixme: do this! //int *new_neighbors = new int[max_neighbors]; overlaps = overlaps_with_any(temp, p, periodic); if (!overlaps) { // Okay, we've checked twice, just like Santa Clause, so we're definitely // keeping this move and need to tell our neighbors where we are now. temp.neighbor_center = temp.pos; inform_neighbors(temp, p[id], id, p); move.informs ++; delete[] p[id].neighbors; } else delete[] temp.neighbors; } if (!overlaps) { p[id] = temp; move.workingmoves ++; // move sucessful return move; } } } return move; // move unsucessful }
void neighbor_find_update(int lattice[], int array[], int * number_up, int * number_down, double p) { int latticesize = array[10]; int ss = random_at_most((latticesize - 1)); // pick random site within lattice //int global_ss = rsn + (taskid)*(sublatticesize); int ss2 = 0, rn = 0, ln = 0; double p_cA = 0; double p_cB = 0; p_cA = ((double)rand()) / ((double)RAND_MAX); p_cB = ((double)rand()) / ((double)RAND_MAX); global_assignments(ss, &ss2, &ln, &rn,latticesize); // determine what the four sites of interest are. PROBLEM!!!!! array[5] = ln; //ln array[6] = ss; // ss, not ss2 (THIS IS the global version of rsn) array[7] = rn; //rn if (lattice[ss] == lattice[ss2]) { update_neighbors(lattice, array, p_cA, p_cB, p); } }
/** * gts_graph_bisection_bkl_refine: * @bg: a #GtsGraphBisection. * @mmax: the maximum number of unsuccessful successive moves. * @imbalance: the maximum relative imbalance allowed between the * weights of both halves of the partition. * * An implementation of the simplified boundary Kernighan-Lin * algorithm for graph bisection refinement as described in Karypis * and Kumar (1997). * * The algorithm stops if @mmax consecutive modes do not lead to a * decrease in the number of edges cut. This last @mmax moves are * undone. * * Returns: the decrease in the weight of the edges cut by the bisection. */ gdouble gts_graph_bisection_bkl_refine (GtsGraphBisection * bg, guint mmax, gfloat imbalance) { GtsEHeap * h1, * h2; GtsGNode * n; guint nm = 0, i; GtsGNode ** moves; gdouble bestcost = 0., totalcost = 0., best_balance; gboolean balanced = FALSE; g_return_val_if_fail (bg != NULL, 0.); g_return_val_if_fail (mmax > 0, 0.); g_return_val_if_fail (imbalance >= 0. && imbalance <= 1., 0.); h1 = gts_eheap_new ((GtsKeyFunc) node_move_cost1, bg); gts_eheap_freeze (h1); g_hash_table_foreach (bg->bg1, (GHFunc) build_bheap, h1); gts_eheap_thaw (h1); h2 = gts_eheap_new ((GtsKeyFunc) node_move_cost2, bg); gts_eheap_freeze (h2); g_hash_table_foreach (bg->bg2, (GHFunc) build_bheap, h2); gts_eheap_thaw (h2); moves = g_malloc (sizeof (GtsGNode *)*mmax); imbalance *= gts_graph_weight (bg->g); best_balance = fabs (gts_graph_weight (bg->g1) - gts_graph_weight (bg->g2)); if (best_balance <= imbalance) balanced = TRUE; do { GtsGraph * g1, * g2; GHashTable * bg1, * bg2; gdouble cost; if (gts_graph_weight (bg->g1) > gts_graph_weight (bg->g2)) { n = gts_eheap_remove_top (h1, &cost); g1 = bg->g1; g2 = bg->g2; bg1 = bg->bg1; bg2 = bg->bg2; } else { n = gts_eheap_remove_top (h2, &cost); g1 = bg->g2; g2 = bg->g1; bg1 = bg->bg2; bg2 = bg->bg1; } if (n) { gdouble balance; GTS_OBJECT (n)->reserved = n; gts_container_add (GTS_CONTAINER (g2), GTS_CONTAINEE (n)); gts_container_remove (GTS_CONTAINER (g1), GTS_CONTAINEE (n)); g_hash_table_remove (bg1, n); if (gts_gnode_degree (n, g1)) g_hash_table_insert (bg2, n, n); update_neighbors (n, bg, h1, h2); totalcost += cost; balance = fabs (gts_graph_weight (g1) - gts_graph_weight (g2)); if (!balanced && balance <= imbalance) { bestcost = totalcost; best_balance = balance; balanced = TRUE; nm = 0; } else if (totalcost < bestcost && (balance < best_balance || balance <= imbalance)) { bestcost = totalcost; best_balance = balance; nm = 0; } else if (totalcost == bestcost && balance < best_balance) { best_balance = balance; nm = 0; } else moves[nm++] = n; } } while (n && nm < mmax); gts_container_foreach (GTS_CONTAINER (bg->g), (GtsFunc) gts_object_reset_reserved, NULL); gts_eheap_destroy (h1); gts_eheap_destroy (h2); /* undo last nm moves */ for (i = 0; i < nm; i++) { GtsGNode * n = moves[i]; GtsGraph * g1, * g2; GHashTable * bg1, * bg2; if (gts_containee_is_contained (GTS_CONTAINEE (n), GTS_CONTAINER (bg->g1))) { g1 = bg->g1; g2 = bg->g2; bg1 = bg->bg1; bg2 = bg->bg2; } else { g1 = bg->g2; g2 = bg->g1; bg1 = bg->bg2; bg2 = bg->bg1; } gts_container_add (GTS_CONTAINER (g2), GTS_CONTAINEE (n)); gts_container_remove (GTS_CONTAINER (g1), GTS_CONTAINEE (n)); g_hash_table_remove (bg1, n); if (gts_gnode_degree (n, g1)) g_hash_table_insert (bg2, n, n); update_neighbors (n, bg, NULL, NULL); } g_free (moves); return bestcost; }