def runO(x): p = Problem() p.model.add_subsystem('hs', HeatSink(num_nodes=1)) p.setup(check=False) p['hs.fin_gap'] = x[0] p['hs.fin_w'] = x[1] p.run_model() def printstuff(): print('=============') print('V_in (m/s) : %f' %p['hs.V_in']) print('V_fin (m/s) : %f' %p['hs.V_fin']) print('Nu : %f' %p['hs.Nu']) print('Pr : %f' %p['hs.Pr']) print('Re : %f' %p['hs.Re']) print('fin height: %f' %p['hs.fin_h']) print('# of fins : %f' %p['hs.n_fins']) print('-------------') print('fin thickness (m): %f' % p['hs.fin_w']) print('fin gap (m): %f' % p['hs.fin_gap']) print('Volumetric Flow Rate (m^3/s): %f' % p['hs.V_dot']) print('Maximum thermal resistance (K/W): %f' %p['hs.R_max']) print('Actual total thermal resistance (K/W): %f' % p['hs.R_tot']) #print('Actual total thermal resistance1 (K/W): %f' % p['hs.R_tot1']) #print('h %f' % p['hs.h']) print('Pressure Drop (Pa): %f' % p['hs.dP']) print() printstuff() return np.array([p['hs.R_tot']*10000 + p['hs.dP']*1.4])
def test_simple(self): prob = Problem(Group(), impl=impl) size = 5 A1 = prob.root.add('A1', IndepVarComp('a', np.zeros(size, float))) B1 = prob.root.add('B1', IndepVarComp('b', np.zeros(size, float))) B2 = prob.root.add('B2', IndepVarComp('b', np.zeros(size, float))) S1 = prob.root.add('S1', IndepVarComp('s', '')) L1 = prob.root.add('L1', IndepVarComp('l', [])) C1 = prob.root.add('C1', ABCDArrayComp(size)) C2 = prob.root.add('C2', ABCDArrayComp(size)) prob.root.connect('A1.a', 'C1.a') prob.root.connect('B1.b', 'C1.b') # prob.root.connect('S1:s', 'C1.in_string') # prob.root.connect('L1:l', 'C1.in_list') prob.root.connect('C1.c', 'C2.a') prob.root.connect('B2.b', 'C2.b') # prob.root.connect('C1.out_string', 'C2.in_string') # prob.root.connect('C1.out_list', 'C2.in_list') prob.setup(check=False) prob['A1.a'] = np.ones(size, float) * 3.0 prob['B1.b'] = np.ones(size, float) * 7.0 prob['B2.b'] = np.ones(size, float) * 5.0 prob.run() self.assertTrue(all(prob['C2.a'] == np.ones(size, float)*10.)) self.assertTrue(all(prob['C2.b'] == np.ones(size, float)*5.)) self.assertTrue(all(prob['C2.c'] == np.ones(size, float)*15.)) self.assertTrue(all(prob['C2.d'] == np.ones(size, float)*5.))
def test_parallel_diamond(self): size = 3 prob = Problem(Group(), impl=impl) root = prob.root root.add('P1', IndepVarComp('x', np.ones(size, float) * 1.1)) G1 = root.add('G1', ParallelGroup()) G1.add('C1', ABCDArrayComp(size)) G1.add('C2', ABCDArrayComp(size)) root.add('C3', ABCDArrayComp(size)) root.connect('P1.x', 'G1.C1.a') root.connect('P1.x', 'G1.C2.b') root.connect('G1.C1.c', 'C3.a') root.connect('G1.C2.d', 'C3.b') prob.setup(check=False) prob.run() if not MPI or self.comm.rank == 0: assert_rel_error(self, prob.root.G1.C1.unknowns['c'], np.ones(size)*2.1, 1.e-10) assert_rel_error(self, prob.root.G1.C1.unknowns['d'], np.ones(size)*.1, 1.e-10) assert_rel_error(self, prob.root.C3.params['a'], np.ones(size)*2.1, 1.e-10) assert_rel_error(self, prob.root.C3.params['b'], np.ones(size)*-.1, 1.e-10) if not MPI or self.comm.rank == 1: assert_rel_error(self, prob.root.G1.C2.unknowns['c'], np.ones(size)*2.1, 1.e-10) assert_rel_error(self, prob.root.G1.C2.unknowns['d'], np.ones(size)*-.1, 1.e-10)
def test_run_apply(self): # This test makes sure that we correctly apply the "run_apply" flag # to all targets in the "broken" connection, even when they are # nested in Groups. prob = Problem() root = prob.root = Group() sub1 = root.add('sub1', Group()) sub2 = root.add('sub2', Group()) sub1.add('p1', Paraboloid()) sub1.add('p2', Paraboloid()) sub2.add('p1', Paraboloid()) sub2.add('p2', Paraboloid()) root.connect('sub1.p1.f_xy', 'sub2.p1.x') root.connect('sub1.p2.f_xy', 'sub2.p1.y') root.connect('sub1.p1.f_xy', 'sub2.p2.x') root.connect('sub1.p2.f_xy', 'sub2.p2.y') root.connect('sub2.p1.f_xy', 'sub1.p1.x') root.connect('sub2.p2.f_xy', 'sub1.p1.y') root.connect('sub2.p1.f_xy', 'sub1.p2.x') root.connect('sub2.p2.f_xy', 'sub1.p2.y') root.nl_solver = NLGaussSeidel() root.ln_solver = ScipyGMRES() prob.setup(check=False) # Will be True in one group and False in the other, depending on # where it cuts. self.assertTrue(root.sub1.p1._run_apply != root.sub2.p1._run_apply) self.assertTrue(root.sub1.p2._run_apply != root.sub2.p2._run_apply)
def test_multiple_problems(self): if MPI: # split the comm and run an instance of the Problem in each subcomm subcomm = self.comm.Split(self.comm.rank) prob = Problem(Group(), impl=impl, comm=subcomm) size = 5 value = self.comm.rank + 1 values = np.ones(size)*value A1 = prob.root.add('A1', IndepVarComp('x', values)) C1 = prob.root.add('C1', ABCDArrayComp(size)) prob.root.connect('A1.x', 'C1.a') prob.root.connect('A1.x', 'C1.b') prob.setup(check=False) prob.run() # check the first output array and store in result self.assertTrue(all(prob['C1.c'] == np.ones(size)*(value*2))) result = prob['C1.c'] # gather the results from the separate processes/problems and check # for expected values results = self.comm.allgather(result) self.assertEqual(len(results), self.comm.size) for n in range(self.comm.size): expected = np.ones(size)*2*(n+1) self.assertTrue(all(results[n] == expected))
def test_parab_FD(self): model = Problem(impl=impl) root = model.root = Group() par = root.add('par', ParallelGroup()) par.add('c1', Parab1D(root=2.0)) par.add('c2', Parab1D(root=3.0)) root.add('p1', IndepVarComp('x', val=0.0)) root.add('p2', IndepVarComp('x', val=0.0)) root.connect('p1.x', 'par.c1.x') root.connect('p2.x', 'par.c2.x') root.add('sumcomp', ExecComp('sum = x1+x2')) root.connect('par.c1.y', 'sumcomp.x1') root.connect('par.c2.y', 'sumcomp.x2') driver = model.driver = pyOptSparseDriver() driver.options['optimizer'] = OPTIMIZER driver.options['print_results'] = False driver.add_desvar('p1.x', lower=-100, upper=100) driver.add_desvar('p2.x', lower=-100, upper=100) driver.add_objective('sumcomp.sum') root.fd_options['force_fd'] = True model.setup(check=False) model.run() if not MPI or self.comm.rank == 0: assert_rel_error(self, model['p1.x'], 2.0, 1.e-6) assert_rel_error(self, model['p2.x'], 3.0, 1.e-6)
def test_parab_subbed_Pcomps(self): model = Problem(impl=impl) root = model.root = Group() root.ln_solver = lin_solver() par = root.add('par', ParallelGroup()) par.add('s1', MP_Point(root=2.0)) par.add('s2', MP_Point(root=3.0)) root.add('sumcomp', ExecComp('sum = x1+x2')) root.connect('par.s1.c.y', 'sumcomp.x1') root.connect('par.s2.c.y', 'sumcomp.x2') driver = model.driver = pyOptSparseDriver() driver.options['optimizer'] = OPTIMIZER driver.options['print_results'] = False driver.add_desvar('par.s1.p.x', lower=-100, upper=100) driver.add_desvar('par.s2.p.x', lower=-100, upper=100) driver.add_objective('sumcomp.sum') model.setup(check=False) model.run() if not MPI or self.comm.rank == 0: assert_rel_error(self, model['par.s1.p.x'], 2.0, 1.e-6) if not MPI or self.comm.rank == 1: assert_rel_error(self, model['par.s2.p.x'], 3.0, 1.e-6)
def test_mult_conns(self): class SubGroup(Group): def setup(self): self.add_subsystem('c1', ExecComp('y = 2*x', x=np.ones(4), y=2*np.ones(4)), promotes=['y', 'x']) self.add_subsystem('c2', ExecComp('z = 2*y', y=np.ones(4), z=2*np.ones(4)), promotes=['z', 'y']) prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('x', 10*np.ones(4)) indeps.add_output('y', np.ones(4)) prob.model.add_subsystem('sub', SubGroup()) prob.model.connect('x', 'sub.x') prob.model.connect('y', 'sub.y') with self.assertRaises(Exception) as context: prob.setup() self.assertEqual(str(context.exception), "The following inputs have multiple connections: " "sub.c2.y from ['indeps.y', 'sub.c1.y']")
def test_alloc_jacobian(self): # Testing the helper function p = Problem() root = p.root = Group() root.add('comp1', ExecComp(["y[0]=x[0]*2.0+x[1]*7.0", "y[1]=x[0]*5.0-x[1]*3.0+x[2]*1.5"], x=np.zeros(3), y=np.zeros(2))) root.add('comp2', SimpleImplicitComp()) root.ln_solver.options['maxiter'] = 2 p.setup(check=False) # Explciit J = root.comp1.alloc_jacobian() self.assertTrue(len(J) == 1) self.assertTrue(('y', 'x') in J) self.assertTrue(J[('y', 'x')].shape == (2,3)) # Implicit J = root.comp2.alloc_jacobian() self.assertTrue(len(J) == 4) self.assertTrue(('y', 'x') in J) self.assertTrue(('y', 'z') in J) self.assertTrue(('z', 'x') in J) self.assertTrue(('z', 'z') in J) self.assertTrue(J[('y', 'x')].shape == (1, 1)) self.assertTrue(J[('y', 'z')].shape == (1, 1)) self.assertTrue(J[('z', 'x')].shape == (1, 1)) self.assertTrue(J[('z', 'z')].shape == (1, 1)) p.run()
def test_src_indices_error(self): size = 3 group = Group() group.add('P', IndepVarComp('x', numpy.ones(size))) group.add('C1', DistribExecComp(['y=2.0*x'], arr_size=size, x=numpy.zeros(size), y=numpy.zeros(size))) group.add('C2', ExecComp(['z=3.0*y'], y=numpy.zeros(size), z=numpy.zeros(size))) prob = Problem(impl=impl) prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.root.connect('P.x', 'C1.x') prob.root.connect('C1.y', 'C2.y') prob.driver.add_desvar('P.x') prob.driver.add_objective('C1.y') try: prob.setup(check=False) except Exception as err: self.assertEqual(str(err), "'C1.y' is a distributed variable" " and may not be used as a design var," " objective, or constraint.") else: if MPI: self.fail("Exception expected")
def test_too_few_procs(self): size = 3 group = Group() group.add('P', IndepVarComp('x', numpy.ones(size))) group.add('C1', DistribExecComp(['y=2.0*x'], arr_size=size, x=numpy.zeros(size), y=numpy.zeros(size))) group.add('C2', ExecComp(['z=3.0*y'], y=numpy.zeros(size), z=numpy.zeros(size))) prob = Problem(impl=impl) prob.root = group prob.root.ln_solver = LinearGaussSeidel() prob.root.connect('P.x', 'C1.x') prob.root.connect('C1.y', 'C2.y') try: prob.setup(check=False) except Exception as err: self.assertEqual(str(err), "This problem was given 1 MPI processes, " "but it requires between 2 and 2.") else: if MPI: self.fail("Exception expected")
def test_specify_subgroup_solvers(self): from openmdao.api import Problem, NewtonSolver, ScipyKrylov, DirectSolver, NonlinearBlockGS, LinearBlockGS from openmdao.test_suite.components.double_sellar import DoubleSellar prob = Problem() model = prob.model = DoubleSellar() # each SubSellar group converges itself g1 = model.g1 g1.nonlinear_solver = NewtonSolver() g1.linear_solver = DirectSolver() # used for derivatives g2 = model.g2 g2.nonlinear_solver = NewtonSolver() g2.linear_solver = DirectSolver() # Converge the outer loop with Gauss Seidel, with a looser tolerance. model.nonlinear_solver = NonlinearBlockGS(rtol=1.0e-5) model.linear_solver = ScipyKrylov() model.linear_solver.precon = LinearBlockGS() prob.setup() prob.run_model() assert_rel_error(self, prob['g1.y1'], 0.64, .00001) assert_rel_error(self, prob['g1.y2'], 0.80, .00001) assert_rel_error(self, prob['g2.y1'], 0.64, .00001) assert_rel_error(self, prob['g2.y2'], 0.80, .00001)
def test_pbo_desvar_slsqp_scipy(self): top = Problem() root = top.root = Group() root.add('p1', IndepVarComp('x', u'var_x', pass_by_obj=True)) root.add('p2', IndepVarComp('y', -4.0)) root.add('p', PassByObjParaboloid()) root.connect('p1.x', 'p.x') root.connect('p2.y', 'p.y') top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.add_desvar('p1.x') top.driver.add_desvar('p2.y') top.driver.add_objective('p.f_xy') try: top.setup(check=False) except Exception as err: self.assertEqual(str(err), "Parameter 'p1.x' is a 'pass_by_obj' variable and " "can't be used with a gradient based driver of type 'SLSQP'.") else: self.fail("Exception expected")
def test_basic(self): prob = Problem() model = prob.model n_cp = 80 n_point = 160 t = np.linspace(0, 3.0*np.pi, n_cp) x = np.sin(t) model.add_subsystem('px', IndepVarComp('x', val=x)) model.add_subsystem('interp', BsplinesComp(num_control_points=n_cp, num_points=n_point, in_name='h_cp', out_name='h', distribution='uniform')) model.connect('px.x', 'interp.h_cp') prob.setup(check=False) prob.run_model() xx = prob['interp.h'].flatten() tt = np.linspace(0, 3.0*np.pi, n_point) x_expected = np.sin(tt) delta = xx - x_expected # Here we test that we don't have crazy interpolation error. self.assertLess(max(delta), .15) # And that it gets middle points a little better. self.assertLess(max(delta[15:-15]), .06)
def test_file_diamond(self): # connect a source FileRef to two target FileRefs on # components running in parallel, and connect the outputs # of those components to a common sink component. All filenames # are different, so files will actually be copied for each connection. if MPI: num = self.N_PROCS else: num = 1 prob = Problem(Group(), impl=impl) src = prob.root.add("src", FileSrc('src')) par = prob.root.add('par', ParallelGroup()) sink = prob.root.add("sink", FileSink('sink', num)) for i in range(num): par.add("mid%d"%i, FileMid('mid%d'%i,'mid%d'%i)) prob.root.connect('src.fout', 'par.mid%d.fin'%i) prob.root.connect('par.mid%d.fout'%i, 'sink.fin%d'%i) prob.setup(check=False) prob.run() for i in range(num): with sink.params['fin%d'%i].open('r') as f: self.assertEqual(f.read(), "src\npar.mid%d\n"%i)
def test_add_params(self): self.comp.add_param("x", 0.0) self.comp.add_param("y", 0.0) self.comp.add_param("z", shape=(1, )) self.comp.add_param("t", shape=2) self.comp.add_param("u", shape=1) # This should no longer raise an error self.comp.add_param("w") prob = Problem() self.comp._init_sys_data('', prob._probdata) params, unknowns = self.comp._setup_variables() self.assertEqual(["x", "y", "z", "t", "u", 'w'], list(params.keys())) self.assertEqual(params["x"], {'shape': 1, 'pathname': 'x', 'val': 0.0, 'size': 1}) self.assertEqual(params["y"], {'shape': 1, 'pathname': 'y', 'val': 0.0, 'size': 1}) np.testing.assert_array_equal(params["z"]["val"], np.zeros((1,))) np.testing.assert_array_equal(params["t"]["val"], np.zeros((2,))) self.assertEqual(params["u"], {'shape': 1, 'pathname': 'u', 'val': 0.0, 'size': 1}) prob = Problem() root = prob.root = Group() root.add('comp', self.comp) with self.assertRaises(RuntimeError) as cm: prob.setup(check=False) self.assertEqual(str(cm.exception), "Unconnected param 'comp.w' is missing a shape or default value.")
def setup_model(self, mode): asize = 3 prob = Problem() root = prob.model root.linear_solver = LinearBlockGS() p = root.add_subsystem('p', IndepVarComp('x', np.arange(asize, dtype=float)+1.0)) G1 = root.add_subsystem('G1', ParallelGroup()) G1.linear_solver = LinearBlockGS() c2 = G1.add_subsystem('c2', ExecComp('y = x * 2.0', x=np.zeros(asize), y=np.zeros(asize))) c3 = G1.add_subsystem('c3', ExecComp('y = ones(3).T*x.dot(arange(3.,6.))', x=np.zeros(asize), y=np.zeros(asize))) c4 = root.add_subsystem('c4', ExecComp('y = x * 4.0', x=np.zeros(asize), y=np.zeros(asize))) c5 = root.add_subsystem('c5', ExecComp('y = x * 5.0', x=np.zeros(asize), y=np.zeros(asize))) prob.model.add_design_var('p.x', indices=[1, 2]) prob.model.add_constraint('c4.y', upper=0.0, indices=[1], parallel_deriv_color='par_resp') prob.model.add_constraint('c5.y', upper=0.0, indices=[2], parallel_deriv_color='par_resp') root.connect('p.x', 'G1.c2.x') root.connect('p.x', 'G1.c3.x') root.connect('G1.c2.y', 'c4.x') root.connect('G1.c3.y', 'c5.x') prob.setup(check=False, mode=mode) prob.run_driver() return prob
class TestDeprecatedExternalCode(unittest.TestCase): def setUp(self): self.startdir = os.getcwd() self.tempdir = tempfile.mkdtemp(prefix='test_extcode-') os.chdir(self.tempdir) shutil.copy(os.path.join(DIRECTORY, 'extcode_example.py'), os.path.join(self.tempdir, 'extcode_example.py')) msg = "'ExternalCode' has been deprecated. Use 'ExternalCodeComp' instead." with assert_warning(DeprecationWarning, msg): self.extcode = DeprecatedExternalCodeForTesting() self.prob = Problem() self.prob.model.add_subsystem('extcode', self.extcode) def tearDown(self): os.chdir(self.startdir) try: shutil.rmtree(self.tempdir) except OSError: pass def test_normal(self): self.extcode.options['command'] = [ 'python', 'extcode_example.py', 'extcode.out' ] self.extcode.options['external_input_files'] = ['extcode_example.py'] self.extcode.options['external_output_files'] = ['extcode.out'] self.prob.setup(check=True) self.prob.run_model()
def test_beam_tutorial_viewtree(self): top = Problem() top.root = BeamTutorial() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-8 top.driver.options['maxiter'] = 10000 #maximum number of solver iterations top.driver.options['disp'] = False #room length and width bounds top.driver.add_desvar('ivc_rlength.room_length', lower=5.0*12.0, upper=50.0*12.0) #domain: 1in <= length <= 50ft top.driver.add_desvar('ivc_rwidth.room_width', lower=5.0*12.0, upper=30.0*12.0) #domain: 1in <= width <= 30ft top.driver.add_objective('d_neg_area.neg_room_area') #minimize negative area (or maximize area) top.driver.add_constraint('d_len_minus_wid.length_minus_width', lower=0.0) #room_length >= room_width top.driver.add_constraint('d_deflection.deflection', lower=720.0) #deflection >= 720 top.driver.add_constraint('d_bending.bending_stress_ratio', upper=0.5) #bending < 0.5 top.driver.add_constraint('d_shear.shear_stress_ratio', upper=1.0/3.0) #shear < 1/3 top.setup(check=False) from openmdao.api import view_tree view_tree(top, show_browser=False) import os.path self.assertTrue(os.path.isfile('partition_tree_n2.html')) os.remove('partition_tree_n2.html')
def test_hierarchy_iprint3(self): prob = Problem() model = prob.model model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0]))) sub1 = model.add_subsystem('sub1', Group()) sub2 = sub1.add_subsystem('sub2', Group()) g1 = sub2.add_subsystem('g1', SubSellar()) g2 = model.add_subsystem('g2', SubSellar()) model.connect('pz.z', 'sub1.sub2.g1.z') model.connect('sub1.sub2.g1.y2', 'g2.x') model.connect('g2.y2', 'sub1.sub2.g1.x') model.nonlinear_solver = NonlinearBlockJac() sub1.nonlinear_solver = NonlinearBlockJac() sub2.nonlinear_solver = NonlinearBlockJac() g1.nonlinear_solver = NonlinearBlockJac() g2.nonlinear_solver = NonlinearBlockJac() prob.set_solver_print(level=2) prob.setup(check=False) output = run_model(prob)
def test_check_totals_calls_run_once(self): prob = Problem() root = prob.root = Group() root.add('p1', IndepVarComp('x', 1.0), promotes=['*']) root.add('p2', IndepVarComp('y', 1.0), promotes=['*']) root.add('comp', Paraboloid(), promotes=['*']) prob.driver.add_desvar('x') prob.driver.add_desvar('y') prob.driver.add_objective('f_xy') prob.setup(check=False) prob['x'] = 5.0 prob['y'] = 2.0 iostream = StringIO() data = prob.check_total_derivatives(out_stream=iostream) self.assertAlmostEqual(first=prob["f_xy"], second= (prob['x']-3.0)**2 \ + prob['x']*prob['y'] \ + (prob['y']+4.0)**2 - 3.0, places=5, msg="check partial derivatives did not call" "run_once on the driver as expected.") self.assertEqual(first=iostream.getvalue()[:39], second="Executing model to populate unknowns...", msg="check partial derivatives failed to run driver once")
def test_fan_in(self): prob = Problem(Group(), impl=impl) par = prob.root.add('par', ParallelGroup()) G1 = par.add('G1', Group()) A1 = G1.add('A1', IndepVarComp('a', [1.,1.,1.,1.,1.])) C1 = G1.add('C1', PBOComp()) G2 = par.add('G2', Group()) B1 = G2.add('B1', IndepVarComp('b', [3.,3.,3.,3.,3.])) C2 = G2.add('C2', PBOComp()) C3 = prob.root.add('C3', PBOComp()) par.connect('G1.A1.a', 'G1.C1.a') par.connect('G2.B1.b', 'G2.C2.a') prob.root.connect('par.G1.C1.c', 'C3.a') prob.root.connect('par.G2.C2.c', 'C3.b') prob.setup(check=False) prob.run() self.assertEqual(prob['C3.a'], [2.,3.,4.,5.,6.]) self.assertEqual(prob['C3.b'], [4.,5.,6.,7.,8.]) self.assertEqual(prob['C3.c'], [6.,8.,10.,12.,14.]) self.assertEqual(prob['C3.d'], [-2.,-2.,-2.,-2.,-2.]) self.assertEqual(prob.root.unknowns.vec.size, 0)
def test_simple_deriv_xfer(self): prob = Problem(impl=impl) prob.root = FanInGrouped() prob.setup(check=False) prob.root.comp3.dpmat[None]['x1'] = 7. prob.root.comp3.dpmat[None]['x2'] = 11. prob.root._transfer_data(mode='rev', deriv=True) if not MPI or self.comm.rank == 0: self.assertEqual(prob.root.sub.comp1.dumat[None]['y'], 7.) if not MPI or self.comm.rank == 1: self.assertEqual(prob.root.sub.comp2.dumat[None]['y'], 11.) prob.root.comp3.dpmat[None]['x1'] = 0. prob.root.comp3.dpmat[None]['x2'] = 0. self.assertEqual(prob.root.comp3.dpmat[None]['x1'], 0.) self.assertEqual(prob.root.comp3.dpmat[None]['x2'], 0.) prob.root._transfer_data(mode='fwd', deriv=True) self.assertEqual(prob.root.comp3.dpmat[None]['x1'], 7.) self.assertEqual(prob.root.comp3.dpmat[None]['x2'], 11.)
def test_iprint(self): top = Problem() top.root = SellarStateConnection() top.setup(check=False) base_stdout = sys.stdout try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed, '') # Turn on all iprints top.print_all_convergence() try: ostream = cStringIO() sys.stdout = ostream top.run() finally: sys.stdout = base_stdout printed = ostream.getvalue() self.assertEqual(printed.count('NEWTON'), 3) self.assertEqual(printed.count('GMRES'), 4) self.assertTrue('[root] NL: NEWTON 0 | ' in printed) self.assertTrue(' [root.sub] LN: GMRES 0 | ' in printed)
def test_conflicting_promotions(self): # verify we get an error if we have conflicting promotions root = Group() # promoting G1.x will create an implicit connection to G3.x # this is a conflict because G3.x (aka G3.C4.x) is already connected # to G3.C3.x G2 = root.add('G2', Group()) G2.add('C1', IndepVarComp('x', 5.), promotes=['x']) G1 = G2.add('G1', Group(), promotes=['x']) G1.add('C2', ExecComp('y=x*2.0'), promotes=['x']) G3 = root.add('G3', Group(), promotes=['x']) G3.add('C3', ExecComp('y=x*2.0'), promotes=['y']) # promoting y G3.add('C4', ExecComp('y=x*2.0'), promotes=['x', 'y']) # promoting y again.. BAD prob = Problem(root) try: prob.setup(check=False) except Exception as error: msg = "'G3': promoted name 'y' matches multiple unknowns: ('G3.C3.y', 'G3.C4.y')" self.assertEqual(text_type(error), msg) else: self.fail("Error expected")
def test_no_vecs(self): prob = Problem(root=ExampleGroup()) prob.setup(check=False) # test that problem has no unknowns, params, etc. try: prob.unknowns['G3.C4.y'] except AttributeError as err: self.assertEqual(str(err), "'Problem' object has no attribute 'unknowns'") else: self.fail("AttributeError expected") try: prob.params['G3.C4.x'] except AttributeError as err: self.assertEqual(str(err), "'Problem' object has no attribute 'params'") else: self.fail("AttributeError expected") try: prob.resids['G3.C4.x'] except AttributeError as err: self.assertEqual(str(err), "'Problem' object has no attribute 'resids'") else: self.fail("AttributeError expected")
def test_byobj_run(self): prob = Problem(root=ExampleByObjGroup()) prob.setup(check=False) prob.run() self.assertEqual(prob['G3.C4.y'], 'fooC2C3C4')
def configure(cfg): pf = read_blade_planform(os.path.join(PATH, 'data/DTU_10MW_RWT_blade_axis_prebend.dat')) nsec = 8 s_new = np.linspace(0, 1, nsec) pf = redistribute_planform(pf, s=s_new) cfg['redistribute_flag'] = False cfg['blend_var'] = np.array([0.241, 0.301, 0.36, 1.0]) afs = [] for f in [os.path.join(PATH, 'data/ffaw3241.dat'), os.path.join(PATH, 'data/ffaw3301.dat'), os.path.join(PATH, 'data/ffaw3360.dat'), os.path.join(PATH, 'data/cylinder.dat')]: afs.append(np.loadtxt(f)) cfg['base_airfoils'] = afs d = PGLLoftedBladeSurface(cfg, size_in=nsec, size_out=(200, nsec, 3), suffix='_st') p = Problem(root=Group()) r = p.root.add('blade_surf', d, promotes=['*']) p.setup() for k, v in pf.iteritems(): if k+'_st' in p.root.blade_surf.params.keys(): p.root.blade_surf.params[k+'_st'] = v return p
def test_conflicting_connections(self): # verify we get an error if we have conflicting implicit and explicit connections root = Group() # promoting G1.x will create an implicit connection to G3.x # this is a conflict because G3.x (aka G3.C4.x) is already connected # to G3.C3.x G2 = root.add('G2', Group(), promotes=['x']) # BAD PROMOTE G2.add('C1', IndepVarComp('x', 5.), promotes=['x']) G1 = G2.add('G1', Group(), promotes=['x']) G1.add('C2', ExecComp('y=x*2.0'), promotes=['x']) G3 = root.add('G3', Group(), promotes=['x']) G3.add('C3', ExecComp('y=x*2.0')) G3.add('C4', ExecComp('y=x*2.0'), promotes=['x']) root.connect('G2.G1.C2.y', 'G3.C3.x') G3.connect('C3.y', 'x') prob = Problem(root) try: prob.setup(check=False) except Exception as error: msg = "Target 'G3.C4.x' is connected to multiple unknowns: ['G2.C1.x', 'G3.C3.y']" self.assertTrue(msg in str(error)) else: self.fail("Error expected")
def test_hierarchy_iprint(self): prob = Problem() model = prob.model model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0]))) sub1 = model.add_subsystem('sub1', Group()) sub2 = sub1.add_subsystem('sub2', Group()) g1 = sub2.add_subsystem('g1', SubSellar()) g2 = model.add_subsystem('g2', SubSellar()) model.connect('pz.z', 'sub1.sub2.g1.z') model.connect('sub1.sub2.g1.y2', 'g2.x') model.connect('g2.y2', 'sub1.sub2.g1.x') model.nonlinear_solver = NewtonSolver() model.linear_solver = ScipyKrylov() model.nonlinear_solver.options['solve_subsystems'] = True model.nonlinear_solver.options['max_sub_solves'] = 0 g1.nonlinear_solver = NewtonSolver() g1.linear_solver = LinearBlockGS() g2.nonlinear_solver = NewtonSolver() g2.linear_solver = ScipyKrylov() g2.linear_solver.precon = LinearBlockGS() g2.linear_solver.precon.options['maxiter'] = 2 prob.set_solver_print(level=2) prob.setup(check=False) output = run_model(prob)
def create_mda(self): return Mda(self.scalers) @staticmethod def create_performance(self): return Performance(self.scalers) @staticmethod def create_constraints(self): return Constraints(self.scalers) if __name__ == "__main__": parser = OptionParser() parser.add_option("-n", "--no-n2", action="store_false", dest='n2_view', default=True, help="display N2 openmdao viewer") (options, args) = parser.parse_args() problem = Problem() problem.model = SsbjMda() problem.setup() problem.final_setup() if options.n2_view: view_model(problem)
def test_case1(self): self.prob = Problem() cycle = self.prob.model = Cycle() cycle.options['thermo_method'] = 'CEA' cycle.options['thermo_data'] = species_data.janaf cycle.add_subsystem('flow_start', FlowStart(), promotes=['MN', 'P', 'T']) cycle.add_subsystem('duct', Duct(), promotes=['MN']) cycle.pyc_connect_flow('flow_start.Fl_O', 'duct.Fl_I') cycle.set_input_defaults('MN', 0.5) cycle.set_input_defaults('duct.dPqP', 0.0) cycle.set_input_defaults('P', 17., units='psi') cycle.set_input_defaults('T', 500., units='degR') cycle.set_input_defaults('flow_start.W', 500., units='lbm/s') self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_solver_print(level=-1) # 6 cases to check against for i, data in enumerate(ref_data): self.prob['duct.dPqP'] = data[h_map['dPqP']] # input flowstation self.prob['P'] = data[h_map['Fl_I.Pt']] self.prob['T'] = data[h_map['Fl_I.Tt']] self.prob['MN'] = data[h_map['Fl_O.MN']] self.prob['flow_start.W'] = data[h_map['Fl_I.W']] self.prob['duct.Fl_I:stat:V'] = data[h_map['Fl_I.V']] # give a decent initial guess for Ps print(i, self.prob['P'], self.prob['T'], self.prob['MN']) self.prob.run_model() # check outputs pt, ht, ps, ts = data[h_map['Fl_O.Pt']], data[h_map[ 'Fl_O.ht']], data[h_map['Fl_O.Ps']], data[h_map['Fl_O.Ts']] pt_computed = self.prob['duct.Fl_O:tot:P'] ht_computed = self.prob['duct.Fl_O:tot:h'] ps_computed = self.prob['duct.Fl_O:stat:P'] ts_computed = self.prob['duct.Fl_O:stat:T'] tol = 2.0e-2 assert_near_equal(pt_computed, pt, tol) assert_near_equal(ht_computed, ht, tol) assert_near_equal(ps_computed, ps, tol) assert_near_equal(ts_computed, ts, tol) partial_data = self.prob.check_partials(out_stream=None, method='cs', includes=['duct.*'], excludes=[ '*.base_thermo.*', ]) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
class DuctTestCase(unittest.TestCase): def test_case1(self): self.prob = Problem() cycle = self.prob.model = Cycle() cycle.options['thermo_method'] = 'CEA' cycle.options['thermo_data'] = species_data.janaf cycle.add_subsystem('flow_start', FlowStart(), promotes=['MN', 'P', 'T']) cycle.add_subsystem('duct', Duct(), promotes=['MN']) cycle.pyc_connect_flow('flow_start.Fl_O', 'duct.Fl_I') cycle.set_input_defaults('MN', 0.5) cycle.set_input_defaults('duct.dPqP', 0.0) cycle.set_input_defaults('P', 17., units='psi') cycle.set_input_defaults('T', 500., units='degR') cycle.set_input_defaults('flow_start.W', 500., units='lbm/s') self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_solver_print(level=-1) # 6 cases to check against for i, data in enumerate(ref_data): self.prob['duct.dPqP'] = data[h_map['dPqP']] # input flowstation self.prob['P'] = data[h_map['Fl_I.Pt']] self.prob['T'] = data[h_map['Fl_I.Tt']] self.prob['MN'] = data[h_map['Fl_O.MN']] self.prob['flow_start.W'] = data[h_map['Fl_I.W']] self.prob['duct.Fl_I:stat:V'] = data[h_map['Fl_I.V']] # give a decent initial guess for Ps print(i, self.prob['P'], self.prob['T'], self.prob['MN']) self.prob.run_model() # check outputs pt, ht, ps, ts = data[h_map['Fl_O.Pt']], data[h_map[ 'Fl_O.ht']], data[h_map['Fl_O.Ps']], data[h_map['Fl_O.Ts']] pt_computed = self.prob['duct.Fl_O:tot:P'] ht_computed = self.prob['duct.Fl_O:tot:h'] ps_computed = self.prob['duct.Fl_O:stat:P'] ts_computed = self.prob['duct.Fl_O:stat:T'] tol = 2.0e-2 assert_near_equal(pt_computed, pt, tol) assert_near_equal(ht_computed, ht, tol) assert_near_equal(ps_computed, ps, tol) assert_near_equal(ts_computed, ts, tol) partial_data = self.prob.check_partials(out_stream=None, method='cs', includes=['duct.*'], excludes=[ '*.base_thermo.*', ]) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8) def test_case_with_dPqP_MN(self): self.prob = Problem() # need two cycles, because we can't mix design and off-design cycle_DES = self.prob.model.add_subsystem('DESIGN', Cycle()) cycle_DES.options['thermo_method'] = 'CEA' cycle_DES.options['thermo_data'] = species_data.janaf cycle_OD = self.prob.model.add_subsystem('OFF_DESIGN', Cycle()) cycle_OD.options['design'] = False cycle_OD.options['thermo_method'] = 'CEA' cycle_OD.options['thermo_data'] = species_data.janaf cycle_DES.add_subsystem('flow_start', FlowStart(), promotes=['P', 'T', 'MN', 'W']) cycle_OD.add_subsystem('flow_start_OD', FlowStart(), promotes=['P', 'T', 'W', 'MN']) expMN = 1.0 cycle_DES.add_subsystem('duct', Duct(expMN=expMN), promotes=['MN']) cycle_OD.add_subsystem('duct', Duct(expMN=expMN, design=False)) cycle_DES.pyc_connect_flow('flow_start.Fl_O', 'duct.Fl_I') cycle_OD.pyc_connect_flow('flow_start_OD.Fl_O', 'duct.Fl_I') cycle_DES.set_input_defaults('P', 17., units='psi') cycle_DES.set_input_defaults('T', 500., units='degR') cycle_DES.set_input_defaults('MN', 0.5) cycle_DES.set_input_defaults('duct.dPqP', 0.0) cycle_DES.set_input_defaults('W', 500., units='lbm/s') cycle_OD.set_input_defaults('P', 17., units='psi') cycle_OD.set_input_defaults('T', 500., units='degR') cycle_OD.set_input_defaults('MN', 0.25) cycle_OD.set_input_defaults('duct.dPqP', 0.0) cycle_OD.set_input_defaults('W', 500., units='lbm/s') self.prob.model.connect("DESIGN.duct.s_dPqP", "OFF_DESIGN.duct.s_dPqP") self.prob.model.connect("DESIGN.duct.Fl_O:stat:area", "OFF_DESIGN.duct.area") self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_solver_print(level=-1) data = ref_data[0] self.prob['DESIGN.duct.dPqP'] = data[h_map['dPqP']] # input flowstation self.prob['DESIGN.P'] = data[h_map['Fl_I.Pt']] self.prob['DESIGN.T'] = data[h_map['Fl_I.Tt']] self.prob['DESIGN.MN'] = data[h_map['Fl_O.MN']] self.prob['DESIGN.W'] = data[h_map['Fl_I.W']] # self.prob['DESIGN.duct.Fl_I:stat:V'] = data[h_map['Fl_I.V']] # input flowstation self.prob['OFF_DESIGN.P'] = data[h_map['Fl_I.Pt']] self.prob['OFF_DESIGN.T'] = data[h_map['Fl_I.Tt']] self.prob['OFF_DESIGN.W'] = data[h_map['Fl_I.W']] # self.prob['OFF_DESIGN.duct.Fl_I:stat:V'] = data[h_map['Fl_I.V']] # give a decent initial guess for Ps print(self.prob['DESIGN.P'], self.prob['DESIGN.T'], self.prob['DESIGN.MN']) self.prob.run_model() # check outputs pt, ht, ps, ts = data[h_map['Fl_O.Pt']], data[h_map['Fl_O.ht']], data[ h_map['Fl_O.Ps']], data[h_map['Fl_O.Ts']] pt_computed = self.prob['OFF_DESIGN.duct.Fl_O:tot:P'] ht_computed = self.prob['OFF_DESIGN.duct.Fl_O:tot:h'] ps_computed = self.prob['OFF_DESIGN.duct.Fl_O:stat:P'] ts_computed = self.prob['OFF_DESIGN.duct.Fl_O:stat:T'] tol = 1.0e-4 assert_near_equal(pt_computed, 8.84073152, tol) assert_near_equal(ht_computed, ht, tol) assert_near_equal(ps_computed, 8.26348914, tol) assert_near_equal(ts_computed, ts, tol) partial_data = self.prob.check_partials(out_stream=None, method='cs', includes=['duct.*'], excludes=[ '*.base_thermo.*', ]) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
counter = 0 for surface in surfList: if surface['sweep'] == 0: surfname = 'str' ailList = ailList_straight else: surfname = 'swp' ailList = ailList_swept for aileron in ailList: surface['control_surfaces'] = [aileron] print(surfname+'_'+aileron['name']+'\n') # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=25., units='m/s') indep_var_comp.add_output('alpha', val=alpha, units='deg') indep_var_comp.add_output('re', val=5e5, units='1/m') indep_var_comp.add_output('rho', val=rho, units='kg/m**3') indep_var_comp.add_output('cg', val=cg_loc, units='m') indep_var_comp.add_output('delta_aileron', val=12.5,units='deg') indep_var_comp.add_output('omega', val=np.array([1.,0.,0.]),units='rad/s') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])
*(inputs[in_name] for in_name in in_names[:i]), self.I[len(completed_in_names) - 1], *(inputs[in_name] for in_name in in_names[i + 1:])).reshape( partials[out_name, in_name].shape) if __name__ == '__main__': from openmdao.api import Problem, IndepVarComp # h = hpy() shape1 = (2, 2, 4) shape2 = (2, 7, 4) shape3 = (7, 2, 4) prob = Problem() comp = IndepVarComp() comp.add_output('x', np.random.rand(*shape1)) comp.add_output('y', np.random.rand(*shape2)) comp.add_output('z', np.random.rand(*shape3)) prob.model.add_subsystem('inputs_comp', comp, promotes=['*']) # out_shape = (2, 3, 4, 4, 7) comp = EinsumComp( in_names=['x', 'y', 'x'], in_shapes=[(2, 2, 4), (2, 7, 4), (2, 2, 4)], out_name='f', operation='abc,ade,fae->bcdfa', ) prob.model.add_subsystem('comp', comp, promotes=['*'])
def test_add_input_output_dupes(self): class Comp(ExplicitComponent): def setup(self): self.add_input('x', val=3.0) self.add_input('x', val=3.0) self.add_output('y', val=3.0) prob = Problem() model = prob.model = Group() model.add_subsystem('px', IndepVarComp('x', val=3.0)) model.add_subsystem('comp', Comp()) model.connect('px.x', 'comp.x') msg = "Variable name 'x' already exists." with assertRaisesRegex(self, ValueError, msg): prob.setup(check=False) class Comp(ExplicitComponent): def setup(self): self.add_input('x', val=3.0) self.add_output('y', val=3.0) self.add_output('y', val=3.0) prob = Problem() model = prob.model = Group() model.add_subsystem('px', IndepVarComp('x', val=3.0)) model.add_subsystem('comp', Comp()) model.connect('px.x', 'comp.x') msg = "Variable name 'y' already exists." with assertRaisesRegex(self, ValueError, msg): prob.setup(check=False) class Comp(ExplicitComponent): def setup(self): self.add_input('x', val=3.0) self.add_output('x', val=3.0) self.add_output('y', val=3.0) prob = Problem() model = prob.model = Group() model.add_subsystem('px', IndepVarComp('x', val=3.0)) model.add_subsystem('comp', Comp()) model.connect('px.x', 'comp.x') msg = "Variable name 'x' already exists." with assertRaisesRegex(self, ValueError, msg): prob.setup(check=False) # Make sure we can reconfigure. class Comp(ExplicitComponent): def setup(self): self.add_input('x', val=3.0) self.add_output('y', val=3.0) prob = Problem() model = prob.model = Group() model.add_subsystem('px', IndepVarComp('x', val=3.0)) model.add_subsystem('comp', Comp()) model.connect('px.x', 'comp.x') prob.setup(check=False) # pretend we reconfigured prob.setup(check=False)
from openmdao.core.mpi_wrap import MPI if MPI: # pragma: no cover # if you called this script with 'mpirun', then use the petsc data passing from openmdao.core.petsc_impl import PetscImpl as impl else: # if you didn't use 'mpirun', then use the numpy data passing from openmdao.api import BasicImpl as impl def mpi_print(prob, *args): """ helper function to only print on rank 0 """ if prob.root.comm.rank == 0: print(*args) prob = Problem(impl=impl) size = 1 # number of processors (and number of wind directions to run) ######################################################################### # define turbine size # define turbine locations in global reference frame # original example case # turbineX = np.array([1164.7, 947.2, 1682.4, 1464.9, 1982.6, 2200.1]) # m # turbineY = np.array([1024.7, 1335.3, 1387.2, 1697.8, 2060.3, 1749.7]) # m # # Scaling grid case # nRows = 3 # number of rows and columns in grid # spacing = 3.5 # turbine grid spacing in diameters #
def test_vectorized(self): # Set up the SimpleTMS problem with 11 evaluation points nn = 11 prob = Problem() prob.model = thermal.SimpleTMS(num_nodes=nn) prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['solve_subsystems'] = True prob.setup() prob.set_val('throttle', np.linspace(0.01, 0.99, nn), units=None) prob.set_val('motor_elec_power_rating', 6., units='MW') prob.run_model() # Check that the solvers properly converged the BalanceComp so # the heat taken by the cold plate equals the heat extracted # by the refrigerator q_fridge = prob['refrigerator.q_c'] q_plate = prob['refrigerator_cold_plate.q'] relative_error_met = (q_fridge - q_plate) / q_plate < 1e-9 self.assertTrue(relative_error_met.all())
# FASTpref['DLC_turbulent'] = RotorSE_DLC_1_1_Turb # Alternate turbulent case, replacing rated and extreme DLCs for calculating max deflection and strain FASTpref['DLC_powercurve'] = power_curve # AEP # FASTpref['DLC_powercurve'] = None # AEP # Initialize, read initial FAST files to avoid doing it iteratively fast = InputReader_OpenFAST(FAST_ver=FASTpref['FAST_ver'], dev_branch=FASTpref['dev_branch']) fast.FAST_InputFile = FASTpref['FAST_InputFile'] fast.FAST_directory = FASTpref['FAST_directory'] fast.execute() fst_vt = fast.fst_vt else: FASTpref = {} fst_vt = {} rotor = Problem() npts_coarse_power_curve = 20 # (Int): number of points to evaluate aero analysis at npts_spline_power_curve = 200 # (Int): number of points to use in fitting spline to power curve regulation_reg_II5 = True # calculate Region 2.5 pitch schedule, False will not maximize power in region 2.5 regulation_reg_III = True # calculate Region 3 pitch schedule, False will return erroneous Thrust, Torque, and Moment for above rated flag_Cp_Ct_Cq_Tables = True # Compute Cp-Ct-Cq-Beta-TSR tables rc_verbosity = False # Verbosity flag for the blade cost model rc_tex_table = False # Flag to generate .tex ready tables from the blade cost model rc_generate_plots = False # Flag to generate plots in the blade cost model rc_show_plots = False # Flag to show plots from the blade cost model rc_show_warnings = False # Flag to show warnings from the blade cost model rc_discrete = False # Flag to switch between a discrete and a continuous appraoch in the blade cost model rotor.model = RotorSE(RefBlade=blade, npts_coarse_power_curve=npts_coarse_power_curve, npts_spline_power_curve=npts_spline_power_curve,
def test_zero_work(self): # Set up the SimpleTMS problem with throttle at zero prob = Problem() prob.model = thermal.SimpleTMS() prob.model.linear_solver = DirectSolver() prob.model.nonlinear_solver = NewtonSolver() prob.model.nonlinear_solver.options['solve_subsystems'] = True prob.setup() prob.set_val('Wdot', 0.) prob.set_val('motor_elec_power_rating', 10., units='kW') prob.run_model() # Check that the solvers properly converged the BalanceComp so # the heat taken by the cold plate equals the heat extracted # by the refrigerator q_fridge = prob['refrigerator.q_c'] q_plate = prob['refrigerator_cold_plate.q'] fridge_abs_error_met = np.abs(q_fridge) < 1e-9 plate_abs_error_met = np.abs(q_plate) < 1e-9 self.assertTrue(fridge_abs_error_met.all()) self.assertTrue(plate_abs_error_met.all())
from openmdao.api import ExplicitComponent, Problem, IndepVarComp, Group, view_model, ScipyOptimizeDriver, DirectSolver, SqliteRecorder, CaseReader, ExecComp from MBGroup import MBGroup prob = Problem() prob.model = MBGroup() prob.driver = ScipyOptimizeDriver() prob.driver.options['optimizer'] = 'SLSQP' # prob.driver.options['maxiter'] = 100 prob.driver.options['tol'] = 1e-10 # prob.driver.options['iprint'] = 2 prob.driver.options['debug_print'] = ['desvars', 'ln_cons', 'nl_cons', 'objs','totals'] prob.model.add_design_var('M_sa') prob.model.add_design_var('M_batt') prob.model.add_objective('t_tot') prob.model.add_constraint('M_batt', lower = 1) prob.model.add_constraint('M_sa', lower = 1) prob.model.add_constraint('constraint1', equals=0) prob.setup() # prob.set_solver_print(level=2) prob.model.approx_totals() # view_model(prob) # prob.run_model() prob.run_driver() print('t_tot',prob['t_tot']) print('M_batt',prob['M_batt']) print('M_sa',prob['M_sa']) print('M_d',prob['M_d'])
from openmdao.api import Problem, Group, IndepVarComp, NonlinearBlockGS from engine_hours_comp import EngineHoursComp from tooling_hours_comp import ToolingHoursComp from mfg_hours_comp import MfgHoursComp from quality_hours_comp import QualityHoursComp from devel_support_comp import DevelSupportComp from flight_test_cost_comp import FlightTestCostComp from mfg_material_cost_comp import MfgMaterialCostComp from rdte_fly_cost_comp import RdteFlyCostComp prob = Problem() group = Group() # Adding all of the Explicit components to the main group comp = IndepVarComp() comp.add_output('We', val=4.) comp.add_output('V', val=83.) comp.add_output('Q', val=500.) comp.add_output('FTA', val=2.) comp.add_output('Re', val=86.0 * 1.530) comp.add_output('Rt', val=88.0 * 1.530) comp.add_output('Rq', val=81.0 * 1.530) comp.add_output('Rm', val=73.0 * 1.530) comp.add_output('Ceng', val=19.99) comp.add_output('Neng', val=2.0) comp.add_output('Cav', val=113.08) group.add_subsystem('ivc', comp, promotes=['*', '*']) group.add_subsystem('ehc', EngineHoursComp(), promotes=['*', '*'])
def test_case1(self): prob = Problem() model = prob.model model.add_subsystem( 'ivc', IndepVarComp('in_composition', [ 3.23319235e-04, 1.10132233e-05, 5.39157698e-02, 1.44860137e-02 ])) model.add_subsystem('combustor', Combustor(), promotes=["*"]) model.set_input_defaults('Fl_I:tot:P', 100.0, units='lbf/inch**2') model.set_input_defaults('Fl_I:tot:h', 100.0, units='Btu/lbm') model.set_input_defaults('Fl_I:stat:W', 100.0, units='lbm/s') model.set_input_defaults('Fl_I:FAR', 0.0) model.set_input_defaults('MN', 0.5) # needed because composition is sized by connection model.connect('ivc.in_composition', [ 'Fl_I:tot:composition', 'Fl_I:stat:composition', ]) prob.set_solver_print(level=2) prob.setup(check=False, force_alloc_complex=True) # 6 cases to check against for i, data in enumerate(ref_data): # input flowstation prob['Fl_I:tot:P'] = data[h_map['Fl_I.Pt']] prob['Fl_I:tot:h'] = data[h_map['Fl_I.ht']] prob['Fl_I:stat:W'] = data[h_map['Fl_I.W']] prob['Fl_I:FAR'] = data[h_map['FAR']] prob['MN'] = data[h_map['Fl_O.MN']] prob.run_model() prob.model.combustor.mix_fuel.list_inputs(print_arrays=True) prob.model.combustor.mix_fuel.list_outputs(print_arrays=True) # print(prob['Fl_I:tot:composition']) # print(prob['Fl_I:tot:n']) # print(prob['Fl_I:tot:h']) # print(prob['Fl_I:tot:P']) # exit() # check outputs tol = 1.0e-2 npss = data[h_map['Fl_O.Pt']] pyc = prob['Fl_O:tot:P'] rel_err = abs(npss - pyc) / npss print('Pt out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.Tt']] pyc = prob['Fl_O:tot:T'] rel_err = abs(npss - pyc) / npss print('Tt out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.ht']] pyc = prob['Fl_O:tot:h'] rel_err = abs(npss - pyc) / npss print('ht out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.Ps']] pyc = prob['Fl_O:stat:P'] rel_err = abs(npss - pyc) / npss print('Ps out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Fl_O.Ts']] pyc = prob['Fl_O:stat:T'] rel_err = abs(npss - pyc) / npss print('Ts out:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) npss = data[h_map['Wfuel']] pyc = prob['Fl_I:stat:W'] * (prob['Fl_I:FAR']) rel_err = abs(npss - pyc) / npss print('Wfuel:', npss, pyc, rel_err) self.assertLessEqual(rel_err, tol) print('') partial_data = prob.check_partials(out_stream=None, method='cs', includes=[ 'combustor.*', ], excludes=[ '*.base_thermo.*', ]) assert_check_partials(partial_data, atol=1e-8, rtol=1e-8)
class TestSqliteCaseReader(unittest.TestCase): def setup_sellar_model_with_optimization(self): self.prob = Problem() self.prob.model = SellarDerivatives() optimizer = 'pyoptsparse' self.prob.driver = optimizers[optimizer]() self.prob.model.add_design_var('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) self.prob.model.add_design_var('x', lower=0.0, upper=10.0) self.prob.model.add_objective('obj') self.prob.model.add_constraint('con1', upper=0.0) self.prob.model.add_constraint('con2', upper=0.0) self.prob.model.suppress_solver_output = True self.prob.driver.options['print_results'] = False def setup_sellar_model(self): self.prob = Problem() model = self.prob.model = Group() model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) model.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) model.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) self.prob.model.nonlinear_solver = NonlinearBlockGS() self.prob.model.linear_solver = LinearBlockGS() self.prob.model.add_design_var('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) self.prob.model.add_design_var('x', lower=0.0, upper=10.0) self.prob.model.add_objective('obj') self.prob.model.add_constraint('con1', upper=0.0) self.prob.model.add_constraint('con2', upper=0.0) def setup_sellar_grouped_model(self): self.prob = Problem() model = self.prob.model = Group() model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0])), promotes=['z']) mda = model.add_subsystem('mda', Group(), promotes=['x', 'z', 'y1', 'y2']) mda.linear_solver = ScipyKrylov() mda.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) mda.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) mda.nonlinear_solver = NonlinearBlockGS() model.linear_solver = LinearBlockGS() model.add_design_var('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) model.add_design_var('x', lower=0.0, upper=10.0) model.add_objective('obj') model.add_constraint('con1', upper=0.0) model.add_constraint('con2', upper=0.0) def setup_sellar_grouped_scaled_model(self): self.prob = Problem() model = self.prob.model = Group() model.add_subsystem('px', IndepVarComp('x', 1.0), promotes=['x']) model.add_subsystem('pz', IndepVarComp('z', np.array([5.0, 2.0]), ref=2.0), promotes=['z']) mda = model.add_subsystem('mda', Group(), promotes=['x', 'z', 'y1', 'y2']) mda.linear_solver = ScipyKrylov() mda.add_subsystem('d1', SellarDis1withDerivatives(), promotes=['x', 'z', 'y1', 'y2']) mda.add_subsystem('d2', SellarDis2withDerivatives(), promotes=['z', 'y1', 'y2']) model.add_subsystem('obj_cmp', ExecComp('obj = x**2 + z[1] + y1 + exp(-y2)', z=np.array([0.0, 0.0]), x=0.0, y1=0.0, y2=0.0), promotes=['obj', 'x', 'z', 'y1', 'y2']) model.add_subsystem('con_cmp1', ExecComp('con1 = 3.16 - y1'), promotes=['con1', 'y1']) model.add_subsystem('con_cmp2', ExecComp('con2 = y2 - 24.0'), promotes=['con2', 'y2']) mda.nonlinear_solver = NonlinearBlockGS() model.linear_solver = LinearBlockGS() model.add_design_var('z', lower=np.array([-10.0, 0.0]), upper=np.array([10.0, 10.0])) model.add_design_var('x', lower=0.0, upper=10.0) model.add_objective('obj') model.add_constraint('con1', upper=0.0) model.add_constraint('con2', upper=0.0) def setUp(self): recording_iteration.stack = [] # reset to avoid problems from earlier tests self.dir = mkdtemp() self.filename = os.path.join(self.dir, "sqlite_test") self.recorder = SqliteRecorder(self.filename) self.original_path = os.getcwd() os.chdir(self.dir) def tearDown(self): os.chdir(self.original_path) try: rmtree(self.dir) except OSError as e: # If directory already deleted, keep going if e.errno not in (errno.ENOENT, errno.EACCES, errno.EPERM): raise e def test_bad_filetype(self): # Pass it a plain text file. fd, filepath = mkstemp() with os.fdopen(fd, 'w') as tmp: tmp.write("Lorem ipsum") tmp.close() with self.assertRaises(IOError): _ = CaseReader(filepath) def test_format_version(self): self.setup_sellar_model() self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) self.assertEqual(cr.format_version, format_version, msg='format version not read correctly') def test_reader_instantiates(self): """ Test that CaseReader returns an SqliteCaseReader. """ self.setup_sellar_model() self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) self.assertTrue(isinstance(cr, SqliteCaseReader), msg='CaseReader not' ' returning the correct subclass.') @unittest.skipIf(OPT is None, "pyoptsparse is not installed" ) @unittest.skipIf(OPTIMIZER is None, "pyoptsparse is not providing SNOPT or SLSQP" ) def test_reading_driver_cases(self): """ Tests that the reader returns params correctly. """ self.setup_sellar_model_with_optimization() self.prob.driver.recording_options['record_desvars'] = True self.prob.driver.recording_options['record_responses'] = True self.prob.driver.recording_options['record_objectives'] = True self.prob.driver.recording_options['record_constraints'] = True self.prob.driver.add_recorder(self.recorder) self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) # Test to see if we got the correct number of cases self.assertEqual(cr.driver_cases.num_cases, 8) self.assertEqual(cr.system_cases.num_cases, 0) self.assertEqual(cr.solver_cases.num_cases, 0) # Test to see if the access by case keys works: seventh_slsqp_iteration_case = cr.driver_cases.get_case('rank0:SLSQP|6') np.testing.assert_almost_equal(seventh_slsqp_iteration_case.desvars['pz.z'], [1.97846296, -2.21388305e-13], decimal=2, err_msg='Case reader gives ' 'incorrect Parameter value' ' for {0}'.format('pz.z')) # Test values from one case, the last case last_case = cr.driver_cases.get_case(-1) np.testing.assert_almost_equal(last_case.desvars['pz.z'], self.prob['z'], err_msg='Case reader gives ' 'incorrect Parameter value' ' for {0}'.format('pz.z')) np.testing.assert_almost_equal(last_case.desvars['px.x'], [-0.00309521], decimal=2, err_msg='Case reader gives ' 'incorrect Parameter value' ' for {0}'.format('px.x')) # Test to see if the case keys (iteration coords) come back correctly case_keys = cr.driver_cases.list_cases() print (case_keys) for i, iter_coord in enumerate(case_keys): self.assertEqual(iter_coord, 'rank0:SLSQP|{}'.format(i)) def test_reading_system_cases(self): self.setup_sellar_model() self.prob.model.recording_options['record_inputs'] = True self.prob.model.recording_options['record_outputs'] = True self.prob.model.recording_options['record_residuals'] = True self.prob.model.recording_options['record_metadata'] = False self.prob.model.add_recorder(self.recorder) d1 = self.prob.model.d1 # instance of SellarDis1withDerivatives, a Group d1.add_recorder(self.recorder) obj_cmp = self.prob.model.obj_cmp # an ExecComp obj_cmp.add_recorder(self.recorder) self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) # Test to see if we got the correct number of cases self.assertEqual(cr.driver_cases.num_cases, 0) self.assertEqual(cr.system_cases.num_cases, 15) self.assertEqual(cr.solver_cases.num_cases, 0) # Test values from cases second_last_case = cr.system_cases.get_case(-2) np.testing.assert_almost_equal(second_last_case.inputs['obj_cmp.y2'], [12.05848815, ], err_msg='Case reader gives ' 'incorrect input value for {0}'.format('obj_cmp.y2')) np.testing.assert_almost_equal(second_last_case.outputs['obj_cmp.obj'], [28.58830817, ], err_msg='Case reader gives ' 'incorrect output value for {0}'.format('obj_cmp.obj')) np.testing.assert_almost_equal(second_last_case.residuals['obj_cmp.obj'], [0.0, ], err_msg='Case reader gives ' 'incorrect residual value for {0}'.format('obj_cmp.obj')) # Test to see if the case keys ( iteration coords ) come back correctly case_keys = cr.system_cases.list_cases()[:-1] # Skip the last one for i, iter_coord in enumerate(case_keys): if i % 2 == 0: last_solver = 'd1._solve_nonlinear' else: last_solver = 'obj_cmp._solve_nonlinear' solver_iter_count = i // 2 self.assertEqual(iter_coord, 'rank0:Driver|0|root._solve_nonlinear|0|NonlinearBlockGS|{iter}|' '{solver}|{iter}'.format(iter=solver_iter_count, solver=last_solver)) def test_reading_solver_cases(self): self.setup_sellar_model() self.prob.model._nonlinear_solver.recording_options['record_abs_error'] = True self.prob.model._nonlinear_solver.recording_options['record_rel_error'] = True self.prob.model._nonlinear_solver.recording_options['record_solver_residuals'] = True self.prob.model._nonlinear_solver.add_recorder(self.recorder) self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) # Test to see if we got the correct number of cases self.assertEqual(cr.driver_cases.num_cases, 0) self.assertEqual(cr.system_cases.num_cases, 0) self.assertEqual(cr.solver_cases.num_cases, 7) # Test values from cases last_case = cr.solver_cases.get_case(-1) np.testing.assert_almost_equal(last_case.abs_err, [0.0, ], err_msg='Case reader gives incorrect value for abs_err') np.testing.assert_almost_equal(last_case.rel_err, [0.0, ], err_msg='Case reader gives incorrect value for rel_err') np.testing.assert_almost_equal(last_case.outputs['px.x'], [1.0, ], err_msg='Case reader gives ' 'incorrect output value for {0}'.format('px.x')) np.testing.assert_almost_equal(last_case.residuals['con_cmp2.con2'], [0.0, ], err_msg='Case reader gives ' 'incorrect residual value for {0}'.format('con_cmp2.con2')) # Test to see if the case keys ( iteration coords ) come back correctly case_keys = cr.system_cases.list_cases() for i, iter_coord in enumerate(case_keys): self.assertEqual(iter_coord, 'rank0:Driver|0|root._solve_nonlinear|0|NonlinearBlockGS|{}' .format(i)) @unittest.skipIf(OPT is None, "pyoptsparse is not installed" ) @unittest.skipIf(OPTIMIZER is None, "pyoptsparse is not providing SNOPT or SLSQP" ) def test_reading_driver_metadata(self): self.setup_sellar_model_with_optimization() self.prob.driver.recording_options['record_desvars'] = True self.prob.driver.recording_options['record_responses'] = True self.prob.driver.recording_options['record_objectives'] = True self.prob.driver.recording_options['record_constraints'] = True self.prob.driver.add_recorder(self.recorder) self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) self.assertEqual(len(cr.driver_metadata['connections_list']), 11) self.assertEqual(len(cr.driver_metadata['tree']), 4) def test_reading_system_metadata(self): if OPT is None: raise unittest.SkipTest("pyoptsparse is not installed") if OPTIMIZER is None: raise unittest.SkipTest("pyoptsparse is not providing SNOPT or SLSQP") self.setup_sellar_grouped_scaled_model() self.prob.driver = pyOptSparseDriver() self.prob.driver.options['optimizer'] = OPTIMIZER if OPTIMIZER == 'SLSQP': self.prob.driver.opt_settings['ACC'] = 1e-9 self.prob.model.recording_options['record_inputs'] = True self.prob.model.recording_options['record_outputs'] = True self.prob.model.recording_options['record_residuals'] = True self.prob.model.recording_options['record_metadata'] = True self.prob.model.add_recorder(self.recorder) pz = self.prob.model.pz # IndepVarComp which is an ExplicitComponent pz.add_recorder(self.recorder) mda = self.prob.model.mda # Group d1 = mda.d1 d1.add_recorder(self.recorder) self.prob.setup(check=False, mode='rev') self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) self.assertEqual( sorted(cr.system_metadata.keys()), sorted(['root', 'mda.d1', 'pz']) ) assert_rel_error( self, cr.system_metadata['pz']['output']['nonlinear']['phys'][0][1], [2.0, 2.0], 1.0e-3) def test_reading_solver_metadata(self): self.setup_sellar_model() nonlinear_solver = self.prob.model.nonlinear_solver self.prob.model.nonlinear_solver.add_recorder(self.recorder) linear_solver = self.prob.model.linear_solver linear_solver.add_recorder(self.recorder) d1 = self.prob.model.d1 # instance of SellarDis1withDerivatives, a Group d1.nonlinear_solver = NonlinearBlockGS() d1.nonlinear_solver.options['maxiter'] = 5 d1.nonlinear_solver.add_recorder(self.recorder) self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) self.assertEqual( sorted(cr.solver_metadata.keys()), sorted(['root.LinearBlockGS', 'root.NonlinearBlockGS', 'd1.NonlinearBlockGS']) ) self.assertEqual(cr.solver_metadata['d1.NonlinearBlockGS']['solver_options']['maxiter'], 5) self.assertEqual(cr.solver_metadata['root.NonlinearBlockGS']['solver_options']['maxiter'],10) self.assertEqual(cr.solver_metadata['root.LinearBlockGS']['solver_class'],'LinearBlockGS') @unittest.skipIf(OPT is None, "pyoptsparse is not installed" ) @unittest.skipIf(OPTIMIZER is None, "pyoptsparse is not providing SNOPT or SLSQP" ) def test_reading_driver_recording_with_system_vars(self): self.setup_sellar_grouped_model() self.prob.driver = pyOptSparseDriver() self.prob.driver.options['optimizer'] = OPTIMIZER if OPTIMIZER == 'SLSQP': self.prob.driver.opt_settings['ACC'] = 1e-9 self.prob.driver.add_recorder(self.recorder) driver = self.prob.driver driver.recording_options['record_desvars'] = True driver.recording_options['record_responses'] = True driver.recording_options['record_objectives'] = True driver.recording_options['record_constraints'] = True driver.recording_options['includes'] = ['mda.d2.y2',] self.prob.driver.options['optimizer'] = OPTIMIZER if OPTIMIZER == 'SLSQP': self.prob.driver.opt_settings['ACC'] = 1e-9 self.prob.setup(check=False) self.prob.run_driver() self.prob.cleanup() cr = CaseReader(self.filename) # Test values from one case, the last case last_case = cr.driver_cases.get_case(-1) np.testing.assert_almost_equal(last_case.desvars['pz.z'], self.prob['pz.z'], err_msg='Case reader gives ' 'incorrect Parameter value' ' for {0}'.format('pz.z')) np.testing.assert_almost_equal(last_case.desvars['px.x'], self.prob['px.x'], err_msg='Case reader gives ' 'incorrect Parameter value' ' for {0}'.format('px.x')) np.testing.assert_almost_equal(last_case.sysincludes['mda.d2.y2'], self.prob['mda.d2.y2'], err_msg='Case reader gives ' 'incorrect Parameter value' ' for {0}'.format('mda.d2.y2'))
def main(maxiter): # select which problem to solve obj_flag = 1 print(locals()) print("solving %s problem" % objectives[obj_flag]) ######################################################## ################# FEA #################### ######################################################## # NB: only Q4 elements + integer-spaced mesh are assumed nelx = 160 nely = 80 length_x = 160. length_y = 80. ls2fe_x = length_x / float(nelx) ls2fe_y = length_y / float(nely) num_nodes_x = nelx + 1 num_nodes_y = nely + 1 nELEM = nelx * nely nNODE = num_nodes_x * num_nodes_y # NB: nodes for plotting (quickfix...) nodes = get_mesh(num_nodes_x, num_nodes_y, nelx, nely) # Declare FEA object (OpenLSTO_FEA) ====================== fea_solver = py_FEA(lx=length_x, ly=length_y, nelx=nelx, nely=nely, element_order=2) [node, elem, elem_dof] = fea_solver.get_mesh() # validate the mesh if nELEM != elem.shape[0]: error("error found in the element") if nNODE != node.shape[0]: error("error found in the node") nDOF_t = nNODE * 1 # each node has one temperature DOF nDOF_e = nNODE * 2 # each node has two displacement DOFs # constitutive properties ================================= E = 1. nu = 0.3 f = -1 # dead load K_cond = 0.1 # thermal conductivity alpha = 1e-5 # thermal expansion coefficient fea_solver.set_material(E=E, nu=nu, rho=1.0) # Boundary Conditions ===================================== if 1: coord_e = np.array([[0., 0.], [length_x, 0.]]) tol_e = np.array([[1e-3, 1e3], [1e-3, 1e+3]]) fea_solver.set_boundary(coord=coord_e, tol=tol_e) BCid_e = fea_solver.get_boundary() nDOF_e_wLag = nDOF_e + len(BCid_e) # elasticity DOF coord = np.array([length_x * 0.5, 0.0]) # length_y]) tol = np.array([0.1, 1e-3]) GF_e_ = fea_solver.set_force(coord=coord, tol=tol, direction=1, f=-f) GF_e = np.zeros(nDOF_e_wLag) GF_e[:nDOF_e] = GF_e_ else: # cantilever bending coord_e = np.array([[0, 0]]) tol_e = np.array([[1e-3, 1e10]]) fea_solver.set_boundary(coord=coord_e, tol=tol_e) BCid_e = fea_solver.get_boundary() nDOF_e_wLag = nDOF_e + len(BCid_e) # elasticity DOF coord = np.array([length_x, length_y / 2]) tol = np.array([0.1, 0.1]) GF_e_ = fea_solver.set_force(coord=coord, tol=tol, direction=1, f=-1.0) GF_e = np.zeros(nDOF_e_wLag) GF_e[:nDOF_e] = GF_e_ xlo = np.array(range(0, nNODE, num_nodes_x)) xhi = np.array(range(nelx, nNODE, num_nodes_x)) # xfix = np.array([num_nodes_x*(nely/2-1), num_nodes_x*nely/2, # num_nodes_x*(nely/2-1) + nelx, num_nodes_x*nely/2 + nelx]) xfix = np.append(xlo, xhi) yfix = np.array(range(num_nodes_x * nely + 70, nNODE - 70)) # yloid = np.array(range(70, 91)) # fixID_d = np.append(xfix, yfix) #fixID_d = np.unique(fixID_d) #fixID = np.append(fixID_d, arange(70, 91)) # BCid_t = np.array(np.append(xfix, arange(70,91)), dtype=int) BCid_t = np.array(np.append(yfix, arange(70, 91)), dtype=int) nDOF_t_wLag = nDOF_t + len(BCid_t) # temperature DOF (zero temp) GF_t = np.zeros(nDOF_t_wLag) # FORCE_HEAT (NB: Q matrix) for ee in range(nELEM): # between element 70 to 91 GF_t[elem[ee]] += 10. # heat generation GF_t[BCid_t] = 0.0 GF_t /= np.sum(GF_t) #GF_t[nDOF_t:nDOF_t+len(fixID_d)+1] = 100. # GF_t[:] = 0.0 ######################################################## ################# LSM #################### ######################################################## movelimit = 0.5 # Declare Level-set object lsm_solver = py_LSM(nelx=nelx, nely=nely, moveLimit=movelimit) if ((nelx == 160) and (nely == 80)): # 160 x 80 case hole = array( [[16, 14, 5], [48, 14, 5], [80, 14, 5], [112, 14, 5], [144, 14, 5], [32, 27, 5], [64, 27, 5], [96, 27, 5], [128, 27, 5], [16, 40, 5], [48, 40, 5], [80, 40, 5], [112, 40, 5], [144, 40, 5], [32, 53, 5], [64, 53, 5], [96, 53, 5], [128, 53, 5], [16, 66, 5], [48, 66, 5], [80, 66, 5], [112, 66, 5], [144, 66, 5]], dtype=float) # NB: level set value at the corners should not be 0.0 hole = append( hole, [[0., 0., 0.1], [0., 80., 0.1], [160., 0., 0.1], [160., 80., 0.1]], axis=0) lsm_solver.add_holes(locx=list(hole[:, 0]), locy=list(hole[:, 1]), radius=list(hole[:, 2])) elif ((nelx == 80) and (nely == 40)): hole = np.array( [[8, 7, 2.5], [24, 7, 2.5], [40, 7, 2.5], [56, 7, 2.5], [72, 7, 2.5], [16, 13.5, 2.5], [32, 13.5, 2.5], [48, 13.5, 2.5], [64, 13.5, 2.5], [8, 20, 2.5], [24, 20, 2.5], [40, 20, 2.5], [56, 20, 2.5], [72, 20, 2.5], [16, 26.5, 2.5], [32, 26.5, 2.5], [48, 26.5, 2.5], [64, 26.5, 2.5], [8, 33, 2.5], [24, 33, 2.5], [40, 33, 2.5], [56, 33, 2.5], [72, 33, 2.5]], dtype=np.float) # NB: level set value at the corners should not be 0.0 hole = append( hole, [[0., 0., 0.1], [0., 40., 0.1], [80., 0., 0.1], [80., 40., 0.1]], axis=0) lsm_solver.add_holes(locx=list(hole[:, 0]), locy=list(hole[:, 1]), radius=list(hole[:, 2])) else: lsm_solver.add_holes([], [], []) lsm_solver.set_levelset() for i_HJ in range(maxiter): (bpts_xy, areafraction, seglength) = lsm_solver.discretise() ######################################################## ############### OpenMDAO ################ ######################################################## # Declare Group if (objectives[obj_flag] == "compliance"): model = ComplianceGroup(fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force=GF_e, movelimit=movelimit, BCid=BCid_e) elif (objectives[obj_flag] == "stress"): # TODO: sensitivity has not been verified yet model = StressGroup(fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force=GF_e, movelimit=movelimit, pval=5.0, E=E, nu=nu) elif (objectives[obj_flag] == "conduction"): model = ConductionGroup(fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force=GF_t, movelimit=movelimit, K_cond=K_cond, BCid=BCid_t) elif (objectives[obj_flag] == "coupled_heat"): model = HeatCouplingGroup( fea_solver=fea_solver, lsm_solver=lsm_solver, nelx=nelx, nely=nely, force_e=GF_e, force_t=GF_t, movelimit=movelimit, K_cond=K_cond, BCid_e=BCid_e, BCid_t=BCid_t, E=E, nu=nu, alpha=alpha, w=0.9 ) # if w = 0.0, thermoelastic + conduction, if w = 1.0, conduction only # One Problem per one OpenMDAO object prob = Problem(model) # optimize ... prob.driver = pyOptSparseDriver() prob.driver.options['optimizer'] = 'IPOPT' prob.driver.opt_settings['linear_solver'] = 'ma27' prob.setup(check=False) if i_HJ == 0: view_model(prob) prob.run_model() # Total derivative using MAUD ===================== total = prob.compute_totals() if (objectives[obj_flag] == "compliance"): ff = total['compliance_comp.compliance', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] elif (objectives[obj_flag] == "stress"): ff = total['pnorm_comp.pnorm', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] elif (objectives[obj_flag] == "conduction"): ff = total['compliance_comp.compliance', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] elif (objectives[obj_flag] == "coupled_heat"): ff = total['objective_comp.y', 'inputs_comp.Vn'][0] gg = total['weight_comp.weight', 'inputs_comp.Vn'][0] nBpts = int(bpts_xy.shape[0]) # # WIP checking sensitivity 10/23 Sf = -ff[:nBpts] # equal to M2DO-perturbation Cf = np.multiply(Sf, seglength) #np.savetxt('/home/hayoung/Desktop/a',Sf) #exit() Sg = -gg[:nBpts] Cg = np.multiply(Sf, seglength) # ## WIP # previous ver. # Cf = -ff[:nBpts] # Cg = -gg[:nBpts] # Sf = np.divide(Cf, seglength) # Sg = np.divide(Cg, seglength) # bracketing Sf and Sg Sg[Sg < -1.5] = -1.5 Sg[Sg > 0.5] = 0.5 # Sg[:] = -1.0 Cg = np.multiply(Sg, seglength) ######################################################## ############## suboptimize ################ ######################################################## if 1: suboptim = Solvers(bpts_xy=bpts_xy, Sf=Sf, Sg=Sg, Cf=Cf, Cg=Cg, length_x=length_x, length_y=length_y, areafraction=areafraction, movelimit=movelimit) # suboptimization if 1: # simplex Bpt_Vel = suboptim.simplex(isprint=False) else: # bisection.. Bpt_Vel = suboptim.bisection(isprint=False) timestep = 1.0 np.savetxt('a.txt', Bpt_Vel) elif 1: # works when Sf <- Sf / length is used (which means Cf <- actual Sf) bpts_sens = np.zeros((nBpts, 2)) # issue: scaling problem # bpts_sens[:, 0] = Sf bpts_sens[:, 1] = Sg lsm_solver.set_BptsSens(bpts_sens) scales = lsm_solver.get_scale_factors() (lb2, ub2) = lsm_solver.get_Lambda_Limits() constraint_distance = (0.4 * nelx * nely) - areafraction.sum() model = LSM2D_slpGroup(lsm_solver=lsm_solver, num_bpts=nBpts, ub=ub2, lb=lb2, Sf=bpts_sens[:, 0], Sg=bpts_sens[:, 1], constraintDistance=constraint_distance, movelimit=movelimit) subprob = Problem(model) subprob.setup() subprob.driver = ScipyOptimizeDriver() subprob.driver.options['optimizer'] = 'SLSQP' subprob.driver.options['disp'] = True subprob.driver.options['tol'] = 1e-10 subprob.run_driver() lambdas = subprob['inputs_comp.lambdas'] displacements_ = subprob['displacement_comp.displacements'] # displacements_[displacements_ > movelimit] = movelimit # displacements_[displacements_ < -movelimit] = -movelimit timestep = abs(lambdas[0] * scales[0]) Bpt_Vel = displacements_ / timestep np.savetxt('a.txt', Bpt_Vel) # print(timestep) del subprob else: # branch: perturb-suboptim bpts_sens = np.zeros((nBpts, 2)) # issue: scaling problem # bpts_sens[:, 0] = Sf bpts_sens[:, 1] = Sg lsm_solver.set_BptsSens(bpts_sens) scales = lsm_solver.get_scale_factors() (lb2, ub2) = lsm_solver.get_Lambda_Limits() constraint_distance = (0.4 * nelx * nely) - areafraction.sum() constraintDistance = np.array([constraint_distance]) scaled_constraintDist = lsm_solver.compute_scaledConstraintDistance( constraintDistance) def objF_nocallback(x): displacement = lsm_solver.compute_displacement(x) displacement_np = np.asarray(displacement) return lsm_solver.compute_delF(displacement_np) def conF_nocallback(x): displacement = lsm_solver.compute_displacement(x) displacement_np = np.asarray(displacement) return lsm_solver.compute_delG(displacement_np, scaled_constraintDist, 1) cons = ({'type': 'eq', 'fun': lambda x: conF_nocallback(x)}) res = sp_optim.minimize(objF_nocallback, np.zeros(2), method='SLSQP', options={'disp': True}, bounds=((lb2[0], ub2[0]), (lb2[1], ub2[1])), constraints=cons) lambdas = res.x displacements_ = lsm_solver.compute_unscaledDisplacement(lambdas) displacements_[displacements_ > movelimit] = movelimit displacements_[displacements_ < -movelimit] = -movelimit timestep = 1.0 #abs(lambdas[0]*scales[0]) Bpt_Vel = displacements_ / timestep # scaling # Bpt_Vel = Bpt_Vel#/np.max(np.abs(Bpt_Vel)) lsm_solver.advect(Bpt_Vel, timestep) lsm_solver.reinitialise() print('loop %d is finished' % i_HJ) area = areafraction.sum() / (nelx * nely) try: u = prob['temp_comp.disp'] compliance = np.dot(u, GF_t[:nNODE]) except: u = prob['disp_comp.disp'] # compliance = np.dot(u, GF_e[:nDOF_e]) pass if 1: # quickplot plt.figure(1) plt.clf() plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 10) plt.axis("equal") plt.savefig(saveFolder + "figs/bpts_%d.png" % i_HJ) if obj_flag == 3 or obj_flag == 2: plt.figure(2) plt.clf() [xx, yy] = np.meshgrid(range(0, 161), range(0, 81)) plt.contourf(xx, yy, np.reshape(u, [81, 161])) plt.colorbar() plt.axis("equal") plt.scatter(bpts_xy[:, 0], bpts_xy[:, 1], 5) plt.savefig(saveFolder + "figs/temp_%d.png" % i_HJ) # print([compliance[0], area]) if (objectives[obj_flag] == "compliance"): compliance = prob['compliance_comp.compliance'] print(compliance, area) fid = open(saveFolder + "log.txt", "a+") fid.write(str(compliance) + ", " + str(area) + "\n") fid.close() elif (objectives[obj_flag] == "stress"): print(prob['pnorm_comp.pnorm'][0], area) fid = open(saveFolder + "log.txt", "a+") fid.write( str(prob['pnorm_comp.pnorm'][0]) + ", " + str(area) + "\n") fid.close() elif (objectives[obj_flag] == "coupled_heat"): obj1 = prob['objective_comp.x1'][0] obj2 = prob['objective_comp.x2'][0] obj = prob['objective_comp.y'][0] print([obj1, obj2, obj, area]) fid = open(saveFolder + "log.txt", "a+") fid.write( str(obj1) + ", " + str(obj2) + ", " + str(obj) + ", " + str(area) + "\n") fid.close() # Saving Phi phi = lsm_solver.get_phi() if i_HJ == 0: raw = {} raw['mesh'] = nodes raw['nodes'] = nodes raw['elem'] = elem raw['GF_e'] = GF_e raw['GF_t'] = GF_t raw['BCid_e'] = BCid_e raw['BCid_t'] = BCid_t raw['E'] = E raw['nu'] = nu raw['f'] = f raw['K_cond'] = K_cond raw['alpha'] = alpha raw['nelx'] = nelx raw['nely'] = nely raw['length_x'] = length_x raw['length_y'] = length_y raw['coord_e'] = coord_e raw['tol_e'] = tol_e filename = saveFolder + 'const.pkl' with open(filename, 'wb') as f: pickle.dump(raw, f) raw = {} raw['phi'] = phi if obj_flag == 3: raw['T'] = prob['temp_comp.disp'] filename = saveFolder + 'phi%03i.pkl' % i_HJ with open(filename, 'wb') as f: pickle.dump(raw, f) del model del prob mem = virtual_memory() print(str(mem.available / 1024. / 1024. / 1024.) + "GB") if mem.available / 1024. / 1024. / 1024. < 3.0: print("memory explodes at iteration %3i " % i_HJ) return ()
def create_problem(inverter): root = Group() prob = Problem(root) prob.root.add('comp', inverter) return prob
def test_fan_out_grouped(self): prob = Problem(impl=impl) prob.root = root = Group() root.add('p', IndepVarComp('x', 1.0)) root.add('comp1', ExecComp(['y=3.0*x'])) sub = root.add('sub', ParallelGroup()) sub.add('comp2', ExecComp(['y=-2.0*x'])) sub.add('comp3', ExecComp(['y=5.0*x'])) root.add('c2', ExecComp(['y=-x'])) root.add('c3', ExecComp(['y=3.0*x'])) root.connect('sub.comp2.y', 'c2.x') root.connect('sub.comp3.y', 'c3.x') root.connect("comp1.y", "sub.comp2.x") root.connect("comp1.y", "sub.comp3.x") root.connect("p.x", "comp1.x") prob.root.ln_solver = LinearGaussSeidel() prob.root.sub.ln_solver = LinearGaussSeidel() prob.setup(check=False) prob.run() param = 'p.x' unknown_list = ['sub.comp2.y', "sub.comp3.y"] J = prob.calc_gradient([param], unknown_list, mode='fwd', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], -6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 15.0, 1e-6) J = prob.calc_gradient([param], unknown_list, mode='rev', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], -6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 15.0, 1e-6) unknown_list = ['c2.y', "c3.y"] J = prob.calc_gradient([param], unknown_list, mode='fwd', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], 6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 45.0, 1e-6) J = prob.calc_gradient([param], unknown_list, mode='rev', return_format='dict') assert_rel_error(self, J[unknown_list[0]][param][0][0], 6.0, 1e-6) assert_rel_error(self, J[unknown_list[1]][param][0][0], 45.0, 1e-6)
def test_beam_tutorial_viewmodel_using_data_from_hdf5_case_recorder_file( self): SKIP = False try: from openmdao.recorders.hdf5_recorder import HDF5Recorder import h5py except ImportError: # Necessary for the file to parse from openmdao.recorders.base_recorder import BaseRecorder HDF5Recorder = BaseRecorder SKIP = True if SKIP: raise unittest.SkipTest( "Could not import HDF5Recorder. Is h5py installed?") top = Problem() top.root = BeamTutorial() top.driver = ScipyOptimizer() top.driver.options['optimizer'] = 'SLSQP' top.driver.options['tol'] = 1.0e-8 top.driver.options[ 'maxiter'] = 10000 #maximum number of solver iterations top.driver.options['disp'] = False #room length and width bounds top.driver.add_desvar('ivc_rlength.room_length', lower=5.0 * 12.0, upper=50.0 * 12.0) #domain: 1in <= length <= 50ft top.driver.add_desvar('ivc_rwidth.room_width', lower=5.0 * 12.0, upper=30.0 * 12.0) #domain: 1in <= width <= 30ft top.driver.add_objective('d_neg_area.neg_room_area' ) #minimize negative area (or maximize area) top.driver.add_constraint('d_len_minus_wid.length_minus_width', lower=0.0) #room_length >= room_width top.driver.add_constraint('d_deflection.deflection', lower=720.0) #deflection >= 720 top.driver.add_constraint('d_bending.bending_stress_ratio', upper=0.5) #bending < 0.5 top.driver.add_constraint('d_shear.shear_stress_ratio', upper=1.0 / 3.0) #shear < 1/3 tempdir = mkdtemp() case_recorder_filename = "tmp.hdf5" filename = os.path.join(tempdir, case_recorder_filename) recorder = HDF5Recorder(filename) top.driver.add_recorder(recorder) top.setup(check=False) top.run() view_model(filename, show_browser=False) self.assertTrue(os.path.isfile('partition_tree_n2.html')) os.remove('partition_tree_n2.html')
in_name = self.options['in_name'] out_name = self.options['out_name'] partials[out_name, in_name] = 1.0 - ( (1.0 / np.tanh(inputs[in_name]))**2).flatten() if __name__ == "__main__": from openmdao.api import Problem, IndepVarComp, Group n = 100 val = np.random.rand(n) indeps = IndepVarComp() indeps.add_output( 'x', val=val, shape=(n, ), ) prob = Problem() prob.model = Group() prob.model.add_subsystem( 'indeps', indeps, promotes=['*'], ) prob.model.add_subsystem( 'coth', CotanhComp(in_name='x', out_name='y', shape=(n, )), promotes=['*'], ) prob.setup() prob.check_partials(compact_print=True)
for aileron in ailList: surface['control_surfaces'] = [aileron] print(surfname+' '+aileron['name']+'\n') cl = np.ones((len(vels),len(dels))) CL = np.ones((len(vels),len(dels))) CD = np.ones((len(vels),len(dels))) CM = np.ones((len(vels),len(dels),3)) defmeshes = np.zeros((len(vels),len(dels),num_x,num_y,3)) meshForce = np.zeros((len(vels),len(dels),num_x,num_y,3)) panelForce = np.zeros((len(vels),len(dels),num_x-1,num_y-1,3)) ################################################################### # SET UP PROBLEM # ################################################################### # Create the problem and assign the model group prob = Problem() # Add problem information as an independent variables component indep_var_comp = IndepVarComp() indep_var_comp.add_output('v', val=25., units='m/s') indep_var_comp.add_output('alpha', val=alpha, units='deg') indep_var_comp.add_output('re', val=5e5, units='1/m') indep_var_comp.add_output('rho', val=rho, units='kg/m**3') indep_var_comp.add_output('cg', val=cg_loc, units='m') indep_var_comp.add_output('delta_aileron', val=12.5,units='deg') indep_var_comp.add_output('omega', val=np.array([0.,0.,0.]),units='rad/s') prob.model.add_subsystem('prob_vars', indep_var_comp, promotes=['*'])
def test_brachistochrone_quick_start(self): import numpy as np from openmdao.api import Problem, Group, ScipyOptimizeDriver import dymos as dm import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt # # Define the OpenMDAO problem # p = Problem(model=Group()) # # Define a Trajectory object # traj = dm.Trajectory() p.model.add_subsystem('traj', subsys=traj) # # Define a Dymos Phase object with GaussLobatto Transcription # phase = dm.Phase(ode_class=BrachistochroneODE, transcription=dm.GaussLobatto(num_segments=10, order=3)) traj.add_phase(name='phase0', phase=phase) # # Set the time options # Time has no targets in our ODE. # We fix the initial time so that the it is not a design variable in the optimization. # The duration of the phase is allowed to be optimized, but is bounded on [0.5, 10]. # phase.set_time_options(fix_initial=True, duration_bounds=(0.5, 10.0), units='s') # # Set the time options # Initial values of positions and velocity are all fixed. # The final value of position are fixed, but the final velocity is a free variable. # The equations of motion are not functions of position, so 'x' and 'y' have no targets. # The rate source points to the output in the ODE which provides the time derivative of the # given state. phase.set_state_options('x', fix_initial=True, fix_final=True, units='m', rate_source='xdot') phase.set_state_options('y', fix_initial=True, fix_final=True, units='m', rate_source='ydot') phase.set_state_options('v', fix_initial=True, fix_final=False, units='m/s', rate_source='vdot', targets=['v']) # Define theta as a control. phase.add_control(name='theta', units='rad', lower=0, upper=np.pi, targets=['theta']) # Minimize final time. phase.add_objective('time', loc='final') # Set the driver. p.driver = ScipyOptimizeDriver() # Allow OpenMDAO to automatically determine our sparsity pattern. # Doing so can significant speed up the execution of Dymos. p.driver.options['dynamic_simul_derivs'] = True # Setup the problem p.setup(check=True) # Now that the OpenMDAO problem is setup, we can set the values of the states. p.set_val('traj.phase0.states:x', phase.interpolate(ys=[0, 10], nodes='state_input'), units='m') p.set_val('traj.phase0.states:y', phase.interpolate(ys=[10, 5], nodes='state_input'), units='m') p.set_val('traj.phase0.states:v', phase.interpolate(ys=[0, 5], nodes='state_input'), units='m/s') p.set_val('traj.phase0.controls:theta', phase.interpolate(ys=[90, 90], nodes='control_input'), units='deg') # Run the driver to solve the problem p.run_driver() # Check the validity of our results by using scipy.integrate.solve_ivp to # integrate the solution. sim_out = traj.simulate() # Plot the results fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 4.5)) axes[0].plot(p.get_val('traj.phase0.timeseries.states:x'), p.get_val('traj.phase0.timeseries.states:y'), 'ro', label='solution') axes[0].plot(sim_out.get_val('traj.phase0.timeseries.states:x'), sim_out.get_val('traj.phase0.timeseries.states:y'), 'b-', label='simulation') axes[0].set_xlabel('x (m)') axes[0].set_ylabel('y (m/s)') axes[0].legend() axes[0].grid() axes[1].plot(p.get_val('traj.phase0.timeseries.time'), p.get_val('traj.phase0.timeseries.controls:theta', units='deg'), 'ro', label='solution') axes[1].plot(sim_out.get_val('traj.phase0.timeseries.time'), sim_out.get_val('traj.phase0.timeseries.controls:theta', units='deg'), 'b-', label='simulation') axes[1].set_xlabel('time (s)') axes[1].set_ylabel(r'$\theta$ (deg)') axes[1].legend() axes[1].grid() plt.show()
def execute(self): # --- Import Modules import numpy as np import os from openmdao.api import IndepVarComp, Component, Group, Problem, Brent, ScipyGMRES from rotorse.rotor_aeropower import RotorAeroPower from rotorse.rotor_geometry import RotorGeometry, NREL5MW, DTU10MW, TUM3_35MW, NINPUT from rotorse import RPM2RS, RS2RPM, TURBULENCE_CLASS, DRIVETRAIN_TYPE # --- # --- Init Problem rotor = Problem() myref = TUM3_35MW() npts_coarse_power_curve = 20 # (Int): number of points to evaluate aero analysis at npts_spline_power_curve = 200 # (Int): number of points to use in fitting spline to power curve rotor.root = RotorAeroPower(myref, npts_coarse_power_curve, npts_spline_power_curve, regulation_reg_II5=False, regulation_reg_III=False) rotor.setup() # --- # --- default inputs # === blade grid === rotor[ 'hubFraction'] = myref.hubFraction #0.023785 # (Float): hub location as fraction of radius rotor[ 'bladeLength'] = myref.bladeLength #96.7 # (Float, m): blade length (if not precurved or swept) otherwise length of blade before curvature rotor['precone'] = myref.precone #4. # (Float, deg): precone angle rotor['tilt'] = myref.tilt #6.0 # (Float, deg): shaft tilt rotor['yaw'] = 0.0 # (Float, deg): yaw error rotor['nBlades'] = myref.nBlades #3 # (Int): number of blades # === blade geometry === rotor[ 'r_max_chord'] = myref.r_max_chord #0.2366 # (Float): location of max chord on unit radius rotor[ 'chord_in'] = myref.chord #np.array([4.6, 4.869795, 5.990629, 3.00785428, 0.0962]) # (Array, m): chord at control points. defined at hub, then at linearly spaced locations from r_max_chord to tip rotor[ 'theta_in'] = myref.theta #np.array([14.5, 12.874, 6.724, -0.03388039, -0.037]) # (Array, deg): twist at control points. defined at linearly spaced locations from r[idx_cylinder] to tip rotor[ 'precurve_in'] = myref.precurve #np.array([-0., -0.054497, -0.175303, -0.84976143, -6.206217]) # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) rotor[ 'presweep_in'] = myref.presweep #np.array([0., 0., 0., 0., 0.]) # (Array, m): precurve at control points. defined at same locations at chord, starting at 2nd control point (root must be zero precurve) rotor[ 'sparT_in'] = myref.spar_thickness #np.array([0.03200042 0.07038508 0.08515644 0.07777004 0.01181032]) # (Array, m): spar cap thickness parameters rotor[ 'teT_in'] = myref.te_thickness #np.array([0.04200055 0.08807739 0.05437378 0.01610219 0.00345225]) # (Array, m): trailing-edge thickness parameters # === atmosphere === rotor['rho'] = 1.225 # (Float, kg/m**3): density of air rotor['mu'] = 1.81206e-5 # (Float, kg/m/s): dynamic viscosity of air rotor['hub_height'] = myref.hub_height #119.0 rotor['shearExp'] = 0.25 # (Float): shear exponent rotor[ 'turbine_class'] = myref.turbine_class #TURBINE_CLASS['I'] # (Enum): IEC turbine class rotor[ 'cdf_reference_height_wind_speed'] = myref.hub_height #119.0 # (Float): reference hub height for IEC wind speed (used in CDF calculation) # === control === rotor[ 'control_Vin'] = myref.control_Vin #4.0 # (Float, m/s): cut-in wind speed rotor[ 'control_Vout'] = myref.control_Vout #25.0 # (Float, m/s): cut-out wind speed rotor[ 'control_ratedPower'] = myref.rating #10e6 # (Float, W): rated power rotor[ 'control_minOmega'] = myref.control_minOmega #6.0 # (Float, rpm): minimum allowed rotor rotation speed rotor[ 'control_maxOmega'] = myref.control_maxOmega #8.88766 # (Float, rpm): maximum allowed rotor rotation speed rotor['control_maxTS'] = myref.control_maxTS rotor[ 'control_tsr'] = myref.control_tsr #10.58 # (Float): tip-speed ratio in Region 2 (should be optimized externally) rotor[ 'control_pitch'] = myref.control_pitch #0.0 # (Float, deg): pitch angle in region 2 (and region 3 for fixed pitch machines) # === aero and structural analysis options === rotor[ 'nSector'] = 4 # (Int): number of sectors to divide rotor face into in computing thrust and power rotor[ 'AEP_loss_factor'] = 1.0 # (Float): availability and other losses (soiling, array, etc.) rotor[ 'drivetrainType'] = myref.drivetrain #DRIVETRAIN_TYPE['GEARED'] # (Enum) # --- # === run and outputs === rotor.run() print('AEP =', rotor['AEP']) print('diameter =', rotor['diameter']) print('ratedConditions.V =', rotor['rated_V']) print('ratedConditions.Omega =', rotor['rated_Omega']) print('ratedConditions.pitch =', rotor['rated_pitch']) print('ratedConditions.T =', rotor['rated_T']) print('ratedConditions.Q =', rotor['rated_Q']) import matplotlib.pyplot as plt plt.plot(rotor['V'], rotor['P'] / 1e6) plt.xlabel('Wind Speed (m/s)') plt.ylabel('Power (MW)') # plt.show() # --- outpath = '..\..\..\docs\images' # Power Curve f, ax = plt.subplots(1, 1, figsize=(5.3, 4)) ax.plot(rotor['V'], rotor['P'] / 1e6) ax.set(xlabel='Wind Speed (m/s)', ylabel='Power (MW)') # ax.set_ylim([0, 10.3]) # ax.set_xlim([0, 25]) f.tight_layout() ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) # f.savefig(os.path.abspath(os.path.join(outpath,'power_curve_dtu10mw.png'))) # f.savefig(os.path.abspath(os.path.join(outpath,'power_curve_dtu10mw.pdf'))) # Chord fc, axc = plt.subplots(1, 1, figsize=(5.3, 4)) rc_c = np.r_[0.0, myref.r_cylinder, np.linspace(rotor['r_max_chord'], 1.0, NINPUT - 2)] r = (rotor['r_pts'] - rotor['Rhub']) / rotor['bladeLength'] axc.plot(r, rotor['chord'], c='k') axc.plot(rc_c, rotor['chord_in'], '.', c='k') for i, (x, y) in enumerate(zip(rc_c, rotor['chord_in'])): txt = '$c_%d$' % i if i <= 1: axc.annotate(txt, (x, y), xytext=(x + 0.01, y - 0.4), textcoords='data') else: axc.annotate(txt, (x, y), xytext=(x + 0.01, y + 0.2), textcoords='data') axc.set(xlabel='Blade Fraction, $r/R$', ylabel='Chord (m)') # axc.set_ylim([0, 7.5]) # axc.set_xlim([0, 1.1]) fc.tight_layout() axc.spines['right'].set_visible(False) axc.spines['top'].set_visible(False) # fc.savefig(os.path.abspath(os.path.join(outpath,'chord_dtu10mw.png'))) # fc.savefig(os.path.abspath(os.path.join(outpath,'chord_dtu10mw.pdf'))) # Twist ft, axt = plt.subplots(1, 1, figsize=(5.3, 4)) rc_t = rc_c #np.linspace(myref.r_cylinder, 1.0, NINPUT) r = (rotor['r_pts'] - rotor['Rhub']) / rotor['bladeLength'] axt.plot(r, rotor['theta'], c='k') axt.plot(rc_t, rotor['theta_in'], '.', c='k') for i, (x, y) in enumerate(zip(rc_t, rotor['theta_in'])): txt = '$\Theta_%d$' % i axt.annotate(txt, (x, y), xytext=(x + 0.01, y + 0.1), textcoords='data') axt.set(xlabel='Blade Fraction, $r/R$', ylabel='Twist ($\deg$)') # axt.set_ylim([-1, 15]) # axt.set_xlim([0, 1.1]) ft.tight_layout() axt.spines['right'].set_visible(False) axt.spines['top'].set_visible(False) # ft.savefig(os.path.abspath(os.path.join(outpath,'theta_dtu10mw.png'))) # ft.savefig(os.path.abspath(os.path.join(outpath,'theta_dtu10mw.pdf'))) plt.show()
def test_betz(self): from openmdao.api import Problem, ScipyOptimizer, IndepVarComp, ExplicitComponent class ActuatorDisc(ExplicitComponent): """Simple wind turbine model based on actuator disc theory""" def setup(self): # Inputs self.add_input('a', 0.5, desc="Induced Velocity Factor") self.add_input('Area', 10.0, units="m**2", desc="Rotor disc area") self.add_input('rho', 1.225, units="kg/m**3", desc="air density") self.add_input( 'Vu', 10.0, units="m/s", desc="Freestream air velocity, upstream of rotor") # Outputs self.add_output('Vr', 0.0, units="m/s", desc="Air velocity at rotor exit plane") self.add_output( 'Vd', 0.0, units="m/s", desc="Slipstream air velocity, downstream of rotor") self.add_output('Ct', 0.0, desc="Thrust Coefficient") self.add_output('thrust', 0.0, units="N", desc="Thrust produced by the rotor") self.add_output('Cp', 0.0, desc="Power Coefficient") self.add_output('power', 0.0, units="W", desc="Power produced by the rotor") self.declare_partials('Vr', ['a', 'Vu']) self.declare_partials('Vd', 'a') self.declare_partials('Ct', 'a') self.declare_partials('thrust', ['a', 'Area', 'rho', 'Vu']) self.declare_partials('Cp', 'a') self.declare_partials('power', ['a', 'Area', 'rho', 'Vu']) def compute(self, inputs, outputs): """ Considering the entire rotor as a single disc that extracts velocity uniformly from the incoming flow and converts it to power.""" a = inputs['a'] Vu = inputs['Vu'] qA = .5 * inputs['rho'] * inputs['Area'] * Vu**2 outputs['Vd'] = Vd = Vu * (1 - 2 * a) outputs['Vr'] = .5 * (Vu + Vd) outputs['Ct'] = Ct = 4 * a * (1 - a) outputs['thrust'] = Ct * qA outputs['Cp'] = Cp = Ct * (1 - a) outputs['power'] = Cp * qA * Vu def compute_partials(self, inputs, J): """ Jacobian of partial derivatives.""" a = inputs['a'] Vu = inputs['Vu'] Area = inputs['Area'] rho = inputs['rho'] # pre-compute commonly needed quantities a_times_area = a * Area one_minus_a = 1.0 - a a_area_rho_vu = a_times_area * rho * Vu J['Vr', 'a'] = -Vu J['Vr', 'Vu'] = one_minus_a J['Vd', 'a'] = -2.0 * Vu J['Ct', 'a'] = 4.0 - 8.0 * a J['thrust', 'a'] = .5 * rho * Vu**2 * Area * J['Ct', 'a'] J['thrust', 'Area'] = 2.0 * Vu**2 * a * rho * one_minus_a J['thrust', 'rho'] = 2.0 * a_times_area * Vu**2 * (one_minus_a) J['thrust', 'Vu'] = 4.0 * a_area_rho_vu * (one_minus_a) J['Cp', 'a'] = 4.0 * a * (2.0 * a - 2.0) + 4.0 * (one_minus_a)**2 J['power', 'a'] = 2.0 * Area * Vu**3 * a * rho * ( 2.0 * a - 2.0) + 2.0 * Area * Vu**3 * rho * one_minus_a**2 J['power', 'Area'] = 2.0 * Vu**3 * a * rho * one_minus_a**2 J['power', 'rho'] = 2.0 * a_times_area * Vu**3 * (one_minus_a)**2 J['power', 'Vu'] = 6.0 * Area * Vu**2 * a * rho * one_minus_a**2 # build the model prob = Problem() indeps = prob.model.add_subsystem('indeps', IndepVarComp(), promotes=['*']) indeps.add_output('a', .5) indeps.add_output('Area', 10.0, units='m**2') indeps.add_output('rho', 1.225, units='kg/m**3') indeps.add_output('Vu', 10.0, units='m/s') prob.model.add_subsystem('a_disk', ActuatorDisc(), promotes_inputs=['a', 'Area', 'rho', 'Vu']) # setup the optimization prob.driver = ScipyOptimizer() prob.driver.options['optimizer'] = 'SLSQP' prob.model.add_design_var('a', lower=0., upper=1.) prob.model.add_design_var('Area', lower=0., upper=1.) # negative one so we maximize the objective prob.model.add_objective('a_disk.Cp', scaler=-1) prob.setup() prob.run_driver() # minimum value assert_rel_error(self, prob['a_disk.Cp'], 16. / 27., 1e-4)
(rRoot**2) * alum_stress) mRoot = 2.0 * math.pi * rRoot * t * rootLength * alum_rho # Total weight mass = nBlades * (np.sum(m[0:-1] * np.diff(x)) + 2.0 * mRib + mRoot) error = abs(mass - massOld) massOld = mass mass = fudge * mass # Fudge factor unknowns['mass'] = mass if __name__ == "__main__": # DEBUG top = Problem() root = top.root = Group() # Sample Inputs indep_vars_constants = [('rProp', 1.4), ('thrust', 10000.0)] root.add('Inputs', IndepVarComp(indep_vars_constants)) root.add('Example', prop_mass()) root.connect('Inputs.rProp', 'Example.rProp') root.connect('Inputs.thrust', 'Example.thrust') top.setup() top.run()
coupled, promotes=['*']) root.add('vlmfuncs', VLMFunctionals(num_y), promotes=['*']) root.add('spatialbeamfuncs', SpatialBeamFunctionals(num_y, E, G, stress, mrho), promotes=['*']) root.add('fuelburn', FunctionalBreguetRange(W0, CT, a, R, M), promotes=['*']) root.add('eq_con', FunctionalEquilibrium(W0), promotes=['*']) prob = Problem() prob.root = root coupled.nl_solver.options['iprint'] = 1 # makes OpenMDAO print out solver convergence data coupled.ln_solver.options['iprint'] = 1 # makes OpenMDAO print out solver convergence data prob.driver.add_recorder(SqliteRecorder('prob1d.db')) prob.setup() # view_tree(prob, outfile="my_aerostruct_n2.html", show_browser=True) # generate the n2 diagram diagram # always need to run before you compute derivatives! prob.run_once() st = time.time() jac = prob.calc_gradient(['twist','alpha','t'], ['fuelburn'], mode="fwd", return_format="dict")
from pprint import pprint as pp import numpy as np from openmdao.api import Problem, IndepVarComp from path_dependent_missions.f110_pycycle import mixedflow_turbofan as mftf prob = Problem() des_vars = prob.model.add_subsystem('des_vars', IndepVarComp(), promotes=["*"]) ########################################## # Design Variables ########################################## des_vars.add_output('alt', 0., units='ft') #DV des_vars.add_output('MN', 0.001) #DV des_vars.add_output('T4max', 3200, units='degR') des_vars.add_output('T4maxab', 3400, units='degR') des_vars.add_output('Fn_des', 17000., units='lbf') des_vars.add_output('Mix_ER', 1.05, units=None) # defined as 1 over 2 des_vars.add_output('fan:PRdes', 3.3) #ADV des_vars.add_output('hpc:PRdes', 9.3) ##################### # DESIGN CASE ##################### prob.model.add_subsystem('DESIGN', mftf.MixedFlowTurbofan(design=True)) prob.model.connect('alt', 'DESIGN.fc.alt') prob.model.connect('MN', 'DESIGN.fc.MN')
def test_sellar_state_connection(self): # Test derivatives across a converged Sellar model. prob = Problem() prob.model = SellarStateConnection( linear_solver=self.linear_solver_class(), nl_atol=1e-12) prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.run_model() # Just make sure we are at the right answer assert_rel_error(self, prob['y1'], 25.58830273, .00001) assert_rel_error(self, prob['d2.y2'], 12.05848819, .00001) wrt = ['x', 'z'] of = ['obj', 'con1', 'con2'] Jbase = {} Jbase['con1', 'x'] = [[-0.98061433]] Jbase['con1', 'z'] = np.array([[-9.61002285, -0.78449158]]) Jbase['con2', 'x'] = [[0.09692762]] Jbase['con2', 'z'] = np.array([[1.94989079, 1.0775421]]) Jbase['obj', 'x'] = [[2.98061392]] Jbase['obj', 'z'] = np.array([[9.61001155, 1.78448534]]) J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') for key, val in Jbase.items(): assert_rel_error(self, J[key], val, .00001) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') for key, val in Jbase.items(): assert_rel_error(self, J[key], val, .00001)
# Compute the stall margins self.add_subsystem('stall_margins', StallCalcs(), promotes_inputs=[('PR_actual', 'PRmap'), ('Wc_actual', 'WcMap')], promotes_outputs=['SMN', 'SMW']) self.connect('SMN_map.PRmap', 'stall_margins.PR_SMN') self.connect('SMW_map.PRmap', 'stall_margins.PR_SMW') self.connect('SMN_map.WcMap', 'stall_margins.Wc_SMN') if __name__ == "__main__": from openmdao.api import Problem, IndepVarComp from pycycle.maps.ncp01 import NCP01 p1 = Problem() ivc = p1.model.add_subsystem('ivc', IndepVarComp(), promotes=['*']) # Design variables ivc.add_output('alphaMap', 0.0) ivc.add_output('PR', 2.0) ivc.add_output('Nc', 1000.0, units='rpm') ivc.add_output('eff', .9) ivc.add_output('Wc', 3000., units='lbm/s') # Off-design variables # ivc.add_output('alphaMap', 0.0) # ivc.add_output('Nc', 1000.0, units='rpm') # ivc.add_output('Wc', 3000., units='lbm/s') # ivc.add_output('s_Nc', 1.0) # ivc.add_output('s_Wc', 1.0) # ivc.add_output('s_PR', 1.0)
def test_single_diamond_grouped(self): # Test derivatives for grouped diamond topology. prob = Problem() prob.model = Diamond() prob.model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob.run_model() wrt = ['iv.x'] of = ['c4.y1', 'c4.y2'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['c4.y1', 'iv.x'], [[25]], 1e-6) assert_rel_error(self, J['c4.y2', 'iv.x'], [[-40.5]], 1e-6) prob.setup(check=False, mode='rev') prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['c4.y1', 'iv.x'], [[25]], 1e-6) assert_rel_error(self, J['c4.y2', 'iv.x'], [[-40.5]], 1e-6)
def test_simple_matvec_subbed(self): # Tests derivatives on a group that contains a simple comp that # defines compute_jacvec. prob = Problem() model = prob.model model.add_subsystem('x_param', IndepVarComp('length', 3.0), promotes=['length']) sub = model.add_subsystem('sub', Group(), promotes=['length', 'width', 'area']) sub.add_subsystem('mycomp', TestExplCompSimpleJacVec(), promotes=['length', 'width', 'area']) model.linear_solver = self.linear_solver_class() prob.set_solver_print(level=0) prob.setup(check=False, mode='fwd') prob['width'] = 2.0 # Note, For DirectSolver, assemble_jac must be False for mat-vec. if isinstance(model.linear_solver, DirectSolver): model.linear_solver.options['assemble_jac'] = False prob.run_model() of = ['area'] wrt = ['length'] J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'], [[2.0]], 1e-6) prob.setup(check=False, mode='rev') prob['width'] = 2.0 prob.run_model() J = prob.compute_totals(of=of, wrt=wrt, return_format='flat_dict') assert_rel_error(self, J['area', 'length'], [[2.0]], 1e-6)