Пример #1
0
    def test_cp_numbering(self):
        model = SplineModel(3, 3)
        v = Volume().refine(1, 1, 1)
        model.add(v)
        model.add(v + (1, 0, 0))
        model.add(v + (0, 0, 1))

        # Predictable numbering of control points
        model.generate_cp_numbers()
        cps = model.cps()
        self.assertEqual(cps.shape, (63, 3))
        np.testing.assert_almost_equal(cps[:27],
                                       v.controlpoints.reshape(-1, 3))
        np.testing.assert_almost_equal(
            cps[27:45], v.controlpoints[1:].reshape(-1, 3) + (1, 0, 0))
        np.testing.assert_almost_equal(
            cps[45:], v.controlpoints[:, :, 1:].reshape(-1, 3) + (0, 0, 1))
Пример #2
0
    def test_cell_numbering(self):
        model = SplineModel(3, 3)
        v = Volume().refine(1, 1, 1)
        model.add(v)
        model.add(v + (1, 0, 0))
        model.add(v + (0, 0, 1))

        # Predictable numbering of cells
        model.generate_cell_numbers()
        self.assertTrue((model[v].node.cell_numbers.flatten() == np.arange(
            8, dtype=int)).all())
        self.assertTrue(
            (model[v + (1, 0, 0)].node.cell_numbers.flatten() == np.arange(
                8, 16, dtype=int)).all())
        self.assertTrue(
            (model[v + (0, 0, 1)].node.cell_numbers.flatten() == np.arange(
                16, 24, dtype=int)).all())
Пример #3
0
    def test_lookup(self):
        model = SplineModel(3, 3)
        v = Volume().refine(1, 1, 1)
        model.add(v)
        model.add(v + (1, 0, 0))
        model.add(v + (0, 0, 1))

        q = Volume().refine(1, 1, 1)
        self.assertIs(model[q].node, model[v].node)

        q = Volume().refine(1, 1, 1).reverse('u').swap('u', 'v')
        self.assertIs(model[q].node, model[v].node)

        self.assertIs(model[v.section(w=-1)].node,
                      model[(v + (0, 0, 1)).section(w=0)].node)
Пример #4
0
    def test_node_counts(self):
        model = SplineModel(3, 3)
        v = Volume().refine(1, 1, 1)
        model.add(v)
        model.add(v + (1, 0, 0))
        model.add(v + (0, 0, 1))

        # 3 volumes
        cat = model.catalogue
        self.assertEqual(len(cat.top_nodes()), 3)

        # 16 faces
        cat = cat.lower
        self.assertEqual(len(cat.top_nodes()), 16)

        # 28 edges
        cat = cat.lower
        self.assertEqual(len(cat.top_nodes()), 28)

        # 16 vertices
        cat = cat.lower
        self.assertEqual(len(cat.top_nodes()), 16)
Пример #5
0
    def test_orient(self):
        connections = [
            [
                IFEMConnection(1, 2, 2, 1, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 4, 3, 0),
                IFEMConnection(2, 6, 6, 5, 0),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 2, 1, 3),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 3, 3, 1),
                IFEMConnection(2, 6, 5, 5, 1),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 2, 2, 2),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 3, 3, 2),
                IFEMConnection(2, 6, 6, 5, 3),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 2, 2, 1),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 4, 3, 3),
                IFEMConnection(2, 6, 5, 5, 2),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 2, 3, 1),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 2, 3, 1),
                IFEMConnection(2, 6, 5, 5, 4),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 2, 5, 5),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 3, 3, 4),
                IFEMConnection(2, 6, 2, 5, 5),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 2, 4, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 6, 5, 0),
                IFEMConnection(2, 4, 2, 3, 2),
                IFEMConnection(2, 6, 6, 5, 6),
                IFEMConnection(3, 4, 2, 1, 0),
                IFEMConnection(3, 7, 6, 5, 0),
                IFEMConnection(4, 8, 6, 5, 0),
                IFEMConnection(5, 6, 2, 1, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 2, 1, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 1, 1),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 6, 4),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 4, 1, 1),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 5, 4),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 1, 0),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 4, 1, 4),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 6, 0),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 3, 1),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 2, 1, 6),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 3, 5),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 1, 5),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 5, 1, 4),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 1, 7),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 4, 5),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 5, 1, 1),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 1, 2),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 5, 5),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 3, 1, 0),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 5, 7),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 2, 2),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 3, 1, 5),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 3, 6),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 2, 4),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 6, 1, 5),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
            [
                IFEMConnection(1, 2, 6, 5, 0),
                IFEMConnection(1, 3, 4, 3, 0),
                IFEMConnection(1, 5, 2, 1, 0),
                IFEMConnection(2, 4, 4, 4, 7),
                IFEMConnection(2, 6, 2, 1, 0),
                IFEMConnection(3, 4, 6, 2, 7),
                IFEMConnection(3, 7, 2, 1, 0),
                IFEMConnection(4, 8, 5, 1, 7),
                IFEMConnection(5, 7, 4, 3, 0),
                IFEMConnection(5, 6, 6, 5, 0),
                IFEMConnection(6, 8, 4, 3, 0),
                IFEMConnection(7, 8, 6, 5, 0)
            ],
        ]

        for i, ref_topo in enumerate(connections):
            model = SplineModel(3, 3)
            with G2(THIS_DIR +
                    '/geometries/cube-8-orient{}.g2'.format(i)) as myfile:
                model.add(myfile.read())

            writer = IFEMWriter(model)
            my_topo = list(writer.connections())

            my_topo = sorted(my_topo, key=lambda c: c.slave)
            my_topo = sorted(my_topo, key=lambda c: c.master)
            ref_topo = sorted(ref_topo, key=lambda c: c.slave)
            ref_topo = sorted(ref_topo, key=lambda c: c.master)

            for my_con, ref_con in zip(my_topo, ref_topo):
                assert my_con == ref_con
            assert len(my_topo) == len(ref_topo)
Пример #6
0
    def test_faces(self):
        model = SplineModel(3, 3)
        v = Volume().refine(1, 1, 1)
        vr = v + (1, 0, 0)
        vu = v + (0, 0, 1)
        model.add([v, vr, vu])

        model[v.section(u=0)].name = 'uneg'
        model[vr.section(u=-1)].name = 'upos'
        model[vu.section(u=0)].name = 'uneg'
        model[vu.section(u=-1)].name = 'upos'

        for vv in [v, vr, vu]:
            model[vv.section(v=0)].name = 'vneg'
            model[vv.section(v=-1)].name = 'vpos'

        model[v.section(w=0)].name = 'wneg'
        model[vr.section(w=0)].name = 'wneg'
        model[vr.section(w=-1)].name = 'wpos'
        model[vu.section(w=-1)].name = 'wpos'

        model.generate_cp_numbers()
        model.generate_cell_numbers()
        faces = model.faces()

        self.assertEqual(len(faces), 100)

        # The owner should always be the lower numbered cell
        self.assertTrue(((faces['owner'] < faces['neighbor']) |
                         (faces['neighbor'] == -1)).all())

        # Where the boundary is named, the neighbor is always -1
        self.assertTrue((faces[faces['name'] != None]['neighbor'] == -1).all())

        # On internal faces, the neighbor is always > 0
        self.assertTrue((faces[faces['name'] == None]['neighbor'] > 0).all())

        # Boundaries occur the expected number of times
        self.assertEqual(np.sum(faces['name'] == None), 44)
        self.assertEqual(np.sum(faces['name'] == 'uneg'), 8)
        self.assertEqual(np.sum(faces['name'] == 'upos'), 8)
        self.assertEqual(np.sum(faces['name'] == 'vneg'), 12)
        self.assertEqual(np.sum(faces['name'] == 'vpos'), 12)
        self.assertEqual(np.sum(faces['name'] == 'wneg'), 8)
        self.assertEqual(np.sum(faces['name'] == 'wpos'), 8)

        # Every cell is mentioned by exactly six faces
        nmentions = [0] * 24
        for face in faces:
            nmentions[face['owner']] += 1
            if face['neighbor'] > 0:
                nmentions[face['neighbor']] += 1
        self.assertEqual(nmentions, [6] * 24)

        # Face normals always point toward the neighbor
        # In this case, that means in a positive axial direction,
        # except possibly for boundary faces
        cps = model.cps()
        for face in faces:
            for I in [face['nodes'][:-1], face['nodes'][1:]]:
                vertices = cps[I]
                z = np.cross(vertices[1] - vertices[0],
                             vertices[2] - vertices[1])

                # Should be zero, zero and +/- 0.25
                self.assertAlmostEqual(sum(np.abs(z)), 0.25)

                # j = index of the 0.25
                j = np.argmax(np.abs(z))
                others = {0: [1, 2], 1: [0, 2], 2: [0, 1]}[j]
                np.testing.assert_almost_equal(z[others], 0.0)

                # Check that the 0.25 has the right sign
                if face['name'] is None or face['name'][1:] == 'pos':
                    np.testing.assert_almost_equal(z[j], 0.25)
                else:
                    np.testing.assert_almost_equal(z[j], -0.25)

                # And that it occurs in the expected index (for boundary faces)
                if face['name'] is not None:
                    self.assertEqual(j, 'uvw'.index(face['name'][0]))