diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..71b0a4a1 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,15 @@ +### Summary + +Summary of PR. + +### Related Issues + +- Resolves # + +### Backwards incompatibilities + +None + +### New Dependencies + +None diff --git a/README.md b/README.md index d3f88089..8a492272 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Here is the OpenMDAO version you need for the specific versions of pyCycle | 4.2.0 | 3.10.0 or greater | ## Version 4.2 --- PyPI release -No significant code changes, but minor adjustments to the package name in `setup.py` to enable publishing to PyPI. +No significant code changes, but minor adjustments to the package name in `setup.py` to enable publishing to PyPI. ## Citation @@ -59,9 +59,9 @@ If you use pyCycle, please cite this paper: pip install 'om-pycycle[all]' -Why is it `om-pycycle` on PyPI? -Because another package already claimed `pyCycle`! -Note that the import does not change though. +Why is it `om-pycycle` on PyPI? +Because another package already claimed `pyCycle`! +Note that the import does not change though. You still use `import pycycle` regardless. @@ -90,7 +90,7 @@ or for pyCycle V4.0.0: Use pip to install: - pip install -e . + pip install -e .[all] ## Testing @@ -100,10 +100,10 @@ After installation if you wat to run the unit test suite you can do so via the ` testflo pycycle This will run all the unit tests within the pycycle repository, but note that it will NOT run the longer regression tests from the -`example_cycles` folder. -If you want to run the regression tests, then you need to clone the repository, CD into the `example_cycles` folder and call +`example_cycles` folder. These tests are written as 'benchmark' tests. +If you want to run these tests, then you need to clone the repository, CD into the `example_cycles` folder and call - testflo . + testflo -b . ## Version 4.0 Announcements diff --git a/example_cycles/N+3ref/N3_SPD.py b/example_cycles/N+3ref/N3_SPD.py index dc1d28ae..dfba2279 100644 --- a/example_cycles/N+3ref/N3_SPD.py +++ b/example_cycles/N+3ref/N3_SPD.py @@ -4,20 +4,27 @@ from pprint import pprint import openmdao.api as om +from openmdao.utils.general_utils import set_pyoptsparse_opt import pycycle.api as pyc from N3ref import N3, viewer, MPN3 +# check that pyoptsparse is installed +OPT, OPTIMIZER = set_pyoptsparse_opt('SNOPT') +if OPTIMIZER: + from openmdao.drivers.pyoptsparse_driver import pyOptSparseDriver + + def N3_SPD_model(): prob = om.Problem() - prob.model = MPN3() + prob.model = MPN3() # setup the optimization prob.driver = om.pyOptSparseDriver() - prob.driver.options['optimizer'] = 'SNOPT' + prob.driver.options['optimizer'] = OPTIMIZER prob.driver.options['debug_print'] = ['desvars', 'nl_cons', 'objs'] prob.driver.opt_settings={'Major step limit': 0.05} @@ -53,7 +60,7 @@ def N3_SPD_model(): # Define the design point prob.set_val('TOC.splitter.BPR', 23.94514401), prob.set_val('TOC.balance.rhs:hpc_PR', 53.6332) - prob.set_val('TOC.fc.W', 820.44097898, units='lbm/s') + prob.set_val('TOC.fc.W', 820.44097898, units='lbm/s') # Set specific cycle parameters prob.set_val('fan:PRdes', 1.300), @@ -61,7 +68,7 @@ def N3_SPD_model(): prob.set_val('T4_ratio.TR', 0.926470588) prob.set_val('RTO_T4', 3400.0, units='degR') prob.set_val('SLS.balance.rhs:FAR', 28620.84, units='lbf') - prob.set_val('CRZ.balance.rhs:FAR', 5510.72833567, units='lbf') + prob.set_val('CRZ.balance.rhs:FAR', 5510.72833567, units='lbf') prob.set_val('RTO.hpt_cooling.x_factor', 0.9) # Set initial guesses for balances @@ -116,4 +123,4 @@ def N3_SPD_model(): for pt in ['TOC']+prob.model.od_pts: viewer(prob, pt) - print("time", time.time() - st) \ No newline at end of file + print("time", time.time() - st) diff --git a/example_cycles/N+3ref/benchmark_N3_SPD.py b/example_cycles/N+3ref/benchmark_N3_SPD.py index cc29dbe8..934a47c5 100644 --- a/example_cycles/N+3ref/benchmark_N3_SPD.py +++ b/example_cycles/N+3ref/benchmark_N3_SPD.py @@ -1,16 +1,22 @@ -import numpy as np +import numpy as np import unittest import os import openmdao.api as om from openmdao.utils.assert_utils import assert_near_equal +from openmdao.utils.general_utils import set_pyoptsparse_opt import pycycle.api as pyc from N3_SPD import N3_SPD_model +# check that pyoptsparse is installed +OPT, OPTIMIZER = set_pyoptsparse_opt('SNOPT') + + class N3MDPOptTestCase(unittest.TestCase): + @unittest.skipUnless(OPT, "This test requires pyOptSparse.") def benchmark_case1(self): prob = N3_SPD_model() @@ -20,7 +26,7 @@ def benchmark_case1(self): # Define the design point prob.set_val('TOC.splitter.BPR', 23.94514401), prob.set_val('TOC.balance.rhs:hpc_PR', 53.6332) - prob.set_val('TOC.fc.W', 820.44097898, units='lbm/s') + prob.set_val('TOC.fc.W', 820.44097898, units='lbm/s') # Set specific cycle parameters prob.set_val('fan:PRdes', 1.300), @@ -28,7 +34,7 @@ def benchmark_case1(self): prob.set_val('T4_ratio.TR', 0.926470588) prob.set_val('RTO_T4', 3400.0, units='degR') prob.set_val('SLS.balance.rhs:FAR', 28620.84, units='lbf') - prob.set_val('CRZ.balance.rhs:FAR', 5510.72833567, units='lbf') + prob.set_val('CRZ.balance.rhs:FAR', 5510.72833567, units='lbf') prob.set_val('RTO.hpt_cooling.x_factor', 0.9) # Set initial guesses for balances @@ -126,7 +132,7 @@ def benchmark_case1(self): assert_near_equal(prob['CRZ.balance.fan_Nmech'], 2118.62554023, tol)# assert_near_equal(prob['CRZ.balance.lp_Nmech'], 6567.78766693, tol)# assert_near_equal(prob['CRZ.balance.hp_Nmech'], 20574.43651756, tol)# - assert_near_equal(prob['CRZ.hpc.Fl_O:tot:T'], 1481.9756247, tol)# + assert_near_equal(prob['CRZ.hpc.Fl_O:tot:T'], 1481.9756247, tol)# if __name__ == "__main__": diff --git a/example_cycles/electric_propulsor.py b/example_cycles/electric_propulsor.py index 8a054aad..d4108975 100644 --- a/example_cycles/electric_propulsor.py +++ b/example_cycles/electric_propulsor.py @@ -2,6 +2,13 @@ import pycycle.api as pyc +# protection incase env doesn't have matplotlib installed, since its not strictly required +try: + import matplotlib + import matplotlib.pyplot as plt +except ImportError: + plt = None + class Propulsor(pyc.Cycle): @@ -10,10 +17,10 @@ def setup(self): design = self.options['design'] USE_TABULAR = True - if USE_TABULAR: + if USE_TABULAR: self.options['thermo_method'] = 'TABULAR' self.options['thermo_data'] = pyc.AIR_JETA_TAB_SPEC - else: + else: self.options['thermo_method'] = 'CEA' self.options['thermo_data'] = pyc.species_data.janaf FUEL_TYPE = 'JP-7' @@ -24,7 +31,7 @@ def setup(self): self.add_subsystem('inlet', pyc.Inlet()) self.add_subsystem('fan', pyc.Compressor(map_data=pyc.FanMap, map_extrap=True)) self.add_subsystem('nozz', pyc.Nozzle()) - + self.add_subsystem('perf', pyc.Performance(num_nozzles=1, num_burners=0)) @@ -125,15 +132,14 @@ def setup(self): self.pyc_add_pnt(pt, Propulsor(design=False, thermo_method='CEA')) self.set_input_defaults(pt+'.fc.MN', val=self.od_MNs[i]) - self.set_input_defaults(pt+'.fc.alt', val=self.od_alts, units='m') - self.set_input_defaults(pt+'.fan.map.RlineMap', val=self.od_Rlines[i]) + self.set_input_defaults(pt+'.fc.alt', val=self.od_alts, units='m') + self.set_input_defaults(pt+'.fan.map.RlineMap', val=self.od_Rlines[i]) self.pyc_use_default_des_od_conns() self.pyc_connect_des_od('nozz.Throat:stat:area', 'balance.rhs:W') super().setup() - if __name__ == "__main__": @@ -158,13 +164,13 @@ def setup(self): # Set initial guesses for balances prob['design.balance.W'] = 200. - + for i, pt in enumerate(mp_propulsor.od_pts): - + # initial guesses - prob['off_design.fan.PR'] = 1.2 - prob['off_design.balance.W'] = 406.790 - prob['off_design.balance.Nmech'] = 1. # normalized value + prob[pt+'.fan.PR'] = 1.2 + prob[pt+'.balance.W'] = 406.790 + prob[pt+'.balance.Nmech'] = 1. # normalized value st = time.time() @@ -184,7 +190,7 @@ def setup(self): print('\n', '#'*10, pt, '#'*10) viewer(prob, pt) - map_plots(prob,'design') - + if plt: + map_plots(prob,'design') print("Run time", run_time)