/** Manage the received acks * @param ack The received acknowledgment. * @param sender The node which sent ack. */ void handle_ack(message_t* ack, node_t* sender) { // First check if we already received the corresponding message. // If not create an entry in the already_received list and add the ack. // The message will be filled later when received. GList* element_list = get_msg_from_list(delivered, ack); // If already delivered skip it if(!element_list) { element_list = get_msg_from_list(already_received, ack); message_element_t* element_msg; if(!element_list) { // Received an ack for a message we didn't received yet GList* element_list = get_msg_from_list(not_received_yet, ack); if(!element_list) { // Message not received yet and received the first ack for it // Create an empty message to register the ack and register them // for the futur message. message_t* msg = malloc(sizeof(message_t)); msg->node_id = ack->node_id; msg->id = ack->id; msg->content = NULL; insert_message(msg, ¬_received_yet); } else { element_msg = (message_element_t*)element_list->data; add_ack(element_msg, &sender->id); } } else { element_msg = (message_element_t*)element_list->data; add_ack(element_msg, &sender->id); if(is_replicated(element_msg)) { deliver(element_msg); } } } else { } }
std::unique_ptr<MeshBase> SphereSurfaceMeshGenerator::generate() { // Have MOOSE construct the correct libMesh::Mesh object using Mesh block and CLI parameters. auto mesh = _mesh->buildMeshBaseObject(); mesh->set_mesh_dimension(2); mesh->set_spatial_dimension(3); const Sphere sphere(_center, _radius); // icosahedron points (using golden ratio rectangle construction) const Real phi = (1.0 + std::sqrt(5.0)) / 2.0; const Real X = std::sqrt(1.0 / (phi * phi + 1.0)); const Real Z = X * phi; const Point vdata[12] = {{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z}, {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X}, {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}}; for (unsigned int i = 0; i < 12; ++i) mesh->add_point(vdata[i] * _radius + _center, i); // icosahedron faces const unsigned int tindices[20][3] = {{0, 4, 1}, {0, 9, 4}, {9, 5, 4}, {4, 5, 8}, {4, 8, 1}, {8, 10, 1}, {8, 3, 10}, {5, 3, 8}, {5, 2, 3}, {2, 7, 3}, {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6}, {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5}, {7, 2, 11}}; for (unsigned int i = 0; i < 20; ++i) { Elem * elem = mesh->add_elem(new Tri3); elem->set_node(0) = mesh->node_ptr(tindices[i][0]); elem->set_node(1) = mesh->node_ptr(tindices[i][1]); elem->set_node(2) = mesh->node_ptr(tindices[i][2]); } // we need to prepare distributed meshes before using refinement if (!mesh->is_replicated()) mesh->prepare_for_use(/*skip_renumber =*/false); // Now we have the beginnings of a sphere. // Add some more elements by doing uniform refinements and // popping nodes to the boundary. MeshRefinement mesh_refinement(*mesh); // Loop over the elements, refine, pop nodes to boundary. for (unsigned int r = 0; r < _depth; ++r) { mesh_refinement.uniformly_refine(1); auto it = mesh->active_nodes_begin(); const auto end = mesh->active_nodes_end(); for (; it != end; ++it) { Node & node = **it; node = sphere.closest_point(node); } } // Flatten the AMR mesh to get rid of inactive elements MeshTools::Modification::flatten(*mesh); return dynamic_pointer_cast<MeshBase>(mesh); }