def test_spawn_location_1(self):
        """
        Base case: moving Node. 
        Also the prototype should follow the movement.
        This should be done automatically when calling MarbleEmitterNode.emit().
        Using a MarbleEmitterVariablePosition.
        """
        vel = torch.tensor([1.0])
        radius = 10
        eps = 10e-5
        prototype = Marble(ZERO, ZERO, ZERO, 0, None, None, 0, 0, 0, 0)
        emitter = MarbleEmitterVariablePosition(prototype,
                                                0,
                                                10,
                                                rel_prototype_pos=torch.tensor(
                                                    [radius + eps]))
        emitter_node = MarbleEmitterNode(ZERO,
                                         vel,
                                         ZERO,
                                         0,
                                         None,
                                         0,
                                         0,
                                         0,
                                         0,
                                         radius=radius,
                                         emitter=emitter)
        emitter_node.update_movement(1)

        self.assertTrue(check_close(emitter_node.pos, torch.tensor([1.0])))
        expected_marble_pos = torch.tensor([1.0]) + radius + eps
        self.assertTrue(
            check_close(emitter_node.emit().pos, expected_marble_pos))
    def test_spawn_location_2(self):
        """
        Base case: stationary Node.
        Using a normal MarbleEmitter.
        """
        vel = torch.tensor([1.0])
        radius = 10
        eps = 10e-5
        prototype = Marble(ZERO + radius + eps, ZERO, ZERO, 0, None, None, 0,
                           0, 0, 0)
        emitter = MarbleEmitter(prototype, 0, 10)
        emitter_node = MarbleEmitterNode(ZERO,
                                         vel,
                                         ZERO,
                                         0,
                                         None,
                                         0,
                                         0,
                                         0,
                                         0,
                                         radius=radius,
                                         emitter=emitter)

        self.assertTrue(check_close(emitter_node.pos, ZERO))
        self.assertTrue(check_close(emitter.emit().pos, ZERO + radius + eps))
Example #3
0
    def test_reset(self):
        # Node and Marble have some arbitrary nonzero initial motion vars.
        node = Node(torch.tensor([1.]), torch.tensor([2.]), torch.tensor([3.]),
                    4, NewtonianGravity(), 1, 1, 1, 1)
        marble = Marble(torch.tensor([1.1]), torch.tensor([2.2]),
                        torch.tensor([3.3]), 4.4, NewtonianGravity(), None)
        model = NenwinModel([node], [marble])
        model.make_timestep(10)
        model.make_timestep(10)
        model.make_timestep(10)

        # Verify that the motion variables have changed
        self.assertFalse(check_close(node.pos, node.init_pos))
        self.assertFalse(check_close(marble.vel, marble.init_vel))
        self.assertFalse(check_close(marble.acc, marble.init_acc))

        model.reset()

        # Now they should be the original values again.
        self.assertTrue(check_close(node.pos, node.init_pos))
        self.assertTrue(check_close(node.vel, node.init_vel))
        self.assertTrue(check_close(node.acc, node.init_acc))
        self.assertTrue(check_close(marble.pos, marble.init_pos))
        self.assertTrue(check_close(marble.vel, marble.init_vel))
        self.assertTrue(check_close(marble.acc, marble.init_acc))
Example #4
0
    def test_copy(self):
        pos = torch.tensor([-10, -100], dtype=torch.float)
        vel = torch.tensor([0, 0], dtype=torch.float)
        acc = torch.tensor([0, 0], dtype=torch.float)
        original = Particle(pos, vel, acc)
        copy = original.copy()

        self.assertFalse(copy is original)

        self.assertTrue(check_close(acc, copy.acc))
        self.assertTrue(check_close(vel, copy.vel))
        self.assertTrue(check_close(pos, copy.pos))
Example #5
0
    def test_movement_3(self):
        """
        Corner case: no vel and no acc => no movement.
        """
        pos = torch.tensor([-10, -100], dtype=torch.float)
        vel = torch.tensor([0, 0], dtype=torch.float)
        acc = torch.tensor([0, 0], dtype=torch.float)
        p = Particle(pos, vel, acc)
        for _ in range(100):
            p.update_movement(0.01)

        expected = runge_kutta_4_step(pos, vel, acc)
        self.assertTrue(check_close(acc, p.acc))
        self.assertTrue(check_close(vel, p.vel))
        self.assertTrue(check_close(pos, p.pos))
Example #6
0
    def test_movement_2(self):
        """
        Base case: deacceleration.
        """
        pos = torch.tensor([-10, -100], dtype=torch.float)
        vel = torch.tensor([100, 1000], dtype=torch.float)
        acc = torch.tensor([0, -91], dtype=torch.float)
        p = Particle(pos, vel, acc)
        for _ in range(100):
            p.update_movement(0.01)

        expected = runge_kutta_4_step(pos, vel, acc)
        self.assertTrue(check_close(expected[1], p.vel))
        self.assertTrue(check_close(expected[0], p.pos))
        # Should not have changed
        self.assertTrue(check_close(acc, p.acc))
 def test_output_1(self):
     """
     Base case: 3 Eater nodes with different eat counts.
     """
     marbles_eaten_per_node = [10, 20, 0]
     model = MockModel(marbles_eaten_per_node)
     result = self.output_reader.read_output(model)
     expected = np.array(marbles_eaten_per_node)
     self.assertTrue(check_close(result, expected))
 def test_output_2(self):
     """
     Corner case: no eater nodes in the model present.
     """
     marbles_eaten_per_node = []
     model = MockModel(marbles_eaten_per_node)
     result = self.output_reader.read_output(model)
     expected = np.array(marbles_eaten_per_node)
     self.assertTrue(check_close(result, expected))
Example #9
0
    def test_copy(self):
        """
        Copy should use the initial values for position, 
        velocity and acceleration.
        """
        pos = torch.tensor([-10, -100], dtype=torch.float)
        vel = torch.tensor([1, 10], dtype=torch.float)
        acc = torch.tensor([10, 1], dtype=torch.float)
        original = InitialValueParticle(pos, vel, acc)

        original.update_movement(time_passed=10)

        copy = original.copy()

        self.assertFalse(copy is original)
        self.assertTrue(check_close(acc, copy.acc))
        self.assertTrue(check_close(vel, copy.vel))
        self.assertTrue(check_close(pos, copy.pos))
Example #10
0
    def test_distance_1(self):
        """
        Base case: 2 nodes at different positions.
        """
        pos1 = np.array([1, 0, 0])
        pos2 = np.array([2, 0, 0])
        zero_vect = np.array([0, 0, 0])
        p1 = Particle(pos1, zero_vect, zero_vect)
        p2 = Particle(pos2, zero_vect, zero_vect)

        expected = 1

        self.assertTrue(check_close(distance(p1, p2), expected))
Example #11
0
    def test_output_4(self):
        """
        Base case: node close but not within eater, becomes pulled in.
        """
        zero = np.array([0])
        eater = MarbleEaterNode(zero, zero, zero, 100, self.attract_funct, 1,
                                10)
        marble = Marble(np.array([11]), zero, zero, 1, self.attract_funct,
                        None)
        model = NumMarblesEatenAsOutputModel([eater], 1, [marble])

        model.run(1)

        result = model._produce_outputs()
        expected = np.array([0])
        self.assertTrue(check_close(result, expected))

        model.run(10)

        result = model._produce_outputs()
        expected = np.array([1])
        self.assertTrue(check_close(result, expected))
Example #12
0
    def test_output_2(self):
        """
        Corner case: no eaternodes, empty array as output.
        """
        zero = np.array([0])
        marble = Marble(np.array([9]), zero, zero, 1, self.attract_funct, None)
        model = NumMarblesEatenAsOutputModel([], 1, [marble])

        model.run(1)

        result = model._produce_outputs()
        expected = np.array([])
        self.assertTrue(check_close(result, expected))
Example #13
0
    def test_distance_2(self):
        """
        Corner case: 2 nodes at same positions.
        """
        pos1 = np.array([9, 8, 70.5])
        pos2 = np.array([9, 8, 70.5])
        zero_vect = np.array([0, 0, 0])
        p1 = Particle(pos1, zero_vect, zero_vect)
        p2 = Particle(pos2, zero_vect, zero_vect)

        expected = 0

        self.assertTrue(check_close(distance(p1, p2), expected))
Example #14
0
 def test_copy(self):
     """
     Check if the copy has the same values as the original.
     Base case: original still has init values.
     """
     (prototype, delay, stored_mass, initial_time_passed, rel_prototype_pos,
      emitter) = self.set_up_full_emitter()
     copy = emitter.copy()
     self.assertIsInstance(copy, MarbleEmitterVariablePosition)
     self.assertAlmostEqual(copy.init_stored_mass, stored_mass)
     self.assertAlmostEqual(copy.init_time_passed, initial_time_passed)
     self.assertAlmostEqual(copy.delay, delay)
     self.assertTrue(check_close(copy.rel_prototype_pos, rel_prototype_pos))
     self.assertIs(copy.prototype.init_pos, prototype.init_pos)
Example #15
0
    def test_distance_3(self):
        """
        Corner case: 2 nodes at different position that differ 
        in multiple dimensions.
        """
        pos1 = np.array([1, 1, 1])
        pos2 = np.array([-1, -1, -1])
        zero_vect = np.array([0, 0, 0])
        p1 = Particle(pos1, zero_vect, zero_vect)
        p2 = Particle(pos2, zero_vect, zero_vect)

        expected = np.sqrt(3 * 2**2)

        self.assertTrue(check_close(distance(p1, p2), expected))
Example #16
0
    def test_output_1(self):
        """
        Base case: single marble created within radius of eater node,
        should become output after 1 step.
        """
        zero = np.array([0])
        eater = MarbleEaterNode(zero, zero, zero, 10, self.attract_funct, 1,
                                10)
        marble = Marble(np.array([9]), zero, zero, 1, self.attract_funct, None)
        model = NumMarblesEatenAsOutputModel([eater], 1, [marble])

        model.run(1)

        result = model._produce_outputs()
        expected = np.array([1])
        self.assertTrue(check_close(result, expected))
Example #17
0
    def test_copy_acc_with_grad(self):
        """
        Gradients of initial accelerations should be copied as well.
        """
        some_particle = setup_simple_particle()

        some_tensor = torch.tensor([4.0], requires_grad=True)
        loss = torch.sum(some_particle.acc + some_tensor)
        loss.backward()
        self.assertIsNotNone(some_particle.init_acc.grad)
        self.assertIsNotNone(some_tensor.grad)

        another_particle = some_particle.copy()
        self.assertTrue(
            check_close(some_particle.init_acc.grad,
                        another_particle.init_acc.grad))
Example #18
0
    def test_output_3(self):
        """
        Base case: single marble created outside radius of eater node,
        and not cominig close. Output should remain 0.
        """
        zero = np.array([0])
        eater = MarbleEaterNode(zero, zero, zero, 10, self.attract_funct, 1,
                                10)
        # Moving too fast to be pulled back.
        marble = Marble(np.array([11]), np.array([100]), zero, 1,
                        self.attract_funct, None)
        model = NumMarblesEatenAsOutputModel([eater], 1, [marble])

        model.run(1)

        result = model._produce_outputs()
        expected = np.array([0])
        self.assertTrue(check_close(result, expected))