Example #1
0
def test_actuator_force_can_be_used(square_lattice: Lattice):
    """make sure force-based protocol can be called"""
    actuator = Actuator(lattice=square_lattice,
                        frozen_nodes=[2, 3],
                        input_nodes=[0],
                        input_vectors=np.array([[0.1, 0.2]]),
                        output_nodes=[1],
                        output_vectors=np.array([
                            [0.3, 0.4],
                        ]),
                        method="force")
    actuator.act()
    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 = EdgeInfoLattice(
            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
Example #4
0
def test_actuator_frozen_x_nodes(square_lattice):
    """make sure that we can add x-only contraints"""
    actuator = Actuator(
        lattice=square_lattice,
        frozen_nodes=[3],
        frozen_x_nodes=[2],
        input_nodes=[0],
        input_vectors=np.array([[-0.5, 0]]),
        output_nodes=[1],
        output_vectors=np.array([[-1, 0]]),
    )
    actuator.act()
    # grab x and y of semifrozen nodes
    x_displaced = actuator._relax_params["X"][2]
    y_displaced = actuator._relax_params["Y"][2]
    assert x_displaced == -1 and y_displaced != -1
Example #5
0
def test_actuator_rescale_efficiency_fails(square_lattice: Lattice):
    """make sure we can't use rescale efficiency when norms are not constant"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(lattice=square_lattice,
                            frozen_nodes=[3],
                            input_nodes=[0, 2],
                            input_vectors=np.array([[0.1, 0.1], [0.2, 0.2]]),
                            output_nodes=[1],
                            output_vectors=np.array([[0.3, 0.4]]),
                            rescale_efficiency=True)
Example #6
0
def test_actuator_nodes_unique(square_lattice: Lattice):
    """make sure we cannot pass non-unique lists of nodes"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(
            lattice=square_lattice,
            frozen_nodes=[0, 1],
            input_nodes=[1, 2, 1],
            output_nodes=[2, 0],
            input_vectors=np.array([[1, 1]]),
            output_vectors=np.array([[1, 1]]),
        )
Example #7
0
def test_actuator_nodes_overlap_input_output(square_lattice: Lattice):
    """make sure we cannot pass overlapping lists between input output"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(
            lattice=square_lattice,
            frozen_nodes=[2, 3],
            input_nodes=[0],
            input_vectors=np.array([[0.1, 0.2]]),
            output_nodes=[0],
            output_vectors=np.array([[0.3, 0.4]]),
        )
Example #8
0
def test_actuator_no_duplicates_in_input(square_lattice: Lattice):
    """make sure we cannot pass duplicated nodes to input"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(
            lattice=square_lattice,
            frozen_nodes=[2, 3],
            input_nodes=[0, 0],
            input_vectors=np.array([[0.1, 0.2], [0.1, 0.2]]),
            output_nodes=[1],
            output_vectors=np.array([[0.3, 0.4]]),
        )
Example #9
0
def square_actuator_force(square_lattice: Lattice):
    """a actuator for the simple square"""
    lattice = square_lattice
    actuator = Actuator(lattice=lattice,
                        frozen_nodes=[2, 3],
                        input_nodes=[0],
                        input_vectors=np.array([[0.1, 0.2]]),
                        output_nodes=[1],
                        output_vectors=np.array([[0.3, 0.4]]),
                        method="force")
    return actuator
Example #10
0
def test_actuator_nodes_sizes_input(square_lattice: Lattice):
    """make sure we raise error when input sizes dont match"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(
            lattice=square_lattice,
            frozen_nodes=[0, 1],
            input_nodes=[2],
            output_nodes=[3],
            input_vectors=np.array([[1, 1], [1, 1]]),
            output_vectors=np.array([[1, 1]]),
        )
Example #11
0
def test_actuator_nodes_exist(square_lattice: Lattice):
    """make sure we cannot pass inexistent nodes"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(
            lattice=square_lattice,
            frozen_nodes=[0, 5, 8],
            input_nodes=[1],
            output_nodes=[2, 4],
            input_vectors=np.array([[1, 1]]),
            output_vectors=np.array([[1, 1]]),
        )
Example #12
0
def test_actuator_frozen_overlaps(square_lattice):
    """make sure that we cannot pass overlapping lists of frozen nodes"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(
            lattice=square_lattice,
            frozen_nodes=[3, 2],
            frozen_x_nodes=[2],
            input_nodes=[0],
            input_vectors=np.array([[-0.5, 0]]),
            output_nodes=[1],
            output_vectors=np.array([[-1, 0]]),
        )
Example #13
0
def test_actuator_unkown_protocols(square_lattice: Lattice):
    """make sure cannot use unkown protocols"""
    with pytest.raises(RuntimeError):
        actuator = Actuator(lattice=square_lattice,
                            frozen_nodes=[2, 3],
                            input_nodes=[0],
                            input_vectors=np.array([[0.1, 0.2]]),
                            output_nodes=[1],
                            output_vectors=np.array([
                                [0.3, 0.4],
                            ]),
                            method="unknown")
Example #14
0
def test_actuator_get_efficiency_displacement(square_lattice: Lattice):
    """make sure we correctly compute efficiencies
    for the displacement case (with just one vector)
    """
    for _ in range(100):
        for rescale_efficiency in [True, False]:
            # set a specific displacement
            disp_x = np.random.uniform(-2, 2)
            disp_y = np.random.uniform(-2, 2)
            # set a specific output
            out_x = np.random.uniform(-2, 2)
            out_y = np.random.uniform(-2, 2)
            # set a specific input
            inp_x = np.random.uniform(-2, 2)
            inp_y = np.random.uniform(-2, 2)
            # setup the actuator
            actuator = Actuator(lattice=square_lattice,
                                frozen_nodes=[2, 3],
                                input_nodes=[0],
                                input_vectors=np.array([[inp_x, inp_y]]),
                                output_nodes=[1],
                                output_vectors=np.array([[out_x, out_y]]),
                                rescale_efficiency=rescale_efficiency)
            # move the output node by hand
            actuator._relax_params["X"][actuator.output_nodes] = -1 + disp_x
            actuator._relax_params["Y"][actuator.output_nodes] = 1 + disp_y
            # compute the efficiency by hand
            numerator = disp_x * out_x + disp_y * out_y
            denominator = np.sqrt(out_x**2 + out_y**2)
            projection_length = numerator / denominator
            input_length = np.sqrt(inp_x**2 + inp_y**2)
            if rescale_efficiency:
                efficiency_by_hand = projection_length / input_length
            else:
                efficiency_by_hand = projection_length
            # compute with the actuators method
            efficiency_by_code = actuator._get_efficiency()
            # compare
            assert np.isclose(efficiency_by_code, efficiency_by_hand)
Example #15
0
def square_actuator(square_lattice):
    """actuator for the simple square"""
    lattice = square_lattice
    actuator = Actuator(
        lattice=lattice,
        frozen_nodes=[],
        input_nodes=[0],
        input_vectors=np.array([
            [0.1, 0.2]
        ]),
        output_nodes=[1],
        output_vectors=np.array([
            [0.3, 0.4]
        ]),
    )
    return actuator
Example #16
0
def test_metropolis_(square_lattice: Lattice):
    """test that metropolis raises error if no edges can be removed"""
    lattice = square_lattice
    actuator = Actuator(
        lattice=lattice,
        input_nodes=[0],
        output_nodes=[1],
        frozen_nodes=[2, 3],
        input_vectors=np.array([
            [0.1, 0.2]
        ]),
        output_vectors=np.array([
            [0.3, 0.4]
        ]),
    )
    with pytest.raises(RuntimeError):
        metropolis = Metropolis(actuator)
Example #17
0
def test_metropolis_max_iter_early_stop(max_iter, stop_at, square_lattice):
    """test that we stop at the correct value of maxiter"""
    lattice = square_lattice
    actuator = Actuator(
        lattice=lattice,
        frozen_nodes=[],
        input_nodes=[0],
        input_vectors=np.array([
            [0.1, 0.2]
        ]),
        output_nodes=[1],
        output_vectors=np.array([
            [0.3, 0.4]
        ]),
        max_iter=max_iter
    )
    metropolis = Metropolis(actuator=actuator)
    metropolis.run(
        temperature=1,
        num_steps=100
    )
    assert metropolis.history["relax_internal_steps"][-1] == stop_at
Example #18
0
def test_metropolis_is_valid_flag(square_lattice):
    """test that if max_iter is reached then is_valid
    is set to False"""
    lattice = square_lattice
    actuator = Actuator(
        lattice=lattice,
        frozen_nodes=[],
        input_nodes=[0],
        input_vectors=np.array([
            [0.1, 0.2]
        ]),
        output_nodes=[1],
        output_vectors=np.array([
            [0.3, 0.4]
        ]),
        max_iter=10
    )
    metropolis = Metropolis(actuator=actuator)
    metropolis.run(
        temperature=1,
        num_steps=100
    )
    assert not metropolis.is_valid
    def calculate_simulation(self):
        nodes_pos, edges_indices, edges_thickness, _ = self.extract_node_edge_info()

        lattice = EdgeInfoLattice(
            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
        )

        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
Example #21
0
# measure output at top-left nodes along -x direction
output_nodes = [68, 69, 70, 71]
output_vectors = np.array([
    [-1, 0],
    [-1, 0],
    [-1, 0],
    [-1, 0],
])

# freeze the bottomn layer
frozen_nodes = [1, 3, 5, 7, 9, 11, 13, 15]

# construct the actuator
actuator = Actuator(lattice=lattice,
                    input_nodes=input_nodes,
                    input_vectors=input_vectors,
                    output_nodes=output_nodes,
                    output_vectors=output_vectors,
                    frozen_nodes=frozen_nodes)

print("initial efficiency", actuator.efficiency)

metropolis = Metropolis(actuator=actuator)
metropolis.run(initial_temperature=0.1, final_temperature=0, num_steps=500)

print("final efficiency", actuator.efficiency)
# final efficiency 2.8265941145286715

history_df = pd.DataFrame(metropolis.history)
"""
# 記録やOVITOを用いた可視化用
history_df.to_xlsx("/path/MC_history.xlsx")
Example #22
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