Exemple #1
0
    def test_weighted_sum(self):
        """Tests weighted sum to make sure weights are implemented correctly"""

        fitness_params = {
            'goal_fos': 1.5,
            'critical_nodes': np.array([1]),
            'w_fos': 100,
            'w_mass': 1,
            'w_deflection': 10
        }
        f = FitnessFunction('weighted_sum', fitness_params)
        mass = 5
        deflection = np.array([[1, 0, 0, 0, 0, 0],
                               [np.sqrt(2), np.sqrt(2), 0, 0, 0, 0]])
        fos = np.array([.5, 5])
        t1 = Truss(0, 0, 0, 0)
        t1.mass = mass
        t1.deflection = deflection
        t1.fos = fos
        t1 = f(t1)
        self.assertAlmostEqual(t1.fitness_score, 125)

        t0 = Truss(0, 0, 0, 0)
        fitness_params['critical_nodes'] = np.array([])
        fos = np.array([])
        t0.mass = mass
        t0.deflection = deflection
        t0.fos = fos
        t0 = f(t0)
        self.assertAlmostEqual(t0.fitness_score, 185)
Exemple #2
0
    def test_sphere(self):
        """Tests to make sure min is where it should be."""

        x = np.zeros(10)
        y = np.ones(10)
        t0 = Truss(x, x, 0, 0)
        t1 = Truss(y, y, 0, 0)
        f = FitnessFunction('sphere', {})
        t0 = f(t0)
        t1 = f(t1)
        self.assertAlmostEqual(t0.fitness_score, 0)
        self.assertAlmostEqual(t1.fitness_score, 10)
Exemple #3
0
    def test_rosenbrock(self):
        """Tests to make sure min for rosenbrock function
        is where it should be.
        """

        x = np.zeros(11)
        y = np.ones(11)
        t0 = Truss(x, x, 0, 0)
        t1 = Truss(y, y, 0, 0)
        f = FitnessFunction('rosenbrock', {})
        t0 = f(t0)
        t1 = f(t1)
        self.assertAlmostEqual(t0.fitness_score, 5)
        self.assertAlmostEqual(t1.fitness_score, 0)
Exemple #4
0
    def testProgressBar(self):
        """Tests single progress bar for genalg.
        """
        user_spec_nodes = np.array([[]]).reshape(0, 3)

        nodes = np.array([[1, 2, 3], [2, 3, 4]])
        edges = np.array([[0, 1]])
        properties = np.array([[0, 3]])

        pop_size = 10
        population = [
            Truss(user_spec_nodes, nodes, edges, properties)
            for i in range(pop_size)
        ]

        for truss in population:
            truss.fitness_score = np.random.random()

        population.sort(key=lambda x: x.fitness_score)

        GA = GenAlg(config)

        GA.population = population
        progress_truss = False
        progress_fitness = False
        # dumb GA run
        num_generations = 20
        progress = ProgMon(progress_fitness, progress_truss, num_generations)
        # Loop over all generations:
        for current_gen in tqdm(range(num_generations)):
            progress.progress_monitor(current_gen, population)
            time.sleep(0.05)
            for truss in GA.population:
                truss.fitness_score = truss.fitness_score + 5.0
        return GA.population[0], GA.pop_progress
Exemple #5
0
    def test_axial_load_z(self):
        """Tests simple straight beam under axial forces"""

        p = 5000  # load in newtons
        L = 4  # length in meters
        matl = 1
        rand_nodes = np.array([]).reshape(0, 3)  # no random nodes
        user_spec_nodes = np.array([[0, 0, 0], [0, 0, L]])
        edges = np.array([[0, 1]])
        properties = np.array([matl])
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        dof = np.array([[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0,
                                             0]]).reshape(2, 6, 1)
        load = np.array([[0, 0, 0, 0, 0, 0], [0, 0, p, 0, 0,
                                              0]]).reshape(2, 6, 1)
        beam_dict = utilities.beam_file_parser('gastop-config/properties.csv')
        bdry = {'loads': load, 'fixtures': dof}
        evaluator = Evaluator('mat_struct_analysis_DSM', 'mass_basic',
                              'interference_ray_tracing', 'cost_calc', bdry,
                              beam_dict)
        evaluator(truss)
        A = beam_dict['x_section_area'][matl]
        E = beam_dict['elastic_modulus'][matl]
        sigma = p / A
        fos_true = beam_dict['yield_strength'][matl] / sigma
        strain = sigma / E
        deflection_true = np.array([[[0], [0], [0], [0], [0], [0]],
                                    [[0], [0], [strain * L], [0], [0], [0]]])

        np.testing.assert_almost_equal(truss.mass,
                                       A * L * beam_dict['density'][matl])
        np.testing.assert_array_almost_equal(truss.fos, fos_true)
        np.testing.assert_array_almost_equal(truss.deflection, deflection_true)
Exemple #6
0
    def test_duplicate_members(self):
        """Tests a truss with duplicate members between two nodes,
        to ensure those members are not counted"""

        p = 9000  # axial load in newtons
        f = 1750  # transverse load in newtons
        T = 72  # torsion in newton-meters
        L = .12  # length in meters
        matl = 4
        rand_nodes = np.array([]).reshape(0, 3)  # no random nodes
        user_spec_nodes = np.array([[0, 0, 0], [L, 0, 0]])
        edges = np.array([[0, 1], [0, 1]])
        properties = np.array([matl, matl])
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        dof = np.array([[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0,
                                             0]]).reshape(2, 6, 1)
        load = np.array([[0, 0, 0, 0, 0, 0], [p, -f, 0, -T, 0,
                                              0]]).reshape(2, 6, 1)
        beam_dict = utilities.beam_file_parser('gastop-config/properties.csv')
        bdry = {'loads': load, 'fixtures': dof}
        evaluator = Evaluator('mat_struct_analysis_DSM', 'mass_basic',
                              'blank_test', 'cost_calc', bdry, beam_dict)
        evaluator(truss)
        A = beam_dict['x_section_area'][matl]
        fos_true = 4.57

        np.testing.assert_almost_equal(truss.mass,
                                       A * L * beam_dict['density'][matl])
        np.testing.assert_array_almost_equal(truss.fos[0], fos_true, 2)
        np.testing.assert_almost_equal(truss.cost, L * beam_dict['cost'][matl])
Exemple #7
0
    def test_unconnected_node(self):
        """Tests truss with 3 nodes and 1 connection

        3rd node is not connected to the other two, and is not loaded or supported
        should return nonzero fos, as unconnected node is not loaded so is ignored
        """

        p = 10000  # load in newtons
        L = 4  # length in meters
        matl = 2
        rand_nodes = np.array([]).reshape(0, 3)  # no random nodes
        user_spec_nodes = np.array([[0, 0, 0], [L, 0, 0], [0, L, 0]])
        edges = np.array([[0, 1]])
        properties = np.array([matl])
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        dof = np.array([[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0]]).reshape(3, 6, 1)
        load = np.array([[0, 0, 0, 0, 0, 0], [p, 0, 0, 0, 0, 0],
                         [0, 0, 0, 0, 0, 0]]).reshape(3, 6, 1)
        beam_dict = utilities.beam_file_parser('gastop-config/properties.csv')
        bdry = {'loads': load, 'fixtures': dof}
        evaluator = Evaluator('mat_struct_analysis_DSM', 'mass_basic',
                              'blank_test', 'cost_calc', bdry, beam_dict)
        evaluator(truss)
        A = beam_dict['x_section_area'][matl]
        sigma = p / A
        fos_true = beam_dict['yield_strength'][matl] / sigma

        np.testing.assert_almost_equal(truss.mass,
                                       A * L * beam_dict['density'][matl])
        np.testing.assert_array_almost_equal(truss.fos, fos_true)
        np.testing.assert_almost_equal(truss.cost, L * beam_dict['cost'][matl])
        np.testing.assert_almost_equal(truss.cost, L * beam_dict['cost'][matl])
Exemple #8
0
    def test_unsupported_load(self):
        """Tests straight beam under axial forces with additional unsupported load

        Should return fos = 0, as stiffness matrix is singular
        """

        p = 50000  # load in newtons
        L = 10  # length in meters
        matl = 0
        rand_nodes = np.array([]).reshape(0, 3)  # no random nodes
        user_spec_nodes = np.array([[0, 0, 0], [L, 0, 0], [0, 0, L]])
        edges = np.array([[0, 1]])
        properties = np.array([matl])
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        dof = np.array([[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0],
                        [0, 0, 0, 0, 0, 0]]).reshape(3, 6, 1)
        load = np.array([[0, 0, 0, 0, 0, 0], [p, 0, 0, 0, 0, 0],
                         [p, 0, 0, 0, 0, 0]]).reshape(3, 6, 1)
        beam_dict = utilities.beam_file_parser('gastop-config/properties.csv')
        bdry = {'loads': load, 'fixtures': dof}
        evaluator = Evaluator('mat_struct_analysis_DSM', 'mass_basic',
                              'blank_test', 'cost_calc', bdry, beam_dict)
        evaluator(truss)
        fos_true = 0

        np.testing.assert_array_almost_equal(truss.fos, fos_true)
Exemple #9
0
    def test_combined_load(self):
        """Tests beam under combined loading

        Beam is fixed at one end, and loads applied at the other,
        creating bending moment, torsion and shear forces.
        From Shigley's Mechanical Engineering Design, 10th ed, pp 247-248
        """
        p = 9000  # axial load in newtons
        f = 1750  # transverse load in newtons
        T = 72  # torsion in newton-meters
        L = .12  # length in meters
        matl = 4
        rand_nodes = np.array([]).reshape(0, 3)  # no random nodes
        user_spec_nodes = np.array([[0, 0, 0], [L, 0, 0]])
        edges = np.array([[0, 1]])
        properties = np.array([matl])
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        dof = np.array([[1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0,
                                             0]]).reshape(2, 6, 1)
        load = np.array([[0, 0, 0, 0, 0, 0], [p, -f, 0, -T, 0,
                                              0]]).reshape(2, 6, 1)
        beam_dict = utilities.beam_file_parser('gastop-config/properties.csv')
        bdry = {'loads': load, 'fixtures': dof}
        evaluator = Evaluator('mat_struct_analysis_DSM', 'mass_basic',
                              'blank_test', 'cost_calc', bdry, beam_dict)
        evaluator(truss)
        A = beam_dict['x_section_area'][matl]

        fos_true = 4.57

        np.testing.assert_almost_equal(truss.mass,
                                       A * L * beam_dict['density'][matl])
        np.testing.assert_array_almost_equal(truss.fos, fos_true, 2)
        np.testing.assert_almost_equal(truss.cost, L * beam_dict['cost'][matl])
Exemple #10
0
    def generate_random(self):  # Dan
        '''Generates and returns new truss objects with random properties

        The random method first determines the desired ranges of all values
        that will be calculated. Then, random numbers for the node locations,
        connections, and properties are all determined with the numpy.random
        methods.

        Args:
            None

        Returns:
            (Truss object): Truss object with the newly determined values
        '''
        # Generates new random chromosomes with uniform distribution
        num_rand_nodes = self.random_params['num_rand_nodes']
        num_rand_edges = self.random_params['num_rand_edges']
        user_spec_nodes = self.random_params['user_spec_nodes']
        num_user_spec_nodes = user_spec_nodes.shape[0]
        domain = self.random_params['domain']
        # First, generate the new nodes:
        new_nodes = np.random.uniform(domain[0], domain[1],
                                      (num_rand_nodes, 3))

        # 2nd, generate the new edges between the nodes:
        new_edges = np.random.randint(num_rand_nodes + num_user_spec_nodes,
                                      size=(num_rand_edges, 2))

        new_properties = np.random.randint(
            self.random_params['num_material_options'], size=(num_rand_edges))

        return Truss(user_spec_nodes, new_nodes, new_edges, new_properties)
Exemple #11
0
    def load_state(dest_config='config.json',
                   dest_pop='population.json'):  # Cristian
        '''Loads the current population and config settings from JSON files.

        Args:
            dest_config (string): Path to config data file.
            dest_pop (string): Path to population data file.

        Returns:
            ga (GenAlg object)
        '''
        # Load config data
        with open(dest_config, 'r') as f:
            config_loaded = json.load(f)
        config = json.loads(config_loaded, object_hook=encoders.numpy_decoder)

        # Load population data
        with open(dest_pop, 'r') as f:
            pop_loaded = json.load(f)
        population = json.loads(pop_loaded, object_hook=encoders.numpy_decoder)
        population = (Truss(**dct) for dct in population)

        ga = GenAlg(config)
        ga.population = population
        return ga
Exemple #12
0
    def test_truss_print(self):
        """Prints a truss as formatted text"""

        user_spec_nodes = np.array([[-1, -1, 0], [-1, 1, 0]])
        rand_nodes = np.array([[1, 1, 0], [1, -1, 0], [0, 0, 1]])
        edges = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 4], [1, 4],
                          [2, 4], [3, 4]])
        properties = np.zeros(8)

        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        print(truss)
Exemple #13
0
    def test_truss_plot(self):
        """Plots a pyramidal truss with loads and deflections."""

        user_spec_nodes = np.array([[-1, -1, 0], [-1, 1, 0]])
        rand_nodes = np.array([[1, 1, 0], [1, -1, 0], [0, 0, 1]])
        edges = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 4], [1, 4],
                          [2, 4], [3, 4]])
        properties = np.zeros(8)
        loads = np.concatenate((np.zeros(
            (4, 6)), np.array([[-100, 0, -100, 0, 0, 0]])),
                               axis=0).reshape(5, 6, 1)
        fixtures = np.concatenate((np.ones((4, 6)), np.zeros((1, 6))),
                                  axis=0).reshape(5, 6, 1)
        load_scale = .005
        def_scale = 10
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        truss.deflection = np.concatenate((np.zeros(
            (4, 6)), np.array([[-.01, 0, -.01, 0, 0, 0]])),
                                          axis=0).reshape(5, 6, 1)
        domain = np.array([[-1.5, 1.5], [-1.5, 1.5], [0, 1.5]]).T
        truss.plot(domain, loads, fixtures, True, load_scale, def_scale)
Exemple #14
0
    def __call__(self, truss_1, truss_2):
        """Calls a crossover object on two trusses to combine them.

        Crossover object must have been instantiated specifying which
        methods to use.

        Args:
            truss_1 (Truss object): First truss to be combined.
            truss_2 (Truss object): Second truss to be combined.

        Returns:
            child_1, child_2 (Truss objects): Children trusses produced by crossover.

        """

        user_spec_nodes = self.params['user_spec_nodes']
        child_1 = Truss(user_spec_nodes, 0, 0, 0)
        child_2 = Truss(user_spec_nodes, 0, 0, 0)
        child_1.rand_nodes, child_2.rand_nodes = self.node_method(
            truss_1.rand_nodes, truss_2.rand_nodes,
            **self.params['node_crossover_params'])
        child_1.edges, child_2.edges = self.edge_method(
            truss_1.edges, truss_2.edges,
            **self.params['edge_crossover_params'])
        child_1.properties, child_2.properties = self.property_method(
            truss_1.properties, truss_2.properties,
            **self.params['property_crossover_params'])

        return child_1, child_2
Exemple #15
0
    def __call__(self, truss):
        """Calls a mutator object on a truss to change it.

        Mutator object must have been instantiated specifying which
        methods to use.

        Args:
            truss (Truss object): Truss to be mutated.

        Returns:
            child (Truss object): Child truss produced by mutation.

        """
        user_spec_nodes = self.params['user_spec_nodes']
        child = Truss(user_spec_nodes, 0, 0, 0)
        child.rand_nodes = self.node_method(
            truss.rand_nodes, **self.params['node_mutator_params'])
        child.edges = self.edge_method(truss.edges,
                                       **self.params['edge_mutator_params'])
        child.properties = self.property_method(
            truss.properties, **self.params['property_mutator_params'])

        return child
Exemple #16
0
    def testInvSqrRankProp(self):
        '''Tests the inverse_square_rank_probability method of Selector()
        '''
        nodes = np.array([[1, 2, 3], [2, 3, 4]])
        edges = np.array([[0, 1]])
        properties = np.array([[0, 3]])
        pop_size = int(1e3)
        population = [
            Truss(nodes, nodes, edges, properties) for i in range(pop_size)
        ]
        for truss in population:
            truss.fitness_score = random.random()

        population.sort(key=lambda x: x.fitness_score)
        # print([x.fitness_score for x in population])

        sel_params = {
            'method': 'inverse_square_rank_probability',
            'method_params': {}
        }
        selector = Selector(sel_params)

        num_parents = int(1e6)
        parents = selector(num_parents, population)

        unique, counts = np.unique(parents, return_counts=True)
        # unique_missing = [x for x in range(pop_size) if x not in unique]
        # counts = np.append(counts,np.zeros(len(unique_missing)))
        # counts = np.insert(counts,unique_missing,np.zeros(len(unique_missing)))
        # print(counts.size)
        distribution = counts / num_parents
        # print(distribution)

        true_distribution = 1 / np.sqrt(np.array(range(1, pop_size + 1)))
        true_sum = np.sum(true_distribution)
        true_distribution = true_distribution / true_sum
        # print(true_distribution)

        error = true_distribution - distribution
        max_err = np.amax(error)
        # print(max_err)

        # print(parents,parents.shape,parents.max())

        self.assertAlmostEqual(max_err / pop_size, 0, places=3)
        self.assertEqual(num_parents, len(parents))
Exemple #17
0
    def test_fixtures(self):
        """Tests applied loads with various dof fixed"""

        p = 1000  # load in newtons
        L = 1  # length in meters
        matl = 2
        rand_nodes = np.array([]).reshape(0, 3)  # no random nodes
        user_spec_nodes = np.array([[0, 1, 0], [L, 0, 0], [0, -1, 0]])
        edges = np.array([[0, 1], [2, 1]])
        properties = matl * np.ones((edges.shape[0])).astype(int)
        truss = Truss(user_spec_nodes, rand_nodes, edges, properties)
        dof = np.array([[1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0],
                        [1, 1, 1, 0, 0, 0]]).reshape(3, 6, 1)
        load = np.array([[0, 0, 0, 0, 0, 0], [0, 0, -p, 0, 0, 0],
                         [0, 0, 0, 0, 0, 0]]).reshape(3, 6, 1)
        beam_dict = utilities.beam_file_parser('gastop-config/properties.csv')
        bdry = {'loads': load, 'fixtures': dof}
        evaluator = Evaluator('mat_struct_analysis_DSM', 'mass_basic',
                              'blank_test', 'cost_calc', bdry, beam_dict)
        evaluator(truss)
Exemple #18
0
def load_progress_history(path_progress_history='progress_history.json'):
    '''Loads the population history (progress_history) from a JSON file.

    Args:
        path_progress_history (string): Path to progress_history data file.

    Returns:
        progress_history (dict): History of each generation, including generation
        number, fittest truss, etc.
    '''
    # Load progress_history data
    with open(path_progress_history, 'r') as f:
        progress_history_loaded = json.load(f)
    progress_history = json.loads(progress_history_loaded,
                                  object_hook=encoders.numpy_decoder)
    # Bundle truss dictionaries as Truss objects
    for gen in progress_history.keys():
        progress_history[gen]['Best Truss'] = Truss(
            **progress_history[gen]['Best Truss'])

    return progress_history
Exemple #19
0
    def testProgressPlotClass(self):
        """Tests fitness plot for progmon
        """
        user_spec_nodes = np.array([[]]).reshape(0, 3)
        nodes = np.array([[1, 2, 3], [2, 3, 4]])
        edges = np.array([[0, 1]])
        properties = np.array([[0, 3]])

        pop_size = 10
        population = [
            Truss(user_spec_nodes, nodes, edges, properties)
            for i in range(pop_size)
        ]

        for truss in population:
            truss.fitness_score = np.random.random()

        population.sort(key=lambda x: x.fitness_score)
        # print([x.fitness_score for x in population])

        GA = GenAlg(config)

        GA.population = population
        progress_fitness = True
        progress_truss = False
        num_generations = 20

        progress = ProgMon(progress_fitness, progress_truss, num_generations)
        #

        # Loop over all generations:
        for current_gen in range(num_generations):
            progress.progress_monitor(current_gen, population)
            for truss in GA.population:
                #truss.fos = np.random.random()
                truss.fitness_score = truss.fitness_score + 5.0
        # plt.show()  # sfr, keep plot from closing right after this completes, terminal will hang until this is closed
        return GA.population[0], GA.pop_progress
Exemple #20
0
    def testTournament(self):
        '''Tests the tournament method of Selector()
        '''
        nodes = np.array([[1, 2, 3], [2, 3, 4]])
        edges = np.array([[0, 1]])
        properties = np.array([[0, 3]])

        pop_size = int(1e2)
        population = [
            Truss(nodes, nodes, edges, properties) for i in range(pop_size)
        ]
        for truss in population:
            truss.fitness_score = random.random()

        population.sort(key=lambda x: x.fitness_score)
        # print([x.fitness_score for x in population])

        sel_params = {
            'method': 'tournament',
            'method_params': {
                'tourn_size': 25,
                'tourn_prob': 0.5
            }
        }
        selector = Selector(sel_params)

        num_parents = int(1e2)
        parents = selector(num_parents, population)

        unique, counts = np.unique(parents, return_counts=True)
        distribution = counts / num_parents
        # print(distribution)

        # print(parents,parents.shape,parents.max())

        self.assertEqual(num_parents, len(parents))
        self.assertTrue(parents.max() < pop_size)