示例#1
0
    def setUp(self): 
        self.prob = Problem()
        self.prob.root = SellarDerivatives()
        self.prob.driver = KonaOptimizer()
        self.driver = driver = self.prob.driver

        # need to give driver a pointer to problem since I'm not always going to run it
        # which is where it would normally get that pointer
        self.driver.problem = self.prob

        driver.add_desvar('z', lower=np.array([-10.0, 0.0]),
                          upper=np.array([10.0, 10.0]))
        driver.add_desvar('x', lower=0.0, upper=10.0)
        driver.add_objective('obj')
        driver.add_constraint('con1', upper=0.0)
        driver.add_constraint('con2', upper=0.0)

        # not part of sellar, but just need to have some of these for the tests
        self.prob.root.add('con_cmp3', ExecComp('con3 = 2*x - y1'), promotes=['*'])
        driver.add_constraint('con3', equals=0)
        self.prob.root.add('con_cmp4', ExecComp('con4 = 2*x - y1'), promotes=['*'])
        driver.add_constraint('con4', lower=0)

        self.prob.setup(check=False)

        # allocate memory like a kona-memory would do
        self.memory_allocator = Allocator(3,2,1,1,2,3,3)
        self.primals = self.memory_allocator.alloc_primal(3)
        self.states = self.memory_allocator.alloc_state(3)
        self.duals = self.memory_allocator.alloc_dual(3)
示例#2
0
class TestKonaSolver(unittest.TestCase): 

    def setUp(self): 
        self.prob = Problem()
        self.prob.root = SellarDerivatives()
        self.prob.driver = KonaOptimizer()
        self.driver = driver = self.prob.driver

        # need to give driver a pointer to problem since I'm not always going to run it
        # which is where it would normally get that pointer
        self.driver.problem = self.prob

        driver.add_desvar('z', lower=np.array([-10.0, 0.0]),
                          upper=np.array([10.0, 10.0]))
        driver.add_desvar('x', lower=0.0, upper=10.0)
        driver.add_objective('obj')
        driver.add_constraint('con1', upper=0.0)
        driver.add_constraint('con2', upper=0.0)

        # not part of sellar, but just need to have some of these for the tests
        self.prob.root.add('con_cmp3', ExecComp('con3 = 2*x - y1'), promotes=['*'])
        driver.add_constraint('con3', equals=0)
        self.prob.root.add('con_cmp4', ExecComp('con4 = 2*x - y1'), promotes=['*'])
        driver.add_constraint('con4', lower=0)

        self.prob.setup(check=False)

        # allocate memory like a kona-memory would do
        self.memory_allocator = Allocator(3,2,1,1,2,3,3)
        self.primals = self.memory_allocator.alloc_primal(3)
        self.states = self.memory_allocator.alloc_state(3)
        self.duals = self.memory_allocator.alloc_dual(3)

    def test_solver_init_design(self): 
        init_vec = self.primals[0] # pull a vector out of kona memory

        self.driver.init_design(init_vec)

        for name, idx in self.driver.primal_vars:
            assert_rel_error(self, init_vec.data[idx[0]:idx[1]], self.prob[name], 1e-10)

    def test_solver_eval_obj(self): 

        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1.111, 12.111, 13.111])
        at_state.data = np.array([2.511, 3.11])

        obj = self.driver.eval_obj(at_des, at_state)
        # make sure that the state variables in the u-vec didn't get changed
        assert_rel_error(self, self.prob['y1'], 2.511, 1e-10)
        assert_rel_error(self, self.prob['y2'], 3.11, 1e-10)

        assert_rel_error(self, obj, 1.111**2 + 13.111 + 2.511 + np.exp(-3.11), 1e-5)

    def test_solver_eval_constraints(self): 

        at_des = self.primals[0]
        at_state = self.states[0]
        store_here = self.duals[0]

        at_des.data = np.array([1.111, 12.111, 13.111])
        at_state.data = np.array([2.511, 3.11])

        self.driver.eval_constraints(at_des, at_state, store_here)
        # make sure that the state variables in the u-vec didn't get changed
        assert_rel_error(self, self.prob['y1'], 2.511, 1e-10)
        assert_rel_error(self, self.prob['y2'], 3.11, 1e-10)

        # KONA Wants positive-valid constraints, so have to negate openmdao! 
        c1 = 3.16 - self.prob['y1'] # y1 > 3.16 -- violated, so negative! 
        c2 = self.prob['y2'] - 24.0 # y2 < 24  -- met, so positive! 

        # print(store_here.ieq_ub_data, np.array([-c1,-c2]))
        assert_rel_error(self, store_here.ieq_ub_data, np.array([-c1,-c2]), 1e-5)
        assert_rel_error(self, store_here.eq_data, np.array([-.289]), 1e-5)
        assert_rel_error(self, store_here.ieq_lb_data, np.array([-.289]), 1e-5)

        assert_rel_error(self, store_here.primal_lb_data, np.array([1.111, 22.111, 13.111]), 1e-5)
        assert_rel_error(self, store_here.primal_ub_data, np.array([8.889, -2.111, -3.111]), 1e-5)

    def test_solver_eval_residual(self): 

        at_des = self.primals[0]
        at_state = self.states[0]
        store_here = self.states[1]

        at_des.data = np.array([1.111, 12.111, 13.111])
        at_state.data = np.array([2.511, 3.11])

        self.driver.eval_residual(at_des, at_state, store_here)

        # Note: Some implementation details in OpenMDAO currently have an inconsistency between residual sign and residual derivative sign!
        for name, idx in self.driver.state_vars:
            # print(name, store_here.data[idx[0]:idx[1]], self.prob.root.resids[name])
            assert_rel_error(self, store_here.data[idx[0]:idx[1]],-self.prob.root.resids[name],1e-10)

    def test_solver_solve_nonlinear(self): 

        at_des = self.primals[0]
        store_here = self.states[1]

        at_des.data = np.array([1.111, 12.111, 13.111])

        self.driver.solve_nonlinear(at_des, store_here)

        for name, idx in self.driver.state_vars:
            # print(name, store_here.data[idx[0]:idx[1]], self.prob[name])
            assert_rel_error(self, store_here.data[idx[0]:idx[1]],self.prob[name],1e-10)

    def test_solver_multiply_dRdx(self): 

        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        in_vec = self.primals[1]
        out_vec = self.states[1]
        in_vec.data = np.array([2,2,2])
        self.driver.multiply_dRdX(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.data[0], -8., 1e-10)
        assert_rel_error(self, out_vec.data[1], -4., 1e-10)

        in_vec = self.states[2]
        out_vec = self.primals[2]
        in_vec.data = np.array([2,2])
        self.driver.multiply_dRdX_T(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.data[0], -2., 1e-10)
        assert_rel_error(self, out_vec.data[1], -6., 1e-10)
        assert_rel_error(self, out_vec.data[2], -4., 1e-10)

    def test_solver_multiply_dRdU(self): 
        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        in_vec = self.states[1]
        out_vec = self.states[2]
        in_vec.data = np.array([2,2])
        self.driver.multiply_dRdU(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.data[0], 2.4, 1e-10)
        assert_rel_error(self, out_vec.data[1], 1., 1e-10)

        in_vec = self.states[1]
        out_vec = self.states[2]
        in_vec.data = np.array([2,2])
        self.driver.multiply_dRdU_T(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.data[0], 1., 1e-10)
        assert_rel_error(self, out_vec.data[1], 2.4, 1e-10)

    def test_solver_multiply_dCdU(self): 
        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        in_vec = self.states[1]
        out_vec = self.duals[2]
        in_vec.data = np.array([2,2])
        out_vec.ieq_ub_data = np.array([-5,-5])

        # con1, con2
        self.driver.multiply_dCdU(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.ieq_ub_data[0], 2., 1e-10)
        assert_rel_error(self, out_vec.ieq_ub_data[1], -2., 1e-10)
        assert_rel_error(self, out_vec.eq_data[0], -2., 1e-10)
        assert_rel_error(self, out_vec.ieq_lb_data[0], -2., 1e-10)

        in_vec = self.duals[1]
        out_vec = self.states[2]
        in_vec.ieq_ub_data = np.array([2,2])
        in_vec.ieq_lb_data = np.array([2])
        in_vec.eq_data = np.array([2])
        self.driver.multiply_dCdU_T(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.data[0], -2, 1e-10)
        assert_rel_error(self, out_vec.data[1], -2, 1e-10)

    def test_solver_multiply_dCdX(self): 
        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        in_vec = self.primals[1]
        out_vec = self.duals[2]
        in_vec.data = np.array([2,2,2])
        out_vec.ieq_ub_data = np.array([-5,-5])
        out_vec.eq_data = np.array([-5,-5])

        self.driver.multiply_dCdX(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.ieq_ub_data[0], 0., 1e-10)
        assert_rel_error(self, out_vec.ieq_ub_data[1], 0., 1e-10)

        assert_rel_error(self, out_vec.eq_data[0], 4., 1e-10)
        assert_rel_error(self, out_vec.ieq_lb_data[0], 4., 1e-10)

        assert_rel_error(self, out_vec.primal_lb_data, 2*np.ones(3), 1e-10)
        assert_rel_error(self, out_vec.primal_ub_data, -2*np.ones(3), 1e-10)

        in_vec = self.duals[1]
        out_vec = self.primals[2]
        in_vec.ieq_ub_data = np.array([2, 2])
        in_vec.ieq_lb_data = np.array([2])
        in_vec.eq_data = np.array([2])
        
        in_vec.primal_lb_data = np.ones(3)
        in_vec.primal_ub_data = -np.ones(3)

        self.driver.multiply_dCdX_T(at_des, at_state, in_vec, out_vec)
        assert_rel_error(self, out_vec.data[0], 10, 1e-10)
        assert_rel_error(self, out_vec.data[1], 2., 1e-10)
        assert_rel_error(self, out_vec.data[2], 2., 1e-10)

    def test_solver_eval_dFdX(self): 
        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        store_here = self.primals[1]

        self.driver.eval_dFdX(at_des, at_state, store_here)
        assert_rel_error(self, store_here.data[0], 2., 1e-10)
        assert_rel_error(self, store_here.data[1], 0., 1e-10)
        assert_rel_error(self, store_here.data[2], 1., 1e-10)

    def test_solver_eval_dFdU(self): 
        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        store_here = self.states[1]

        self.driver.eval_dFdU(at_des, at_state, store_here)
        assert_rel_error(self, store_here.data[0], 1., 1e-10)
        assert_rel_error(self, store_here.data[1], -np.exp(-1), 1e-10)

    def test_solver_solve_dRdU(self): 
        at_des = self.primals[0]
        at_state = self.states[0]

        at_des.data = np.array([1,1,1])
        at_state.data = np.array([1,1])

        tol = 1e-10

        in_vec = self.states[1]
        out_vec = self.states[2]
        in_vec.data = np.array([-3, 7])
        self.driver.solve_linear(at_des, at_state, in_vec, tol, out_vec)
        assert_rel_error(self, out_vec.data[0], -4., 1e-10)
        assert_rel_error(self, out_vec.data[1], 5., 1e-10)

        in_vec = self.states[1]
        out_vec = self.states[2]
        in_vec.data = np.array([9,4])
        self.driver.solve_adjoint(at_des, at_state, in_vec, tol, out_vec)
        assert_rel_error(self, out_vec.data[0], 10., 1e-10)
        assert_rel_error(self, out_vec.data[1], 2., 1e-10)