예제 #1
0
def square_lattice():
    """a simple square with one diagonal"""
    nodes_positions = np.array([
        [1, 1],
        [-1, 1],
        [-1, -1],
        [1, -1]
    ]).astype(float)
    edges_indices = np.array([
        [0, 1],
        [1, 2],
        [0, 2],
        [2, 3],
        [3, 0]
    ]).astype(int)

    # create lattice
    lattice = Lattice(
        nodes_positions=nodes_positions,
        edges_indices=edges_indices,
        linear_stiffness=1,
        angular_stiffness=1
    )
    # activate all edges
    for edge in lattice._possible_edges:
        lattice.flip_edge(edge)

    return lattice
예제 #2
0
def test_lattice_remove_edge(lattice: Lattice):
    """test that we can remove edges"""
    for edge in lattice._possible_edges:
        lattice._add_edge(edge)
    for edge in lattice._possible_edges:
        lattice._remove_edge(edge)
        assert edge not in lattice.edges
    def render(self, save_path="image.png"):
        dir_name = os.path.dirname(save_path)
        if not os.path.exists(dir_name):
            os.makedirs(dir_name)

        nodes_pos, edges_indices, edges_thickness, _ = self.extract_node_edge_info()

        lattice = Lattice(
            nodes_positions=nodes_pos,
            edges_indices=edges_indices,
            edges_thickness=edges_thickness,
            linear_stiffness=LINEAR_STIFFNESS,
            angular_stiffness=ANGULAR_STIFFNESS
        )

        for edge in lattice._possible_edges:
            lattice.flip_edge(edge)

        actuator = Actuator(
            lattice=lattice,
            input_nodes=self.input_nodes,
            input_vectors=self.input_vectors,
            output_nodes=self.output_nodes,
            output_vectors=self.output_vectors,
            frozen_nodes=self.frozen_nodes
        )
        show_actuator(actuator, save_path=save_path)
def _load_crane_displacement(solver_tol=1e-5) -> Actuator:
    input_lammps_file = Path(__file__).parent / \
        "data/crane/crane_initial_config.lammps"

    params = read_lammps(input_lammps_file)
    nodes_postions = params["nodes_positions"]
    edges_indices = params["edges_indices"]
    input_nodes = params["input_nodes"]
    output_nodes = params["output_nodes"]
    frozen_nodes = params["frozen_nodes"]

    lattice = Lattice(
        nodes_positions=nodes_postions,
        edges_indices=edges_indices,
        linear_stiffness=10,
        angular_stiffness=0.2,
    )
    for edge in lattice._possible_edges:
        lattice.flip_edge(edge)

    # input and output vectors
    input_vectors = np.array([[0, -np.sqrt(3) / 4] for _ in input_nodes])

    output_vectors = np.array([[-1, 0] for _ in output_nodes])

    actuator = Actuator(lattice=lattice,
                        input_nodes=input_nodes,
                        output_nodes=output_nodes,
                        frozen_nodes=frozen_nodes,
                        input_vectors=input_vectors,
                        output_vectors=output_vectors,
                        max_force=solver_tol,
                        method="displacement")
    return actuator
예제 #5
0
def test_lattice_flip_edge(lattice: Lattice):
    """test that we can flip edges

    Flipping an edge means adding it if it is not present
    and removing it if it is present
    """
    for edge in lattice.edges:
        lattice.flip_edge(edge)
        assert edge in lattice.edges
    for edge in lattice.edges:
        lattice.flip_edge(edge)
        assert edge not in lattice.edges
예제 #6
0
def lattice() -> Lattice:
    """fixture to create a simple dummy square"""
    nodes_positions = np.array([
        [1, 1],
        [-1, 1],
        [-1, -1],
        [1, -1],
    ])
    edges_indices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])
    lattice = Lattice(nodes_positions=nodes_positions,
                      edges_indices=edges_indices,
                      linear_stiffness=0.1,
                      angular_stiffness=0.1)
    return lattice
예제 #7
0
def test_lattice_fails_wrong_z():
    """make sure we raise an error when passing wrong z coordinates"""
    nodes_positions = np.array([
        [1, 1, 0],
        [-1, 1, 0],
        [-1, -1, 0],
        [1, -1, .2],  # z is not constant
    ])
    edges_indices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])
    with pytest.raises(NotImplementedError):
        lattice = Lattice(nodes_positions=nodes_positions,
                          edges_indices=edges_indices,
                          linear_stiffness=0.1,
                          angular_stiffness=0.1)
예제 #8
0
def test_lattice_fails_wrong_dimension_nodes():
    """make sure we raise an error when passing nodes with wrong number of dimensions"""
    nodes_positions = np.array([
        [0, 0, 0, 1, 1],
        [0, 0, 0, -1, 1],
        [0, 0, 0, -1, -1],
        [0, 0, 0, 1, -1],
    ])
    edges_indices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])
    with pytest.raises(RuntimeError):
        lattice = Lattice(nodes_positions=nodes_positions,
                          edges_indices=edges_indices,
                          linear_stiffness=0.1,
                          angular_stiffness=0.1)
예제 #9
0
def test_lattice_fails_nonunique_nodes():
    """make sure we raise an error when passing nonunique nodes"""
    nodes_positions = np.array([
        [1, 1],
        [1, 1],  # repeated node here
        [-1, -1],
        [1, -1],
    ])
    edges_indices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])
    with pytest.raises(RuntimeError):
        lattice = Lattice(nodes_positions=nodes_positions,
                          edges_indices=edges_indices,
                          linear_stiffness=0.1,
                          angular_stiffness=0.1)
    def calculate_simulation(self):
        nodes_pos, edges_indices, edges_thickness, _ = self.extract_node_edge_info()

        lattice = Lattice(
            nodes_positions=nodes_pos,
            edges_indices=edges_indices,
            edges_thickness=MAX_EDGE_THICKNESS * edges_thickness,
            linear_stiffness=LINEAR_STIFFNESS,
            angular_stiffness=ANGULAR_STIFFNESS
        )

        for edge in lattice._possible_edges:
            lattice.flip_edge(edge)

        actuator = Actuator(
            lattice=lattice,
            input_nodes=self.input_nodes,
            input_vectors=self.input_vectors,
            output_nodes=self.output_nodes,
            output_vectors=self.output_vectors,
            frozen_nodes=self.frozen_nodes
        )

        return actuator.efficiency
def _load_crane_force(solver_tol=1e-5) -> Actuator:
    path_to_initial_config = Path(__file__).parent / \
        "data/crane/crane_initial_config.lammps"

    params = read_lammps(path_to_initial_config)
    nodes_postions = params["nodes_positions"]
    edges_indices = params["edges_indices"]
    input_nodes = params["input_nodes"]
    output_nodes = params["output_nodes"]
    frozen_nodes = params["frozen_nodes"]

    lattice = Lattice(
        nodes_positions=nodes_postions,
        edges_indices=edges_indices,
        linear_stiffness=10,
        angular_stiffness=0.2,
    )
    for edge in lattice._possible_edges:
        lattice.flip_edge(edge)

    # input and output vectors
    input_vectors = np.array([[0, -0.0015] for _ in input_nodes])

    output_vectors = np.array([[2, 0] for _ in output_nodes])

    actuator = Actuator(lattice=lattice,
                        input_nodes=input_nodes,
                        output_nodes=output_nodes,
                        frozen_nodes=frozen_nodes,
                        input_vectors=input_vectors,
                        output_vectors=output_vectors,
                        max_force=solver_tol,
                        method="force",
                        output_spring_stiffness=0.001,
                        efficiency_agg_fun=np.sum)
    return actuator
예제 #12
0
def test_lattice__generate_possible_edges(lattice: Lattice):
    """test that edges are added correctly at init"""
    nodes_positions = np.array([
        [1, 1],
        [-1, 1],
        [-1, -1],
        [1, -1],
    ])
    edges_indices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])
    lattice = Lattice(nodes_positions=nodes_positions,
                      edges_indices=edges_indices,
                      linear_stiffness=0.1,
                      angular_stiffness=0.1)
    for edge, (i, j) in zip(lattice.edges, edges_indices):
        u, v = edge._nodes
        assert i == u.label
        assert j == v.label
예제 #13
0
def test_lattice__add_nodes():
    """make sure nodes are correctly added at init"""
    nodes_positions = np.array([
        [1, 1],
        [-1, 1],
        [-1, -1],
        [1, -1],
    ])
    edges_indices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])
    lattice = Lattice(nodes_positions=nodes_positions,
                      edges_indices=edges_indices,
                      linear_stiffness=0.1,
                      angular_stiffness=0.1)
    assert len(lattice.nodes) == len(nodes_positions)
    for node, (x, y) in zip(lattice.nodes, nodes_positions):
        assert x == node.x
        assert y == node.y
예제 #14
0
def test_lattice_fails_edges_not_in_range_down():
    """make sure we raise an error when trying
    to instantiate with negative indices"""
    nodes_positions = np.array([
        [1, 1],
        [-1, 1],
        [-1, -1],
        [1, -1],
    ])
    edges_indices = np.array([
        [0, 1],
        [1, 2],
        [2, -5],  # wrong index here
        [3, 0],
        [0, 2]
    ])
    with pytest.raises(RuntimeError):
        lattice = Lattice(nodes_positions=nodes_positions,
                          edges_indices=edges_indices,
                          linear_stiffness=0.1,
                          angular_stiffness=0.1)
예제 #15
0
def test_lattice_add_edge(lattice: Lattice):
    """test that we can add edges"""
    for edge in lattice._possible_edges:
        lattice._add_edge(edge)
        assert edge in lattice.edges
예제 #16
0
def square_lattice_to_relax(request):
    """
    Provide a square with its top-right vertex
    perturbed from its resting position.
    """
    # create lattice
    nodes_positions = np.array([[1, 1], [-1, 1], [-1, -1], [1,
                                                            -1]]).astype(float)
    edges_indices = np.array([[0, 1], [1, 2], [0, 2], [2, 3], [3,
                                                               0]]).astype(int)
    lattice = Lattice(nodes_positions=nodes_positions,
                      edges_indices=edges_indices,
                      linear_stiffness=request.param[2],
                      angular_stiffness=request.param[3])
    # activate all edges
    for edge in lattice._possible_edges:
        lattice.flip_edge(edge)

    ##
    # parameters for relax
    ##
    num_nodes = 4
    frozen = np.array([0, 1, 1, 1]).astype(np.intc)
    # input
    target_in = np.array([1]).astype(np.intc)
    Xin = np.array([0.])
    Yin = np.array([0.])
    Zin = np.array([0.])
    Nin = np.intc(1)
    # output
    target_out = np.array([1]).astype(np.intc)
    Xout = np.array([1.])
    Yout = np.array([1.])
    Zout = np.array([0.])
    kout = 1.
    Nout = np.intc(1)
    # other
    epot = np.array([0])
    fmax = np.array([1e-5])
    method = np.intc(0)
    enforce2D = np.intc(1)
    error = np.array([0]).astype(np.intc)
    step_relax = np.array([10000]).astype(np.intc)

    # parameters that depend on the lattice
    params_internal = _get_params_from_lattice(lattice)
    # parameters that depend on the actuator
    params_external = {
        "frozen": frozen,
        "target_in": target_in,
        "Xin": Xin,
        "Yin": Yin,
        "Zin": Zin,
        "Nin": Nin,
        "target_out": target_out,
        "Xout": Xout,
        "Yout": Yout,
        "Zout": Zout,
        "Nout": Nout,
        "kout": kout,
        "epot": epot,
        "fmax": fmax,
        "method": method,
        "enforce2D": enforce2D,
        "error": error,
        "step_relax": step_relax
    }
    # all params
    params = {**params_internal, **params_external}

    # displace the top-right node
    params["X"][0] = request.param[0]
    params["Y"][0] = request.param[1]

    return params
예제 #17
0
    [79, 81],
    [80, 81],
    [80, 82],
    [81, 83],
    [81, 82],
    [82, 83],
    [82, 84],
    [83, 84],
])

edges_thickness = np.ones(len(edges_indices))

# construct the lattice
lattice = Lattice(nodes_positions=nodes_positions,
                  edges_indices=edges_indices,
                  edges_thickness=edges_thickness,
                  linear_stiffness=10,
                  angular_stiffness=0.2)

# 最初に全ての接続可能なエッジすべてにエッジを存在させる
for edge in lattice._possible_edges:
    lattice.flip_edge(edge)

# input displacement is 0.1 units in -y direction
# applied to top-right nodes
input_nodes = [81, 82, 83, 84]
input_vectors = np.array([[0., -0.1], [0., -0.1], [0., -0.1], [0., -0.1]])

# measure output at top-left nodes along -x direction
output_nodes = [68, 69, 70, 71]
output_vectors = np.array([
예제 #18
0
def load_crane_scaling(
    size: int = 8,
    displacement_fraction: float = 0.01,
    solver_tol: float = 1e-5,
) -> Actuator:
    """
    Load crane actuator for scaling analysis.

    Offers a set of initial configs on a regular
    lattice of increasing size and preconfigured
    input/output vectors, suitable for scaling
    analysis.

    Parameters
    ----------
    size : int, optional
        Number of nodes of side of lattice, by default 8
    solver_tol : float, optional
        Tolerance (max force) in FIRE algorithm, by default 1e-5
    displacement_fraction : float, optional
        Set input displacement to a fixed fraction of the length
        of the lattice in the y direction, by default 0.01.

    Returns
    -------
    : Actuator
        Preconfigured crane actuator.
    """
    # make sure size is available
    if size not in AVAILABLE_CRANE_SIZES:
        raise RuntimeError(
            f"Size {size} is not available. Available sizes are", AVAILABLE_CRANE_SIZES)
    path_to_initial_config = Path(__file__).parent / \
        f"data/crane_scaling/conf{size}.data"
    params = read_lammps(path_to_initial_config)
    nodes_postions = params["nodes_positions"]
    edges_indices = params["edges_indices"]

    # define input, output and frozen nodes
    xs, ys, _ = nodes_postions.T
    frozen_nodes = [
        i for i, y in enumerate(ys)
        if y == min(ys)
    ]
    input_nodes = [
        i for i, (x, y) in enumerate(zip(xs, ys))
        if
        (x > min(xs) + 0.8 * (max(xs) - min(xs))) and
        (y > min(ys) + 0.8 * (max(ys) - min(ys)))
    ]
    output_nodes = [
        i for i, (x, y) in enumerate(zip(xs, ys))
        if
        (x < min(xs) + 0.2 * (max(xs) - min(xs))) and
        (y > min(ys) + 0.8 * (max(ys) - min(ys)))
    ]
    # input and output vectors
    # displacement is 1% of y range
    input_vectors = np.array([
        [0, -displacement_fraction * (max(ys) - min(ys))]
        for _ in input_nodes
    ])

    output_vectors = np.array([
        [-1, 0]
        for _ in output_nodes
    ])

    lattice = Lattice(
        nodes_positions=nodes_postions,
        edges_indices=edges_indices,
        linear_stiffness=10,
        angular_stiffness=0.2,
    )
    for edge in lattice._possible_edges:
        lattice.flip_edge(edge)

    actuator = Actuator(
        lattice=lattice,
        input_nodes=input_nodes,
        output_nodes=output_nodes,
        frozen_nodes=frozen_nodes,
        input_vectors=input_vectors,
        output_vectors=output_vectors,
        max_force=solver_tol,
        method="displacement",
    )
    return actuator