예제 #1
0
    def test_add_node(self):
        # Test 3D mesh
        mesh = Mesh(3)

        # test with tuple
        coords = (0.0, 1.0, 2.0)
        new_id = mesh.add_node(coords)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y', 'z']]
        assert_array_equal(coords_actual, np.array(coords, dtype=float))

        # test with array
        coords = np.array([5, 6, 3], dtype=float)
        new_id = mesh.add_node(coords)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y', 'z']]
        assert_array_equal(coords_actual, np.array(coords, dtype=float))

        # test with dict and id
        coords = {'x': 5.0, 'y': 6.0, 'z': 3}
        new_id = mesh.add_node(coords, 8)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y', 'z']]
        assert_array_equal(coords_actual, np.array([5, 6, 3], dtype=float))
        self.assertEqual(new_id, 8)

        # test raise error no overwrite
        coords = np.array([10, 4, 2], dtype=float)
        with self.assertRaises(ValueError):
            new_id = mesh.add_node(coords, 8)

        # test overwrite and with int array
        coords = np.array([10, 4, 2], dtype=int)
        new_id = mesh.add_node(coords, 8, overwrite=True)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y', 'z']]
        assert_array_equal(coords_actual, np.array(coords, dtype=float))
        self.assertEqual(new_id, 8)

        # Test 2D mesh
        mesh = Mesh(2)

        # test with tuple
        coords = (0.0, 1.0, 2.0)
        new_id = mesh.add_node(coords)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y']]
        assert_array_equal(coords_actual, np.array(coords[0:2], dtype=float))

        # test with array
        coords = np.array([5, 6, 3], dtype=float)
        new_id = mesh.add_node(coords)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y']]
        assert_array_equal(coords_actual, np.array(coords[0:2], dtype=float))

        # test with dict and id
        coords = {'x': 5.0, 'y': 6.0, 'z': 3}
        new_id = mesh.add_node(coords, 8)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y']]
        assert_array_equal(coords_actual, np.array([5, 6], dtype=float))
        self.assertEqual(new_id, 8)

        # test raise error no overwrite
        coords = np.array([10, 4, 2], dtype=float)
        with self.assertRaises(ValueError):
            new_id = mesh.add_node(coords, 8)

        # test overwrite and with int array
        coords = np.array([10, 4, 2], dtype=int)
        new_id = mesh.add_node(coords, 8, overwrite=True)
        coords_actual = mesh.nodes_df.loc[new_id, ['x', 'y']]
        assert_array_equal(coords_actual, np.array(coords[0:2], dtype=float))
        self.assertEqual(new_id, 8)
예제 #2
0
    def test_add_element(self):
        mesh = Mesh(2)
        for nodeid, coords in zip(self._nodeids, self._nodes):
            mesh.add_node(coords, nodeid)

        conn_desired = np.array([5, 6, 3], dtype=np.int)
        shape_desired = 'Tri3'
        new_id = mesh.add_element(shape_desired, conn_desired)
        shape_actual = mesh.get_ele_shapes_by_elementids([new_id])[0]
        conn_actual = mesh.get_connectivity_by_elementids([new_id])[0]
        self.assertEqual(shape_actual, shape_desired)
        assert_array_equal(conn_actual, conn_desired)

        conn_desired = np.array([4, 1], dtype=np.int)
        shape_desired = 'straight_line'
        new_id = mesh.add_element(shape_desired, conn_desired)
        shape_actual = mesh.get_ele_shapes_by_elementids([new_id])[0]
        conn_actual = mesh.get_connectivity_by_elementids([new_id])[0]
        self.assertEqual(shape_actual, shape_desired)
        assert_array_equal(conn_actual, conn_desired)

        conn_desired = np.array([3, 2, 5], dtype=np.int)
        shape_desired = 'Tri3'
        new_id = mesh.add_element(shape_desired,
                                  np.array([3, 2, 5], dtype=np.int), 5)
        shape_actual = mesh.get_ele_shapes_by_elementids([new_id])[0]
        conn_actual = mesh.get_connectivity_by_elementids([new_id])[0]
        self.assertEqual(shape_actual, shape_desired)
        assert_array_equal(conn_actual, conn_desired)
        self.assertEqual(new_id, 5)

        with self.assertRaises(ValueError):
            mesh.add_element('Quad4', np.array([1, 2, 3, 4], dtype=np.int), 5)

        conn_desired = np.array([1, 2, 3, 4], dtype=np.int)
        shape_desired = 'Quad4'
        new_id = mesh.add_element('Quad4',
                                  np.array([1, 2, 3, 4], dtype=np.int),
                                  5,
                                  overwrite=True)
        shape_actual = mesh.get_ele_shapes_by_elementids([new_id])[0]
        conn_actual = mesh.get_connectivity_by_elementids([new_id])[0]
        self.assertEqual(shape_actual, shape_desired)
        assert_array_equal(conn_actual, conn_desired)
        self.assertEqual(new_id, 5)

        # Test wrong dtype
        new_id = mesh.add_element('Quad4',
                                  np.array([1, 2, 3, 4], dtype=np.float), 6)
        shape_actual = mesh.get_ele_shapes_by_elementids([new_id])[0]
        conn_actual = mesh.get_connectivity_by_elementids([new_id])[0]
        self.assertEqual(shape_actual, shape_desired)
        assert_array_equal(conn_actual, conn_desired)
        self.assertEqual(new_id, 6)

        # Test with tuple instead of array
        new_id = mesh.add_element('Quad4', (1, 2, 3, 4), 7)
        shape_actual = mesh.get_ele_shapes_by_elementids([new_id])[0]
        conn_actual = mesh.get_connectivity_by_elementids([new_id])[0]
        self.assertEqual(shape_actual, shape_desired)
        assert_array_equal(conn_actual, conn_desired)
        self.assertEqual(new_id, 7)

        # Test wrong shape
        with self.assertRaises(ValueError):
            mesh.add_element('wrong_shape', np.array([1, 2, 3, 4],
                                                     dtype=np.int), 8)
예제 #3
0
class RectangleMesh2D:
    def __init__(self, l, h, n_ele_l, n_ele_h, x_start=0.0, y_start=0.0):
        self.l = l
        self.h = h
        self.n_ele_l = n_ele_l
        self.n_ele_h = n_ele_h
        self.delta_h_x = self.l / self.n_ele_l
        self.delta_h_y = self.h / self.n_ele_h
        self.x_start = x_start
        self.y_start = y_start

        self._mesh = Mesh(2)

    @property
    def mesh(self):
        return self._mesh

    def generate_mesh(self):
        self._create_nodes()
        self._create_elements()

    def _create_nodes(self):
        for i_node_y in np.arange(self.n_ele_h+1):
            for i_node_x in np.arange(self.n_ele_l+1):
                self._mesh.add_node([self.x_start + i_node_x * self.delta_h_x, self.y_start + i_node_y * self.delta_h_y])

    def _create_elements(self):
        for i_ele_y in np.arange(self.n_ele_h):
            for i_ele_x in np.arange(self.n_ele_l):
                node1 = self._mesh.get_nodeid_by_coordinates(self.x_start + i_ele_x * self.delta_h_x,
                                                             self.y_start + i_ele_y * self.delta_h_y)
                node2 = self._mesh.get_nodeid_by_coordinates(self.x_start + (i_ele_x + 1) * self.delta_h_x,
                                                             self.y_start + i_ele_y * self.delta_h_y)
                node3 = self._mesh.get_nodeid_by_coordinates(self.x_start + (i_ele_x + 1) * self.delta_h_x,
                                                             self.y_start + (i_ele_y + 1) * self.delta_h_y)
                node4 = self._mesh.get_nodeid_by_coordinates(self.x_start + i_ele_x * self.delta_h_x,
                                                             self.y_start + (i_ele_y + 1) * self.delta_h_y)
                connectivity = np.array([node1, node2, node3, node4])
                self._mesh.add_element('Quad4', connectivity)

    def add_boundary(self, edge, group_name=None):
        if edge is 'left':
            nodes = self._mesh.get_nodeids_by_coordinate_axis(self.x_start, 'x', 1e-6)
        elif edge is 'right':
            nodes = self._mesh.get_nodeids_by_coordinate_axis(self.x_start+self.l, 'x', 1e-6)
        elif edge is 'bottom':
            nodes = self._mesh.get_nodeids_by_coordinate_axis(self.y_start, 'y', 1e-6)
        elif edge is 'top':
            nodes = self._mesh.get_nodeids_by_coordinate_axis(self.y_start + self.h, 'y', 1e-6)
        else:
            raise ValueError('Unknown edge-type')
        for idx in range(nodes.size-1):
            eleid = self._mesh.add_element('straight_line', np.array([nodes[idx], nodes[idx+1]]))
            if group_name is not None and len(self._mesh.get_groups_by_elementids([eleid])) == 0:
                if group_name in self._mesh.groups:
                    self._mesh.add_element_to_groups(eleid, [group_name])
                else:
                    self._mesh.create_group(group_name, (), [eleid])

    def set_checkerboard_groups(self, segment_length, segment_height, segment_groups):
        n_seg_x = int(round(self.l/segment_length))
        n_seg_y = int(round(self.h/segment_height))
        segments = dict()
        seg = 0
        for seg_y in range(n_seg_y):
            for seg_x in range(n_seg_x):
                if seg_y % 2 == 0:
                    group_name = segment_groups[seg_x % len(segment_groups)]
                else:
                    group_name = segment_groups[(seg_x+1) % len(segment_groups)]
                segments[seg] = {'nodes': {'lowerleft': np.array([seg_x * segment_length, seg_y * segment_height]),
                                           'lowerright': np.array([(seg_x + 1) * segment_length, seg_y * segment_height]),
                                           'upperleft': np.array([seg_x * segment_length, (seg_y + 1) * segment_height]),
                                           'upperright': np.array([(seg_x + 1) * segment_length, (seg_y + 1) * segment_height])},
                                 'group': group_name
                                 }
                seg += 1

        def check_node_in_segment(P1, P2, P3, P4, node):
            edge_x = P2 - P1
            edge_y = P4 - P1
            constraint_x = (np.dot(edge_x, P1) <= np.dot(edge_x, node) <= np.dot(edge_x, P2))
            constraint_y = (np.dot(edge_y, P1) <= np.dot(edge_y, node) <= np.dot(edge_y, P4))
            return constraint_x and constraint_y

        eleids = self._mesh.get_elementids_by_tags(['shape'], ['Quad4'])
        for eleid in eleids:
            nodes = self._mesh.get_nodeids_by_elementids([eleid])
            for idx, seg in segments.items():
                seg_nodes = seg['nodes']
                ele_in_segment = True
                for node in nodes:
                    node_pos = np.array([self._mesh.nodes_df.at[node,'x'], self._mesh.nodes_df.at[node,'y']])
                    if not check_node_in_segment(seg_nodes['lowerleft'], seg_nodes['lowerright'],
                                                 seg_nodes['upperright'], seg_nodes['upperleft'], node_pos):
                        ele_in_segment = False
                        break
                if ele_in_segment:
                    if seg['group'] in self._mesh.groups:
                        self._mesh.add_element_to_groups(eleid, [seg['group']])
                    else:
                        self._mesh.create_group(seg['group'], (), [eleid])
                    break

    def set_homogeneous_group(self, groupname):
        self._mesh.create_group(groupname, (), self._mesh.get_elementids_by_tags(['shape'], ['Quad4']))