Esempio n. 1
0
def test_get_side_set_node_list_quad(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=2,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.zeros(5))
        e.put_elem_blk_info(1, b"QUAD", 6, 4, 0)
        e.put_elem_connectivity(1, np.arange(6 * 4) + 7)
        e.put_side_set_params(4, 4, 0)
        e.put_side_set(4,
                       np.arange(4, dtype=np.int32) + 2,
                       np.arange(4, dtype=np.int32) + 1)

    with exodus(filename, mode="r") as e:
        num_nodes, local_node_ids = e.get_side_set_node_list(id=4)

    np.testing.assert_equal(num_nodes, [2, 2, 2, 2])
    np.testing.assert_equal(local_node_ids, [11, 12, 16, 17, 21, 22, 26, 23])
Esempio n. 2
0
def test_get_element_variable_values(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    e = exodus(filename,
               mode="w",
               title="Example",
               array_type="numpy",
               numDims=3,
               numNodes=5,
               numElems=6,
               numBlocks=1,
               numNodeSets=0,
               numSideSets=1,
               io_size=io_size["io_size"])
    e.set_element_variable_number(5)
    e.put_element_variable_name("random", 3)
    # requires an actual element block.
    e.put_elem_blk_info(1, "HEX", 6, 3, 0)
    e.put_element_variable_values(1, "random", 1, np.arange(6))
    e.close()

    with exodus(filename, mode="a") as e:
        values = e.get_element_variable_values(1, "random", 1)
        np.testing.assert_equal(values, np.arange(6))

        # Raises a value error if the variable does not exist.
        with pytest.raises(ValueError):
            e.get_element_variable_values(1, "rando", 1)
Esempio n. 3
0
def test_get_elem_connectivity_only_some_indices(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    # Generate test file.
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=2,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.zeros(5))
        e.put_elem_blk_info(1, "HEX", 3, 8, 0)
        e.put_elem_connectivity(1, np.arange(3 * 8) + 7)

    with exodus(filename, mode="r") as e:
        conn, num_elem, num_nodes_per_elem = e.get_elem_connectivity(
            id=1, indices=[1, 3])

    np.testing.assert_equal(conn, (np.arange(3 * 8) + 7).reshape(
        (3, 8))[[0, 2]])
    assert num_elem == 3
    assert num_nodes_per_elem == 8
Esempio n. 4
0
def test_get_coord_2d(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=2,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.zeros(5))

    with exodus(filename, mode="r") as e:
        with pytest.raises(ValueError) as f:
            e.get_coord(0)
        assert f.value.args[0] == "Invalid index. Coordinate bounds: [1, 5]."
        with pytest.raises(ValueError) as f:
            e.get_coord(6)
        assert f.value.args[0] == "Invalid index. Coordinate bounds: [1, 5]."

        np.testing.assert_allclose(e.get_coord(1), [0.0, 0.0, 0.0])
        np.testing.assert_allclose(e.get_coord(2), [1.0, 2.0, 0.0])
        np.testing.assert_allclose(e.get_coord(3), [2.0, 4.0, 0.0])
Esempio n. 5
0
def test_get_side_set_node_list_hex(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    # Hex elements.
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=3,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.arange(5, dtype=np.float64) * 3)
        e.put_elem_blk_info(1, "HEX", 6, 8, 0)
        e.put_elem_connectivity(1, np.arange(6 * 8) + 7)
        e.put_side_set_params(4, 5, 0)
        e.put_side_set(4,
                       np.arange(5, dtype=np.int32) + 2,
                       np.arange(5, dtype=np.int32) + 1)

    with exodus(filename, mode="r") as e:
        num_nodes, local_node_ids = e.get_side_set_node_list(id=4)

    np.testing.assert_equal(num_nodes, [4, 4, 4, 4, 4])
    np.testing.assert_equal(local_node_ids, [
        15, 16, 20, 19, 24, 25, 29, 28, 33, 34, 38, 37, 39, 43, 46, 42, 47, 50,
        49, 48
    ])
Esempio n. 6
0
def test_get_side_set_invalid_id(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    # Put two side sets. Note that the ids of the side sets have little to
    # do with their naming inside the file...
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=3,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=2,
                io_size=io_size["io_size"]) as e:
        e.put_side_set_params(4, 5, 0)
        e.put_side_set(4,
                       np.ones(5, dtype=np.int32) * 2,
                       np.ones(5, dtype=np.int32) * 3)
        e.put_side_set_name(4, "edge of the world")

        e.put_side_set_params(2, 5, 0)
        e.put_side_set(2,
                       np.ones(5, dtype=np.int32) * 7,
                       np.ones(5, dtype=np.int32) * 8)
        e.put_side_set_name(2, "hallo")

    with exodus(filename, mode="r") as e:
        with pytest.raises(ValueError) as f:
            e.get_side_set(id=7)

    assert f.value.args[0] == \
        "No side set with id 7 in file. Available ids: 4, 2."
Esempio n. 7
0
def test_get_side_set_hex(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    # Hex elements.
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=3,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.arange(5, dtype=np.float64) * 3)
        e.put_elem_blk_info(1, "HEX", 6, 8, 0)
        e.put_elem_connectivity(1, np.arange(6 * 8) + 7)
        e.put_side_set_params(4, 5, 0)
        e.put_side_set(4,
                       np.arange(5, dtype=np.int32) + 2,
                       np.arange(5, dtype=np.int32) + 1)

    with exodus(filename, mode="r") as e:
        elem_idx, side_ids = e.get_side_set(id=4)

    np.testing.assert_equal(elem_idx, [2, 3, 4, 5, 6])
    np.testing.assert_equal(side_ids, [1, 2, 3, 4, 5])
Esempio n. 8
0
def test_get_side_set_ids(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    # Put two side sets. Note that the ids of the side sets have little to
    # do with their naming inside the file...
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=3,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=2,
                io_size=io_size["io_size"]) as e:
        e.put_side_set_params(4, 5, 0)
        e.put_side_set(4,
                       np.ones(5, dtype=np.int32) * 2,
                       np.ones(5, dtype=np.int32) * 3)
        e.put_side_set_name(4, "edge of the world")

        e.put_side_set_params(2, 5, 0)
        e.put_side_set(2,
                       np.ones(5, dtype=np.int32) * 7,
                       np.ones(5, dtype=np.int32) * 8)
        e.put_side_set_name(2, "hallo")

    with exodus(filename, mode="r") as e:
        assert e.get_side_set_ids() == [4, 2]
Esempio n. 9
0
    def read(self):
        """ Reads the original exodus model files."""
        final_file = os.path.join(self.directory, "final.e")
        initial_file = os.path.join(self.directory, "initial.e")

        # Read yaml file containing information on the ses3d submodel.
        with io.open(os.path.join(self.directory, 'modelinfo.yml'), 'rt') as fh:
            try:
                self.model_info = yaml.load(fh, Loader=yaml.FullLoader)
                print('Evaluating Salvus 1 model: {}'.format(self.model_info['model']))
            except yaml.YAMLError as exc:
                print(exc)

        # Read perturbations
        taper = self.get_edge_taper(exodus_file=initial_file)
        # This is just hardcoded, since there is only one Salvusv1 model.
        edge_taper = True

        for param in self.params:
            with pyexodus.exodus(final_file) as e_final:
                val = e_final.get_node_variable_values(param, step=1)
            with pyexodus.exodus(initial_file) as e_init:
                val -= e_init.get_node_variable_values(param, step=1)

                if edge_taper:
                    self.perturbations[param] = val * taper
                else:
                    self.perturbations[param] = val

        # read points
        with pyexodus.exodus(initial_file) as e_init:
            # get coords and convert to km
            x, y, z = e_init.get_coords()
            self.points = np.array((x, y, z)).T / 1000.0

            if "radius_1D" in e_init.get_node_variable_names():
                self.radius_1d = e_init.get_node_variable_values("radius_1D",
                                                                 step=1)

            rads_3d = np.sqrt(self.points[:, 0] ** 2 + self.points[:, 1] ** 2 +
                              self.points[:, 2] ** 2)
            # convert coordinates to CSEM reference frame
            self.points[:, 0] = self.points[:, 0] * self.radius_1d * \
                                6371.0 / rads_3d
            self.points[:, 1] = self.points[:, 1] * self.radius_1d * \
                                6371.0 / rads_3d
            self.points[:, 2] = self.points[:, 2] * self.radius_1d * \
                                6371.0 / rads_3d

            self.connectivity, self.nelem, self.nodes_per_element = \
                e_init.get_elem_connectivity(id=1)
            # subtract 1, because exodus uses one based numbering
            self.connectivity -= 1
            self.connectivity = self.connectivity.astype("int64")
Esempio n. 10
0
    def attach_field(self, name, values):
        """
        Write values with name to exodus file
        :param name: name of the variable to be written
        :param values: numpy array of values to be written
        :return:
        """

        assert self.mode in ["a"], ("Attach field option only "
                                    "available in mode 'a'")

        with exodus(self._filename, self.mode) as e:
            if values.size == self.nelem:
                e.put_element_variable_values(blockId=1,
                                              name=name,
                                              step=1,
                                              values=values)

            elif values.size == self.npoint:
                # print(name)
                idx = e.get_node_variable_names().index(name) + 1
                # print(idx)
                # print(name)
                # print(e.get_node_variable_names())
                e.put_node_variable_name(name, index=idx)
                # print(e.get_node_variable_names())
                e.put_node_variable_values(name, 1, values)

            else:
                raise ValueError("Shape matches neither the nodes nor the "
                                 "elements")
Esempio n. 11
0
def rotate_mesh(mesh, event_loc, backwards=False):
    """
    Rotate the coordinates of a mesh to make the source show up below
    the North Pole of the mesh. Can also be used to rotate backwards.
    :param mesh: filename of mesh to be rotated
    :param event_loc: location of event to be rotated to N [lat, lon]
    :param backwards: Backrotation uses transpose of rot matrix
    """

    event_vec = [np.cos(event_loc[0]) * np.cos(event_loc[1]),
                 np.cos(event_loc[0]) * np.sin(event_loc[1]),
                 np.sin(event_loc[0])]
    event_vec = np.array(event_vec) / np.linalg.norm(event_vec)
    north_vec = np.array([0.0, 0.0, 1.0])

    rotate_axis = np.cross(event_vec, north_vec)
    rotate_axis /= np.linalg.norm(rotate_axis)
    # Make sure that both axis and angle make sense with r-hand-rule
    rot_angle = np.arccos(np.dot(event_vec, north_vec))
    rot_mat = get_rot_matrix(rot_angle, rotate_axis[0], rotate_axis[1],
                             rotate_axis[2])
    if backwards:
        rot_mat = rot_mat.T

    mesh = exodus(mesh, mode="a")
    points = mesh.get_coords()
    rotated_points = rotate(x=points[0], y=points[1],
                            z=points[2], matrix=rot_mat)
    rotated_points = rotated_points.T

    mesh.put_coords(rotated_points[:, 0], rotated_points[:, 1],
                    rotated_points[:, 2])
Esempio n. 12
0
def test_num_dims_accessor(tmpdir, io_size):
    # 2D
    filename = os.path.join(tmpdir.strpath, "example_2d.e")
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=2,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.zeros(5))
    with exodus(filename, mode="r") as e:
        assert e.num_dims == 2

    # 3D
    filename = os.path.join(tmpdir.strpath, "example_3d.e")
    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=3,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.zeros(5))
    with exodus(filename, mode="r") as e:
        assert e.num_dims == 3
Esempio n. 13
0
def test_get_coords_2d(tmpdir, io_size):
    filename = os.path.join(tmpdir.strpath, "example.e")

    with exodus(filename,
                mode="w",
                title="Example",
                array_type="numpy",
                numDims=2,
                numNodes=5,
                numElems=6,
                numBlocks=1,
                numNodeSets=0,
                numSideSets=1,
                io_size=io_size["io_size"]) as e:
        e.put_coords(xCoords=np.arange(5, dtype=np.float64),
                     yCoords=np.arange(5, dtype=np.float64) * 2,
                     zCoords=np.zeros(5))

    with exodus(filename, mode="r") as e:
        np.testing.assert_allclose(
            e.get_coords(),
            [np.arange(5), np.arange(5) * 2,
             np.zeros(5)])
Esempio n. 14
0
    def get_element_field(self, name):
        """
        Get values from elemental field.
        :param name: name of the variable to be retrieved
        :return element field values:
        """

        assert self.mode in ["r", "a"], ("Attach field option only "
                                         "available in mode 'r' or 'a'")
        assert name in self.elem_var_names, ("Could not find "
                                             "the requested field")
        with exodus(self._filename, self.mode) as e:
            values = e.get_element_variable_values(blockId=1,
                                                   name=name,
                                                   step=1)
        return values
Esempio n. 15
0
    def get_nodal_field(self, name):
        """
        Get values from nodal field.
        :param name: name of the variable to be retrieved
        :return nodal field values:
        """

        assert self.mode in ["r", "a"], ("Attach field option only "
                                         "available in mode 'r' or 'a'")

        with exodus(self._filename, self.mode) as e:
            assert (name in e.get_node_variable_names()
                    ), "Could not find the requested field"

            values = e.get_node_variable_values(name=name, step=1)
        return values
Esempio n. 16
0
    def __init__(self, filename, mode='r'):
        self._filename = filename
        assert mode in ['a', 'r'], "Only mode 'a', 'r' is supported"
        self.mode = mode
        self.connectivity = None
        self.nodes_per_element = None
        self.ndim = None
        self.nelem = None
        self.x = None
        self.y = None
        self.z = None
        self.elem_var_names = None
        self.points = None
        self.e = exodus(self._filename, self.mode)

        # Read File
        self._read()
Esempio n. 17
0
    def _read(self):
        """
        Retrieves basic information from the exodus file
        :return:
        """
        with exodus(self._filename, self.mode) as e:
            self.ndim = e.num_dims
            # assert e.num_dims in [3], "Only '3D' exodus files are supported."
            self.connectivity, self.nelem, self.nodes_per_element = e.get_elem_connectivity(
                id=1)

            # subtract 1 from connectivity
            # as exodus in 1 based, whereas python is not
            self.connectivity = np.array(self.connectivity, dtype="int64") - 1

            self.elem_var_names = e.get_element_variable_names()
            self.points = np.array((e.get_coords())).T.astype(np.float64)
            self.nodal_parameters = e.get_node_variable_names()
Esempio n. 18
0
    def get_edge_taper(self, exodus_file, taper_width=1200e3):
        """
        Returns an edge taper that can be applied to the perturbations.
        This is Sine taper based on the distance
        to the edge of the domain.

        This requires the field inner_boundary to be present
        By default uses the bottom and the sides of the domain.
        Currently, this only applies to the Iran model.
        """
        from scipy.spatial import cKDTree
        with pyexodus.exodus(exodus_file, mode="r") as init_e:
            side_set_names = init_e.get_side_set_names()
            if "inner_boundary" not in side_set_names:
                raise Exception("Currently, inner_boundary is required")
            side_nodes = []
            for side_set in side_set_names:
                if side_set == "surface":
                    continue
                if side_set == "r1":
                    continue
                else:
                    idx = init_e.get_side_set_ids()[
                        side_set_names.index(side_set)]
                    _, nodes_side_set = init_e.get_side_set_node_list(idx)
                    side_nodes.extend(nodes_side_set)

            side_nodes = np.unique(side_nodes)  # remove duplicates
            side_nodes -= 1  # exodus is 1 based, python is not

            points = np.array(init_e.get_coords()).T
            side_points = points[side_nodes]

            # Setup KD tree to query distances to nearest edge point fast
            side_point_tree = cKDTree(side_points)

            dist, point_indices = side_point_tree.query(points, k=1)
            taper = np.ones_like(dist)
            # Compute sine taper
            taper[dist <= taper_width] = \
                (np.sin((dist[dist <= taper_width] /
                         taper_width) * np.pi - 0.5 * np.pi) + 1) / 2

            return taper
Esempio n. 19
0
    def write_exodus(self, filename, overwrite=True, title=None):  # pragma: no cover  # NoQa
        from pyexodus import exodus
        is_pyexodus = True

        # remove file, if it exists
        if overwrite:
            try:
                os.remove(filename)
            # if the file does not exist, do nothing
            except OSError:
                pass

        if title is None:
            title = filename.split('.')[0]

        e = exodus(filename, mode='w', title=title, array_type='numpy',
                   numDims=self.ndim, numNodes=self.npoint,
                   numElems=self.nelem, numBlocks=1, numNodeSets=0,
                   numSideSets=self.nside_sets)

        e.put_info_records(["%s = %s" % t for t in self.global_strings])

        if self.ndim == 2:
            e.put_coords(self.points[:, 0] * self.scale,
                         self.points[:, 1] * self.scale,
                         np.zeros(self.npoint))
        elif self.ndim == 3:
            e.put_coords(self.points[:, 0] * self.scale,
                         self.points[:, 1] * self.scale,
                         self.points[:, 2] * self.scale)

        name = elem.name[(self.ndim, self.nodes_per_element)]
        e.put_elem_blk_info(1, name, self.nelem, self.nodes_per_element, 0)

        if is_pyexodus:
            e.put_elem_connectivity(1, self.connectivity, shift_indices=1)
        # Memory intensive!
        else:  # pramga: no cover
            e.put_elem_connectivity(1, self.connectivity.ravel() + 1)

        # we store the variables in the results section of the exodus file,
        # hence need to define a time step
        e.put_time(1, 0.)

        # write global variables
        e.set_global_variable_number(self.nglobal_variables)
        for i, (name, data) in enumerate(sorted(self.global_variables,
                                                key=lambda x: x[0])):
            e.put_global_variable_name(name, i + 1)
            e.put_global_variable_value(name, 1, data)

        # write elemental fields
        e.set_element_variable_number(self.nelemental_fields)
        for i, (name, data) in enumerate(sorted(self.elemental_fields,
                                                key=lambda x: x[0])):
            e.put_element_variable_name(name, i + 1)
            e.put_element_variable_values(1, name, 1, data)

        # write nodal fields
        e.set_node_variable_number(self.nnodal_fields)
        for i, (name, data) in enumerate(sorted(self.nodal_fields,
                                                key=lambda x: x[0])):
            e.put_node_variable_name(name, i + 1)
            e.put_node_variable_values(name, 1, data)

        # write side sets
        for i, (name, elements, sides) in enumerate(
             sorted(self.side_sets, key=lambda x: x[0])):
            e.put_side_set_params(i + 1, elements.size, 0)
            e.put_side_set(i + 1, elements + 1, sides + 1)
            e.put_side_set_name(i + 1, name)

        e.close()