{"action":"created","comment":{"url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/comments/23304964","id":23304964,"diff_hunk":"@@ -257,118 +260,149 @@ def closure_ordering(PETSc.DM plex,\n \n @cython.boundscheck(False)\n @cython.wraparound(False)\n+@cython.cdivision(True)\n def quadrilateral_closure_ordering(PETSc.DM plex,\n-                                   PETSc.Section cell_numbering):\n+                                   PETSc.Section vertex_numbering,\n+                                   PETSc.Section cell_numbering,\n+                                   np.ndarray[np.int32_t, ndim=1, mode=\"c\"] cell_orientations):\n+    \"\"\"Cellwise orders mesh entities according to the given cell orientations.\n+\n+    :arg plex: The DMPlex object encapsulating the mesh topology\n+    :arg vertex_numbering: Section describing the universal vertex numbering\n+    :arg cell_numbering: Section describing the cell numbering\n+    :arg cell_orientations: Specifies the starting vertex for each cell,\n+                            and the order of traversal (CCW or CW).\n+    \"\"\"\n     cdef:\n-        PetscInt c, cStart, cEnd, cell, o\n-        PetscInt v_per_cell = 4\n-        PetscInt e_per_cell = 4\n-        PetscInt nclosure = v_per_cell + e_per_cell + 1\n-        PetscInt *cone = NULL\n-        PetscInt *cone_orient = NULL\n-        PetscInt edge_direction[4]\n-        PetscInt bottom, top, bottom_dir, top_dir\n-        PetscInt *bottom_vertices = NULL\n-        PetscInt *top_vertices = NULL\n+        PetscInt c, cStart, cEnd, cell\n+        PetscInt fStart, fEnd, vStart, vEnd\n+        PetscInt entity_per_cell, ncells\n+        PetscInt nclosure, p, vi, v, fi, i\n+        PetscInt start_v, off\n+        PetscInt *closure = NULL\n+        PetscInt c_vertices[4]\n+        PetscInt c_facets[4]\n+        PetscInt g_vertices[4]\n+        PetscInt vertices[4]\n+        PetscInt facets[4]\n+        int reverse\n         np.ndarray[np.int32_t, ndim=2, mode=\"c\"] cell_closure\n-        np.ndarray[np.int32_t, ndim=2, mode=\"c\"] edge_directions\n \n     cStart, cEnd = plex.getHeightStratum(0)\n-    ncells = cEnd - cStart\n+    fStart, fEnd = plex.getHeightStratum(1)\n+    vStart, vEnd = plex.getDepthStratum(0)\n \n-    cell_closure = np.empty((ncells, nclosure), dtype=np.int32)\n-    edge_directions = np.empty((ncells, e_per_cell), dtype=np.int32)\n+    ncells = cEnd - cStart\n+    entity_per_cell = 4 + 4 + 1\n \n+    cell_closure = np.empty((ncells, entity_per_cell), dtype=np.int32)\n     for c in range(cStart, cEnd):\n         CHKERR(PetscSectionGetOffset(cell_numbering.sec, c, &cell))\n-        cell_closure[cell, v_per_cell + e_per_cell] = c\n-\n-        CHKERR(DMPlexGetCone(plex.dm, c, &cone))\n-        CHKERR(DMPlexGetConeOrientation(plex.dm, c, &cone_orient))\n-\n-        # We use two values only for edge orientation:\n-        #  0: nodes are located on the edge in straight order\n-        #  1: nodes are located on the edge in reverse order\n-        for i in range(0, 4):\n-            o = cone_orient[i]\n-            edge_direction[i] = -(o+1) if o < 0 else o\n+        CHKERR(DMPlexGetTransitiveClosure(plex.dm, c, PETSC_TRUE, &nclosure, &closure))\n \n-        # DMPlex returns the edges in an order like this:\n+        # First extract the facets (edges) and the vertices\n+        # from the transitive closure into c_facets and c_vertices.\n+        # Here we assume that DMPlex gives entities in the order:\n         #\n-        #   *--2--*\n+        #   8--3--7\n         #   |     |\n-        #   3     1\n+        #   4  0  2\n         #   |     |\n-        #   *--0--*\n+        #   5--1--6\n         #\n-        # (Any edge can be the first edge, and the second edge\n-        # can be any of its neighbours.)\n+        # where the starting vertex and order of traversal is arbitrary.\n+        # (We fix that later.)\n         #\n-        # The edges are directed like this:\n+        # For the vertices, we also retrieve the global numbers into g_vertices.\n+        vi = 0\n+        fi = 0\n+        for p in range(nclosure):\n+            if vStart <= closure[2*p] < vEnd:\n+                CHKERR(PetscSectionGetOffset(vertex_numbering.sec, closure[2*p], &v))\n+                c_vertices[vi] = closure[2*p]\n+                g_vertices[vi] = cabs(v)\n+                vi += 1\n+            elif fStart <= closure[2*p] < fEnd:\n+                c_facets[fi] = closure[2*p]\n+                fi += 1\n+\n+        # Cell orientation is the global number of the first vertex.\n+        # The second vertex is always the one with the smaller global number.","path":"firedrake/dmplex.pyx","position":114,"original_position":114,"commit_id":"1e658b55da59e150a2e0a19bd79e64926a3e211f","original_commit_id":"1e658b55da59e150a2e0a19bd79e64926a3e211f","user":{"login":"wence-","id":1126981,"avatar_url":"https://avatars.githubusercontent.com/u/1126981?v=3","gravatar_id":"","url":"https://api.github.com/users/wence-","html_url":"https://github.com/wence-","followers_url":"https://api.github.com/users/wence-/followers","following_url":"https://api.github.com/users/wence-/following{/other_user}","gists_url":"https://api.github.com/users/wence-/gists{/gist_id}","starred_url":"https://api.github.com/users/wence-/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wence-/subscriptions","organizations_url":"https://api.github.com/users/wence-/orgs","repos_url":"https://api.github.com/users/wence-/repos","events_url":"https://api.github.com/users/wence-/events{/privacy}","received_events_url":"https://api.github.com/users/wence-/received_events","type":"User","site_admin":false},"body":"Oh, I see, I misread the comment.  Maybe say \"The first vertex is given by the entry in cell_orientations\"?","created_at":"2015-01-21T15:09:47Z","updated_at":"2015-01-21T15:09:47Z","html_url":"https://github.com/firedrakeproject/firedrake/pull/432#discussion_r23304964","pull_request_url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432","_links":{"self":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/comments/23304964"},"html":{"href":"https://github.com/firedrakeproject/firedrake/pull/432#discussion_r23304964"},"pull_request":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432"}}},"pull_request":{"url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432","id":27607820,"html_url":"https://github.com/firedrakeproject/firedrake/pull/432","diff_url":"https://github.com/firedrakeproject/firedrake/pull/432.diff","patch_url":"https://github.com/firedrakeproject/firedrake/pull/432.patch","issue_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues/432","number":432,"state":"open","locked":false,"title":"Consistent edge orientations for quadrilaterals","user":{"login":"miklos1","id":4210841,"avatar_url":"https://avatars.githubusercontent.com/u/4210841?v=3","gravatar_id":"","url":"https://api.github.com/users/miklos1","html_url":"https://github.com/miklos1","followers_url":"https://api.github.com/users/miklos1/followers","following_url":"https://api.github.com/users/miklos1/following{/other_user}","gists_url":"https://api.github.com/users/miklos1/gists{/gist_id}","starred_url":"https://api.github.com/users/miklos1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/miklos1/subscriptions","organizations_url":"https://api.github.com/users/miklos1/orgs","repos_url":"https://api.github.com/users/miklos1/repos","events_url":"https://api.github.com/users/miklos1/events{/privacy}","received_events_url":"https://api.github.com/users/miklos1/received_events","type":"User","site_admin":false},"body":"These changes are supposed to solve the edge orientation problem on quadrilateral meshes once and for all. It includes an MPI-parallel version of edge orientation algorithm in deal.II.\r\n\r\nTest cases are still missing, and thorough testing is still in progress, but I think that the code is stable enough for the review process to start.\r\n\r\nRegarding test cases, it would be probably be nice to merge `cubedsphere` first.","created_at":"2015-01-19T13:49:39Z","updated_at":"2015-01-21T15:09:47Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fbf7e0453c1675e0bf6ccdc60cc29e7160a10c5a","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432/commits","review_comments_url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432/comments","review_comment_url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/comments/{number}","comments_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues/432/comments","statuses_url":"https://api.github.com/repos/firedrakeproject/firedrake/statuses/1e658b55da59e150a2e0a19bd79e64926a3e211f","head":{"label":"firedrakeproject:magic-quadrilaterals","ref":"magic-quadrilaterals","sha":"1e658b55da59e150a2e0a19bd79e64926a3e211f","user":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"repo":{"id":13384052,"name":"firedrake","full_name":"firedrakeproject/firedrake","owner":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/firedrakeproject/firedrake","description":"Firedrake is an automated system for the portable solution of partial differential equations using the finite element method (FEM)","fork":false,"url":"https://api.github.com/repos/firedrakeproject/firedrake","forks_url":"https://api.github.com/repos/firedrakeproject/firedrake/forks","keys_url":"https://api.github.com/repos/firedrakeproject/firedrake/keys{/key_id}","collaborators_url":"https://api.github.com/repos/firedrakeproject/firedrake/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/firedrakeproject/firedrake/teams","hooks_url":"https://api.github.com/repos/firedrakeproject/firedrake/hooks","issue_events_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues/events{/number}","events_url":"https://api.github.com/repos/firedrakeproject/firedrake/events","assignees_url":"https://api.github.com/repos/firedrakeproject/firedrake/assignees{/user}","branches_url":"https://api.github.com/repos/firedrakeproject/firedrake/branches{/branch}","tags_url":"https://api.github.com/repos/firedrakeproject/firedrake/tags","blobs_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/refs{/sha}","trees_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/trees{/sha}","statuses_url":"https://api.github.com/repos/firedrakeproject/firedrake/statuses/{sha}","languages_url":"https://api.github.com/repos/firedrakeproject/firedrake/languages","stargazers_url":"https://api.github.com/repos/firedrakeproject/firedrake/stargazers","contributors_url":"https://api.github.com/repos/firedrakeproject/firedrake/contributors","subscribers_url":"https://api.github.com/repos/firedrakeproject/firedrake/subscribers","subscription_url":"https://api.github.com/repos/firedrakeproject/firedrake/subscription","commits_url":"https://api.github.com/repos/firedrakeproject/firedrake/commits{/sha}","git_commits_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/commits{/sha}","comments_url":"https://api.github.com/repos/firedrakeproject/firedrake/comments{/number}","issue_comment_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues/comments/{number}","contents_url":"https://api.github.com/repos/firedrakeproject/firedrake/contents/{+path}","compare_url":"https://api.github.com/repos/firedrakeproject/firedrake/compare/{base}...{head}","merges_url":"https://api.github.com/repos/firedrakeproject/firedrake/merges","archive_url":"https://api.github.com/repos/firedrakeproject/firedrake/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/firedrakeproject/firedrake/downloads","issues_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues{/number}","pulls_url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls{/number}","milestones_url":"https://api.github.com/repos/firedrakeproject/firedrake/milestones{/number}","notifications_url":"https://api.github.com/repos/firedrakeproject/firedrake/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/firedrakeproject/firedrake/labels{/name}","releases_url":"https://api.github.com/repos/firedrakeproject/firedrake/releases{/id}","created_at":"2013-10-07T13:07:44Z","updated_at":"2015-01-21T12:32:46Z","pushed_at":"2015-01-21T14:58:19Z","git_url":"git://github.com/firedrakeproject/firedrake.git","ssh_url":"git@github.com:firedrakeproject/firedrake.git","clone_url":"https://github.com/firedrakeproject/firedrake.git","svn_url":"https://github.com/firedrakeproject/firedrake","homepage":"http://firedrakeproject.org","size":15241,"stargazers_count":12,"watchers_count":12,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":44,"forks":4,"open_issues":44,"watchers":12,"default_branch":"master"}},"base":{"label":"firedrakeproject:master","ref":"master","sha":"2357ced3d92edda8585151657062a50e336951b9","user":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"repo":{"id":13384052,"name":"firedrake","full_name":"firedrakeproject/firedrake","owner":{"login":"firedrakeproject","id":5558005,"avatar_url":"https://avatars.githubusercontent.com/u/5558005?v=3","gravatar_id":"","url":"https://api.github.com/users/firedrakeproject","html_url":"https://github.com/firedrakeproject","followers_url":"https://api.github.com/users/firedrakeproject/followers","following_url":"https://api.github.com/users/firedrakeproject/following{/other_user}","gists_url":"https://api.github.com/users/firedrakeproject/gists{/gist_id}","starred_url":"https://api.github.com/users/firedrakeproject/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/firedrakeproject/subscriptions","organizations_url":"https://api.github.com/users/firedrakeproject/orgs","repos_url":"https://api.github.com/users/firedrakeproject/repos","events_url":"https://api.github.com/users/firedrakeproject/events{/privacy}","received_events_url":"https://api.github.com/users/firedrakeproject/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/firedrakeproject/firedrake","description":"Firedrake is an automated system for the portable solution of partial differential equations using the finite element method (FEM)","fork":false,"url":"https://api.github.com/repos/firedrakeproject/firedrake","forks_url":"https://api.github.com/repos/firedrakeproject/firedrake/forks","keys_url":"https://api.github.com/repos/firedrakeproject/firedrake/keys{/key_id}","collaborators_url":"https://api.github.com/repos/firedrakeproject/firedrake/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/firedrakeproject/firedrake/teams","hooks_url":"https://api.github.com/repos/firedrakeproject/firedrake/hooks","issue_events_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues/events{/number}","events_url":"https://api.github.com/repos/firedrakeproject/firedrake/events","assignees_url":"https://api.github.com/repos/firedrakeproject/firedrake/assignees{/user}","branches_url":"https://api.github.com/repos/firedrakeproject/firedrake/branches{/branch}","tags_url":"https://api.github.com/repos/firedrakeproject/firedrake/tags","blobs_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/refs{/sha}","trees_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/trees{/sha}","statuses_url":"https://api.github.com/repos/firedrakeproject/firedrake/statuses/{sha}","languages_url":"https://api.github.com/repos/firedrakeproject/firedrake/languages","stargazers_url":"https://api.github.com/repos/firedrakeproject/firedrake/stargazers","contributors_url":"https://api.github.com/repos/firedrakeproject/firedrake/contributors","subscribers_url":"https://api.github.com/repos/firedrakeproject/firedrake/subscribers","subscription_url":"https://api.github.com/repos/firedrakeproject/firedrake/subscription","commits_url":"https://api.github.com/repos/firedrakeproject/firedrake/commits{/sha}","git_commits_url":"https://api.github.com/repos/firedrakeproject/firedrake/git/commits{/sha}","comments_url":"https://api.github.com/repos/firedrakeproject/firedrake/comments{/number}","issue_comment_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues/comments/{number}","contents_url":"https://api.github.com/repos/firedrakeproject/firedrake/contents/{+path}","compare_url":"https://api.github.com/repos/firedrakeproject/firedrake/compare/{base}...{head}","merges_url":"https://api.github.com/repos/firedrakeproject/firedrake/merges","archive_url":"https://api.github.com/repos/firedrakeproject/firedrake/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/firedrakeproject/firedrake/downloads","issues_url":"https://api.github.com/repos/firedrakeproject/firedrake/issues{/number}","pulls_url":"https://api.github.com/repos/firedrakeproject/firedrake/pulls{/number}","milestones_url":"https://api.github.com/repos/firedrakeproject/firedrake/milestones{/number}","notifications_url":"https://api.github.com/repos/firedrakeproject/firedrake/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/firedrakeproject/firedrake/labels{/name}","releases_url":"https://api.github.com/repos/firedrakeproject/firedrake/releases{/id}","created_at":"2013-10-07T13:07:44Z","updated_at":"2015-01-21T12:32:46Z","pushed_at":"2015-01-21T14:58:19Z","git_url":"git://github.com/firedrakeproject/firedrake.git","ssh_url":"git@github.com:firedrakeproject/firedrake.git","clone_url":"https://github.com/firedrakeproject/firedrake.git","svn_url":"https://github.com/firedrakeproject/firedrake","homepage":"http://firedrakeproject.org","size":15241,"stargazers_count":12,"watchers_count":12,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":4,"mirror_url":null,"open_issues_count":44,"forks":4,"open_issues":44,"watchers":12,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432"},"html":{"href":"https://github.com/firedrakeproject/firedrake/pull/432"},"issue":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/issues/432"},"comments":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/issues/432/comments"},"review_comments":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432/comments"},"review_comment":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/pulls/432/commits"},"statuses":{"href":"https://api.github.com/repos/firedrakeproject/firedrake/statuses/1e658b55da59e150a2e0a19bd79e64926a3e211f"}}}}