From 589969fe854e230c13a1680b3bd444aa27f16071 Mon Sep 17 00:00:00 2001
From: Cory Mikida <cmikida2@illinois.edu>
Date: Mon, 18 May 2020 15:08:14 -0500
Subject: [PATCH] Makes a number of changes to the box tag interface and test

---
 meshmode/mesh/generation.py | 39 ++++++++++++++++++++++++-------------
 test/test_meshmode.py       | 24 +++++++++++------------
 2 files changed, 37 insertions(+), 26 deletions(-)

diff --git a/meshmode/mesh/generation.py b/meshmode/mesh/generation.py
index 3955fbdd..71c8dfd2 100644
--- a/meshmode/mesh/generation.py
+++ b/meshmode/mesh/generation.py
@@ -673,7 +673,7 @@ def generate_urchin(order, m, n, est_rel_interp_tolerance, min_rad=0.2):
 # {{{ generate_box_mesh
 
 def generate_box_mesh(axis_coords, order=1, coord_dtype=np.float64,
-        group_factory=None, face_to_boundary_tag={}):
+        group_factory=None, boundary_tag_to_face={}):
     """Create a semi-structured mesh.
 
     :param axis_coords: a tuple with a number of entries corresponding
@@ -681,12 +681,12 @@ def generate_box_mesh(axis_coords, order=1, coord_dtype=np.float64,
         specifying the coordinates to be used along that axis.
     :param group_factory: One of :class:`meshmode.mesh.SimplexElementGroup`
         or :class:`meshmode.mesh.TensorProductElementGroup`.
-    :param face_to_boundary_tag: an optional dictionary for boundary configuration.
+    :param boundary_tag_to_face: an optional dictionary for boundary configuration.
         The keys correspond to custom boundary tags, with the values giving
         a list of the faces on which they should be applied in terms of coordinate
-        directions (+x, -x, +y, -y, +z, -z). One example of this would be:
+        directions (+x, -x, +y, -y, +z, -z, +w, -w). One example of this would be:
 
-        face_to_boundary_tag={"bdry_1": ["+x", "+y"], "bdry_2": ["-x"]}
+        boundary_tag_to_face={"bdry_1": ["+x", "+y"], "bdry_2": ["-x"]}
 
     .. versionchanged:: 2017.1
 
@@ -798,26 +798,39 @@ def generate_box_mesh(axis_coords, order=1, coord_dtype=np.float64,
     # compute facial adjacency for Mesh if there is tag information
     facial_adjacency_groups = None
     face_vertex_indices_to_tags = {}
-    boundary_tags = list(face_to_boundary_tag.keys())
-    axes = ["x", "y", "z"]
-    face_ids = [1, 0, 0]
+    boundary_tags = list(boundary_tag_to_face.keys())
+    axes = ["x", "y", "z", "w"]
+    face_ids = [1, 0, 0, 0]
     from meshmode.mesh import _compute_facial_adjacency_from_vertices
     if boundary_tags:
         for tag_idx, tag in enumerate(boundary_tags):
             # Need to map the correct face vertices to the boundary tags
-            for face in face_to_boundary_tag[tag]:
+            for face in boundary_tag_to_face[tag]:
+                # Check if face to boundary input is formatted properly
+                if face.startswith("-"):
+                    pass
+                elif face.startswith("+"):
+                    pass
+                else:
+                    raise ValueError("Face ", face, " given for boundary tag ",
+                            tag, " is not formatted properly. Use +x, -x, +y, "
+                            "+z, -z, +w, or -w")
                 for i_ax, axis in enumerate(axes):
                     if face == "-" + axis:
                         if dim < i_ax + 1:
                             raise ValueError("Boundary condition dimension "
-                            "mismatch")
+                            "mismatch: facial dimension ", face, " for tag ",
+                            tag, " is higher than the dimension of the "
+                            "problem")
                         face_id = face_ids[i_ax]
                         dim_crit = i_ax
                         node_crit = axis_coords[i_ax][0]
                     elif face == "+" + axis:
                         if dim < i_ax + 1:
                             raise ValueError("Boundary condition dimension "
-                            "mismatch")
+                            "mismatch: facial dimension ", face, " for tag ",
+                            tag, " is higher than the dimension of the "
+                            "problem")
                         face_id = face_ids[i_ax]
                         dim_crit = i_ax
                         node_crit = axis_coords[i_ax][-1]
@@ -848,14 +861,14 @@ def generate_box_mesh(axis_coords, order=1, coord_dtype=np.float64,
 # {{{ generate_regular_rect_mesh
 
 def generate_regular_rect_mesh(a=(0, 0), b=(1, 1), n=(5, 5), order=1,
-                               face_to_boundary_tag={}):
+                               boundary_tag_to_face={}):
     """Create a semi-structured rectangular mesh.
 
     :param a: the lower left hand point of the rectangle
     :param b: the upper right hand point of the rectangle
     :param n: a tuple of integers indicating the total number of points
       on [a,b].
-    :param face_to_boundary_tag: an optional dictionary for boundary configuration.
+    :param boundary_tag_to_face: an optional dictionary for boundary configuration.
         The keys correspond to custom boundary tags, with the values giving
         a list of the faces on which they should be applied in terms of coordinate
         directions (+x, -x, +y, -y, +z, -z).
@@ -867,7 +880,7 @@ def generate_regular_rect_mesh(a=(0, 0), b=(1, 1), n=(5, 5), order=1,
             for a_i, b_i, n_i in zip(a, b, n)]
 
     return generate_box_mesh(axis_coords, order=order,
-                             face_to_boundary_tag=face_to_boundary_tag)
+                             boundary_tag_to_face=boundary_tag_to_face)
 
 # }}}
 
diff --git a/test/test_meshmode.py b/test/test_meshmode.py
index fe6a1ea2..609e426b 100644
--- a/test/test_meshmode.py
+++ b/test/test_meshmode.py
@@ -124,26 +124,25 @@ def test_boundary_tags():
 
 
 # {{{ test custom boundary tags on box mesh
-
-def test_box_boundary_tags():
+@pytest.mark.parametrize(("dim", "nelem"), [
+    (2, 20),
+    ])
+def test_box_boundary_tags(dim, nelem):
     from meshmode.mesh.generation import generate_regular_rect_mesh
     from meshmode.mesh import is_boundary_tag_empty
     from meshmode.mesh import check_bc_coverage
-    # Test this capability with a 2D mesh.
     mesh = generate_regular_rect_mesh(a=(0, -1), b=(1, 1),
-                                      n=(20, 20), order=3,
-                                      face_to_boundary_tag={
-                                          "btag_test_1": ["+x", "-y"],
-                                          "btag_test_2": ["+y", "-x"]})
+                                      n=(nelem, nelem), order=3,
+                                      boundary_tag_to_face={
+                                      "btag_test_1": ["+x", "-y"],
+                                      "btag_test_2": ["+y", "-x"]})
+    # correct answer
+    num_on_bdy = dim*(nelem-1)
 
-    # ensure boundary is covered
     assert not is_boundary_tag_empty(mesh, "btag_test_1")
     assert not is_boundary_tag_empty(mesh, "btag_test_2")
     check_bc_coverage(mesh, ['btag_test_1', 'btag_test_2'])
 
-    # correct answers
-    num_on_bdy = 38
-
     # check how many elements are marked on each boundary
     num_marked_bdy_1 = 0
     num_marked_bdy_2 = 0
@@ -160,16 +159,15 @@ def test_box_boundary_tags():
                 num_marked_bdy_1 += 1
             if (-nbrs) & btag_2_bit:
                 num_marked_bdy_2 += 1
-
     # raise errors if wrong number of elements marked
     if num_marked_bdy_1 != num_on_bdy:
         raise ValueError("%i marked on custom boundary 1, should be %i" %
                          (num_marked_bdy_1, num_on_bdy))
-
     if num_marked_bdy_2 != num_on_bdy:
         raise ValueError("%i marked on custom boundary 2, should be %i" %
                          (num_marked_bdy_2, num_on_bdy))
 
+
 # }}}
 
 
-- 
GitLab