def _test_subdomain_conn(self, axis):
        # All coordinate tuples below are specified for the case
        # in which the two subdomains are connected along the X axis.
        # Y-axis connection requires a swap.
        def f(a, b):
            if axis == 0:
                return (a,b)
            else:
                return (b,a)

        face_hi = SubdomainSpec2D.axis_dir_to_face(axis, 1)
        face_lo = SubdomainSpec2D.axis_dir_to_face(axis, -1)
        base = SubdomainSpec2D(f(10, 10), f(10, 10), envelope_size=1, id_=0)

        # exact match
        b1 = SubdomainSpec2D(f(20, 10), f(5, 10), envelope_size=1, id_=1)
        self.assertTrue(base.connect(b1, grid=D2Q9))
        cpair = base.get_connection(face_hi, b1.id)
        self.assertEqual(set(cpair.src.dists),
                         set([vi(*f(1,0)), vi(*f(1,1)), vi(*f(1,-1))]))
        self.assertEqual(cpair.src.src_slice, [slice(1, 11)])
        self.assertEqual(cpair.src.src_macro_slice, [slice(1, 11)])
        self.assertEqual(cpair.src.dst_macro_slice, [slice(1, 11)])
        self.assertEqual(cpair.src.dst_low, [0])
        self.assertEqual(cpair.src.dst_slice, [slice(1, 9)])
        self.assertEqual(cpair.src.dst_full_buf_slice, [slice(1, 9)])
        expected_map = {vi(*f(1,-1)): np.array([[0]]),
                        vi(*f(1,1)): np.array([[9]]),
                        vi(*f(1,0)): np.array([[0],[9]])}
        _verify_partial_map(self, cpair.src, expected_map)

        self.assertEqual(cpair.src.elements, 30)
        self.assertEqual(cpair.src.transfer_shape, [3, 10])

        # partal overlap
        b2 = SubdomainSpec2D(f(20, 5), f(5, 10), envelope_size=1, id_=2)
        self.assertTrue(base.connect(b2, grid=D2Q9))
        cpair = base.get_connection(face_hi, b2.id)
        self.assertEqual(cpair.src.src_slice, [slice(0, 6)])
        self.assertEqual(cpair.src.src_macro_slice, [slice(1, 7)])
        self.assertEqual(cpair.src.dst_macro_slice, [slice(0, 6)])
        self.assertEqual(cpair.src.dst_low, [4])
        self.assertEqual(cpair.src.dst_slice, [slice(6, 10)])
        self.assertEqual(cpair.src.dst_full_buf_slice, [slice(2, 6)])
        expected_map = {vi(*f(1,-1)): np.array([[0], [1]]),
                        vi(*f(1,0)): np.array([[1]])}
        _verify_partial_map(self, cpair.src, expected_map)

        # full overlap (2nd subdomain is smaller)
        b3 = SubdomainSpec2D(f(20, 12), f(5, 7), envelope_size=1, id_=3)
        self.assertTrue(base.connect(b3, grid=D2Q9))
        cpair = base.get_connection(face_hi, b3.id)
        self.assertEqual(cpair.src.src_slice, [slice(3, 10)])
        self.assertEqual(cpair.src.src_macro_slice, [slice(2, 11)])
        self.assertEqual(cpair.src.dst_low, [0])
        self.assertEqual(cpair.src.dst_slice, [slice(0, 7)])
        self.assertEqual(cpair.src.dst_full_buf_slice, [slice(0, 7)])
        self.assertFalse(cpair.src.dst_partial_map)

        self.assertEqual(cpair.dst.src_slice, [slice(0, 9)])
        self.assertEqual(cpair.dst.src_macro_slice, [slice(1, 8)])
        self.assertEqual(cpair.dst.dst_low, [1])
        self.assertEqual(cpair.dst.dst_slice, [slice(3, 8)])
        self.assertEqual(cpair.dst.dst_full_buf_slice, [slice(2, 7)])

        # full overlap (2nd subdomain is larger)
        b4 = SubdomainSpec2D(f(20, 8), f(5, 14), envelope_size=1, id_=4)
        self.assertTrue(base.connect(b4, grid=D2Q9))
        cpair = base.get_connection(face_hi, b4.id)
        self.assertEqual(cpair.src.src_slice, [slice(0, 12)])
        self.assertEqual(cpair.src.src_macro_slice, [slice(1, 11)])
        self.assertEqual(cpair.src.dst_low, [1])
        self.assertEqual(cpair.src.dst_slice, [slice(3, 11)])
        self.assertEqual(cpair.src.dst_full_buf_slice, [slice(2, 10)])
        expected_map = {
                vi(*f(1,-1)): np.array([[0], [1]]),
                vi(*f(1,0)): np.array([[1], [10]]),
                vi(*f(1,1)): np.array([[10], [11]])}
        _verify_partial_map(self, cpair.src, expected_map)

        # exact match at the bottom (2nd subdomain is smaller)
        b5 = SubdomainSpec2D(f(20, 10), f(5, 5), envelope_size=1, id_=5)
        self.assertTrue(base.connect(b5, grid=D2Q9))
        cpair = base.get_connection(face_hi, b5.id)
        self.assertEqual(cpair.src.src_slice, [slice(1, 6)])
        self.assertEqual(cpair.src.src_macro_slice, [slice(1, 7)])
        self.assertEqual(cpair.src.dst_low, [0])
        self.assertEqual(cpair.src.dst_slice, [slice(1, 5)])
        self.assertEqual(cpair.src.dst_full_buf_slice, [slice(1, 5)])
        expected_map = {
                vi(*f(1,-1)): np.array([[0]]),
                vi(*f(1,0)): np.array([[0]])}
        _verify_partial_map(self, cpair.src, expected_map)

        # exact match at the bottom (2nd subdomain is larger)
        b6 = SubdomainSpec2D(f(20, 10), f(5, 15), envelope_size=1, id_=6)
        self.assertTrue(base.connect(b6, grid=D2Q9))
        cpair = base.get_connection(face_hi, b6.id)
        self.assertEqual(cpair.src.src_slice, [slice(1, 12)])
        self.assertEqual(cpair.src.src_macro_slice, [slice(1, 11)])
        self.assertEqual(cpair.src.dst_low, [0])
        self.assertEqual(cpair.src.dst_slice, [slice(1, 9)])
        self.assertEqual(cpair.src.dst_full_buf_slice, [slice(1, 9)])
        expected_map = {
                vi(*f(1,-1)): np.array([[0]]),
                vi(*f(1,0)): np.array([[0], [9]]),
                vi(*f(1,1)): np.array([[9], [10]]),
            }
        _verify_partial_map(self, cpair.src, expected_map)

        # note that the size of the src_slice is different, depending
        # on the direction of the transfer
        self.assertEqual(cpair.dst.src_slice, [slice(1, 11)])
        self.assertEqual(cpair.dst.src_macro_slice, [slice(1, 12)])
        self.assertEqual(cpair.dst.dst_low, [0])
        self.assertEqual(cpair.dst.dst_slice, [slice(1,10)])
        self.assertEqual(cpair.dst.dst_full_buf_slice, [slice(1,10)])

        # disconnected subdomains
        bf1 = SubdomainSpec2D(f(20, 21), f(5, 10), envelope_size=1)
        bf2 = SubdomainSpec2D(f(20, 5),  f(5, 4), envelope_size=1)
        bf3 = SubdomainSpec2D(f(19, 10), f(5, 10), envelope_size=1)
        bf4 = SubdomainSpec2D(f(21, 10), f(5, 10), envelope_size=1)
        self.assertFalse(base.connect(bf1))
        self.assertFalse(base.connect(bf2))
        self.assertFalse(base.connect(bf3))
        self.assertFalse(base.connect(bf4))