diff --git a/openaerostruct/geometry/geometry_group.py b/openaerostruct/geometry/geometry_group.py index fab772a16..b7563e006 100644 --- a/openaerostruct/geometry/geometry_group.py +++ b/openaerostruct/geometry/geometry_group.py @@ -2,6 +2,7 @@ import openmdao.api as om from openaerostruct.utils.check_surface_dict import check_surface_dict_keys +from openaerostruct.utils.interpolation import get_normalized_span_coords class Geometry(om.Group): @@ -29,7 +30,6 @@ def setup(self): # Get the surface name and create a group to contain components # only for this surface - ny = surface["mesh"].shape[1] if self.options["DVGeo"]: from openaerostruct.geometry.ffd_component import GeometryMesh @@ -39,7 +39,7 @@ def setup(self): if "t_over_c_cp" in surface.keys(): n_cp = len(surface["t_over_c_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny - 1)) + x_interp = get_normalized_span_coords(surface, mid_panel=True) comp = self.add_subsystem( "t_over_c_bsp", om.SplineComp( @@ -67,7 +67,7 @@ def setup(self): if "twist_cp" in surface.keys(): n_cp = len(surface["twist_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny)) + x_interp = get_normalized_span_coords(surface) comp = self.add_subsystem( "twist_bsp", om.SplineComp( @@ -86,7 +86,7 @@ def setup(self): if "chord_cp" in surface.keys(): n_cp = len(surface["chord_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny)) + x_interp = get_normalized_span_coords(surface) comp = self.add_subsystem( "chord_bsp", om.SplineComp( @@ -103,7 +103,7 @@ def setup(self): if "t_over_c_cp" in surface.keys(): n_cp = len(surface["t_over_c_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny - 1)) + x_interp = get_normalized_span_coords(surface, mid_panel=True) comp = self.add_subsystem( "t_over_c_bsp", om.SplineComp( @@ -119,7 +119,7 @@ def setup(self): if "xshear_cp" in surface.keys(): n_cp = len(surface["xshear_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny)) + x_interp = get_normalized_span_coords(surface) comp = self.add_subsystem( "xshear_bsp", om.SplineComp( @@ -136,7 +136,7 @@ def setup(self): if "yshear_cp" in surface.keys(): n_cp = len(surface["yshear_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny)) + x_interp = get_normalized_span_coords(surface) comp = self.add_subsystem( "yshear_bsp", om.SplineComp( @@ -153,7 +153,7 @@ def setup(self): if "zshear_cp" in surface.keys(): n_cp = len(surface["zshear_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny)) + x_interp = get_normalized_span_coords(surface) comp = self.add_subsystem( "zshear_bsp", om.SplineComp( diff --git a/openaerostruct/structures/tube_group.py b/openaerostruct/structures/tube_group.py index ad43716cc..6d3e43d1a 100644 --- a/openaerostruct/structures/tube_group.py +++ b/openaerostruct/structures/tube_group.py @@ -1,7 +1,7 @@ -import numpy as np import openmdao.api as om from openaerostruct.structures.section_properties_tube import SectionPropertiesTube from openaerostruct.geometry.radius_comp import RadiusComp +from openaerostruct.utils.interpolation import get_normalized_span_coords class TubeGroup(om.Group): @@ -14,13 +14,11 @@ def initialize(self): def setup(self): surface = self.options["surface"] - mesh = surface["mesh"] - ny = mesh.shape[1] if "thickness_cp" in surface.keys(): n_cp = len(surface["thickness_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny - 1)) + x_interp = get_normalized_span_coords(surface, mid_panel=True) comp = self.add_subsystem( "thickness_bsp", om.SplineComp( @@ -35,7 +33,7 @@ def setup(self): if "radius_cp" in surface.keys(): n_cp = len(surface["radius_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny - 1)) + x_interp = get_normalized_span_coords(surface, mid_panel=True) comp = self.add_subsystem( "radius_bsp", om.SplineComp( diff --git a/openaerostruct/structures/wingbox_group.py b/openaerostruct/structures/wingbox_group.py index cff115f10..860370e7e 100644 --- a/openaerostruct/structures/wingbox_group.py +++ b/openaerostruct/structures/wingbox_group.py @@ -1,7 +1,7 @@ -import numpy as np import openmdao.api as om from openaerostruct.structures.section_properties_wingbox import SectionPropertiesWingbox from openaerostruct.structures.wingbox_geometry import WingboxGeometry +from openaerostruct.utils.interpolation import get_normalized_span_coords class WingboxGroup(om.Group): @@ -12,12 +12,11 @@ def initialize(self): def setup(self): surface = self.options["surface"] - ny = surface["mesh"].shape[1] if "spar_thickness_cp" in surface.keys(): n_cp = len(surface["spar_thickness_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny - 1)) + x_interp = get_normalized_span_coords(surface, mid_panel=True) comp = self.add_subsystem( "spar_thickness_bsp", om.SplineComp( @@ -32,7 +31,7 @@ def setup(self): if "skin_thickness_cp" in surface.keys(): n_cp = len(surface["skin_thickness_cp"]) # Add bspline components for active bspline geometric variables. - x_interp = np.linspace(0.0, 1.0, int(ny - 1)) + x_interp = get_normalized_span_coords(surface, mid_panel=True) comp = self.add_subsystem( "skin_thickness_bsp", om.SplineComp( diff --git a/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py b/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py index c0caf118a..bd66c446c 100644 --- a/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py +++ b/openaerostruct/tests/test_aero_analysis_no_symmetry_wavedrag.py @@ -100,9 +100,9 @@ def test(self): prob.run_driver() - assert_near_equal(prob["aero_point_0.wing_perf.CL"][0], 0.464191542231, 1e-6) - assert_near_equal(prob["aero_point_0.wing_perf.CD"][0], 0.020417875291205534, 1e-6) - assert_near_equal(prob["aero_point_0.CM"][1], -1.859570880469676, 1e-6) + assert_near_equal(prob["aero_point_0.CL"][0], 0.46419154063077483, 1e-6) + assert_near_equal(prob["aero_point_0.CD"][0], 0.020863555824806052, 1e-6) + assert_near_equal(prob["aero_point_0.CM"][1], -1.8595708973535592, 1e-6) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aero_opt_wavedrag.py b/openaerostruct/tests/test_aero_opt_wavedrag.py index 79629b17a..07090ab41 100644 --- a/openaerostruct/tests/test_aero_opt_wavedrag.py +++ b/openaerostruct/tests/test_aero_opt_wavedrag.py @@ -5,6 +5,7 @@ from openaerostruct.geometry.utils import generate_mesh from openaerostruct.geometry.geometry_group import Geometry from openaerostruct.aerodynamics.aero_groups import AeroPoint +from openaerostruct.utils.testing import assert_opt_successful import openmdao.api as om @@ -106,11 +107,13 @@ def test(self): # Set up the problem prob.setup() - prob.run_driver() + optResult = prob.run_driver() - assert_near_equal(prob["aero_point_0.wing_perf.CL"][0], 0.5, 1e-6) - assert_near_equal(prob["aero_point_0.wing_perf.CD"][0], 0.020838936785019083, 1e-6) - assert_near_equal(prob["aero_point_0.CM"][1], -2.081989092575424, 1e-6) + assert_opt_successful(self, optResult) + + assert_near_equal(prob["aero_point_0.CL"][0], 0.5, 1e-6) + assert_near_equal(prob["aero_point_0.CD"][0], 0.021353004050991248, 1e-6) + assert_near_equal(prob["aero_point_0.CM"][1], -2.0819892547514067, 1e-6) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct.py b/openaerostruct/tests/test_aerostruct.py index 2ef5e2086..27f67ac46 100644 --- a/openaerostruct/tests/test_aerostruct.py +++ b/openaerostruct/tests/test_aerostruct.py @@ -1,5 +1,6 @@ from openmdao.utils.assert_utils import assert_near_equal import unittest +from openaerostruct.utils.testing import assert_opt_successful class Test(unittest.TestCase): @@ -144,9 +145,10 @@ def test(self): # group. assert_near_equal(prob["AS_point_0.beta"], 0.0) - prob.run_driver() + optResult = prob.run_driver() + assert_opt_successful(self, optResult) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 92369.79279575823, 1e-8) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 92523.945549167, 1e-8) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_analysis.py b/openaerostruct/tests/test_aerostruct_analysis.py index 40578b7ac..52c407651 100644 --- a/openaerostruct/tests/test_aerostruct_analysis.py +++ b/openaerostruct/tests/test_aerostruct_analysis.py @@ -137,8 +137,8 @@ def test(self): prob.run_model() - assert_near_equal(prob["AS_point_0.fuelburn"][0], 251362.24734663023, 1e-4) - assert_near_equal(prob["AS_point_0.CM"][1], -0.7033677364356814, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 263398.25938918366, 1e-4) + assert_near_equal(prob["AS_point_0.CM"][1], -0.6462808405237332, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_analysis_Sref.py b/openaerostruct/tests/test_aerostruct_analysis_Sref.py index e30cee8ce..eb2327e66 100644 --- a/openaerostruct/tests/test_aerostruct_analysis_Sref.py +++ b/openaerostruct/tests/test_aerostruct_analysis_Sref.py @@ -139,8 +139,8 @@ def test(self): prob.run_model() - assert_near_equal(prob["AS_point_0.CL"][0], 1.6217443031469607, 1e-6) - assert_near_equal(prob["AS_point_0.CM"][1], -1.9988780195141023, 1e-5) + assert_near_equal(prob["AS_point_0.CL"][0], 1.6210175228727655, 1e-6) + assert_near_equal(prob["AS_point_0.CM"][1], -1.8365760768848112, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_analysis_compressible.py b/openaerostruct/tests/test_aerostruct_analysis_compressible.py index 2754f128d..9d12a6da1 100644 --- a/openaerostruct/tests/test_aerostruct_analysis_compressible.py +++ b/openaerostruct/tests/test_aerostruct_analysis_compressible.py @@ -139,8 +139,8 @@ def test(self): prob.run_model() - assert_near_equal(prob["AS_point_0.fuelburn"][0], 213840.78859689648, 1e-4) - assert_near_equal(prob["AS_point_0.CM"][1], -0.9866929184880228, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 224121.12881258246, 1e-4) + assert_near_equal(prob["AS_point_0.CM"][1], -0.9083682371351329, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_engine_thrusts.py b/openaerostruct/tests/test_aerostruct_engine_thrusts.py index a3711e177..11917775a 100644 --- a/openaerostruct/tests/test_aerostruct_engine_thrusts.py +++ b/openaerostruct/tests/test_aerostruct_engine_thrusts.py @@ -156,8 +156,8 @@ def test(self): print(prob["AS_point_0.fuelburn"][0]) print(prob["AS_point_0.CM"][1]) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 251929.9085951508, 1e-4) - assert_near_equal(prob["AS_point_0.CM"][1], -0.7008367976235399, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 263992.6780138112, 1e-4) + assert_near_equal(prob["AS_point_0.CM"][1], -0.6438933659444002, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_ffd.py b/openaerostruct/tests/test_aerostruct_ffd.py index 3d002f954..0ee954db1 100644 --- a/openaerostruct/tests/test_aerostruct_ffd.py +++ b/openaerostruct/tests/test_aerostruct_ffd.py @@ -2,6 +2,7 @@ import unittest import numpy as np from openaerostruct.utils.constants import grav_constant +from openaerostruct.utils.testing import assert_opt_successful # check if pygeo is available try: @@ -165,9 +166,10 @@ def test(self): prob.setup() # prob.run_model() - prob.run_driver() + optResult = prob.run_driver() + assert_opt_successful(self, optResult) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 92343.61493294379, 1e-3) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 92474.52106288195, 1e-3) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_groundeffect.py b/openaerostruct/tests/test_aerostruct_groundeffect.py index 5c2a8c70a..80439e706 100644 --- a/openaerostruct/tests/test_aerostruct_groundeffect.py +++ b/openaerostruct/tests/test_aerostruct_groundeffect.py @@ -1,6 +1,6 @@ from openmdao.utils.assert_utils import assert_near_equal import unittest -from openaerostruct.utils.testing import assert_check_totals +from openaerostruct.utils.testing import assert_check_totals, assert_opt_successful class Test(unittest.TestCase): @@ -144,17 +144,21 @@ def test(self): # Set up the problem prob.setup(check=True) - prob.run_driver() - assert_near_equal(prob["AS_point_0.fuelburn"][0], 92369.74980979414, 1e-6) + optResult = prob.run_driver() + assert_opt_successful(self, optResult) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 92523.90218121602, 1e-6) + prob["height_agl"] = 20.0 - prob.run_driver() + optResult = prob.run_driver() + assert_opt_successful(self, optResult) # the fuel burn should be less in ground effect - assert_near_equal(prob["AS_point_0.fuelburn"][0], 86910.5549671242, 1e-6) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 86980.04655202407, 1e-6) totals = prob.check_totals( of=["AS_point_0.L_equals_W", "AS_point_0.fuelburn", "AS_point_0.wing_perf.failure"], wrt=["wing.twist_cp", "alpha", "height_agl"], compact_print=True, - out_stream=None, + abs_err_tol=1e-2, + rel_err_tol=1e-5, ) assert_check_totals(totals, atol=1e-2, rtol=1e-5) diff --git a/openaerostruct/tests/test_aerostruct_point_loads.py b/openaerostruct/tests/test_aerostruct_point_loads.py index e117a4784..c19467614 100644 --- a/openaerostruct/tests/test_aerostruct_point_loads.py +++ b/openaerostruct/tests/test_aerostruct_point_loads.py @@ -150,8 +150,8 @@ def test(self): prob.run_model() - assert_near_equal(prob["AS_point_0.fuelburn"][0], 252038.66600566648, 1e-4) - assert_near_equal(prob["AS_point_0.CM"][1], -0.7006002684582702, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 264106.7825178142, 1e-4) + assert_near_equal(prob["AS_point_0.CM"][1], -0.6436834908660709, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py b/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py index 67b361eb3..c1be382da 100644 --- a/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py +++ b/openaerostruct/tests/test_aerostruct_wingbox_+weight_analysis.py @@ -400,8 +400,8 @@ def test(self): prob.run_model() - assert_near_equal(prob["AS_point_0.fuelburn"][0], 84598.60636387265, 1e-5) - assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 24009.5230566, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 87333.56998786073, 1e-5) + assert_near_equal(prob["wing.structural_mass"][0], 34500.40422127632, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_wingbox_analysis.py b/openaerostruct/tests/test_aerostruct_wingbox_analysis.py index a071f6747..b4f96fe50 100644 --- a/openaerostruct/tests/test_aerostruct_wingbox_analysis.py +++ b/openaerostruct/tests/test_aerostruct_wingbox_analysis.py @@ -401,9 +401,9 @@ def test(self): print(prob["wing.structural_mass"][0] / 1.25) print(prob["AS_point_0.wing_perf.failure"][0]) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 84999.8396153129, 1e-5) - assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 24009.5230566, 1e-5) - assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], 1.6254327137382174, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 87760.55423816708, 1e-5) + assert_near_equal(prob["wing.structural_mass"][0], 34500.40422127632, 1e-5) + assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], -0.15727437869018163, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py b/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py index bf71f3630..b6e4d7a77 100644 --- a/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py +++ b/openaerostruct/tests/test_aerostruct_wingbox_fuel_vol_constraint_opt.py @@ -3,6 +3,7 @@ import numpy as np from openaerostruct.geometry.utils import generate_mesh +from openaerostruct.utils.testing import assert_opt_successful from openaerostruct.integration.aerostruct_groups import AerostructGeometry, AerostructPoint @@ -426,15 +427,17 @@ def test(self): # Set up the problem prob.setup() - prob.run_driver() + optResult = prob.run_driver() print(prob["AS_point_0.fuelburn"][0]) print(prob["wing.structural_mass"][0] / 1.25) print(prob["fuel_vol_delta.fuel_vol_delta"][0]) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 76869.38586654868, 1e-5) - assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 11619.131535449487, 1e-4) - assert_near_equal(prob["fuel_vol_delta.fuel_vol_delta"][0], 42.98939210455205, 1e-4) + assert_opt_successful(self, optResult) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 76869.3858256513, 1e-4) + assert_near_equal(prob["wing.structural_mass"][0], 14523.135605406405, 1e-4) + assert_near_equal(prob["fuel_vol_delta.fuel_vol_delta"][0], 42.99371350246894, 1e-4) + assert_near_equal(prob["AS_point_0.CL"][0], 0.5, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py b/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py index c4178a26b..3bb331f00 100644 --- a/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py +++ b/openaerostruct/tests/test_aerostruct_wingbox_wave_fuel_vol_constraint_opt.py @@ -1,4 +1,5 @@ from openmdao.utils.assert_utils import assert_near_equal +from openaerostruct.utils.testing import assert_opt_successful import unittest import numpy as np @@ -428,11 +429,12 @@ def test(self): # Set up the problem prob.setup() - optFailed = prob.run_driver() + optResult = prob.run_driver() - self.assertFalse(optFailed) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 85348.88283214, 1e-5) - assert_near_equal(prob["wing.structural_mass"][0], 13029.71120634, 1e-5) + assert_opt_successful(self, optResult) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 85374.45357945036, 1e-5) + assert_near_equal(prob["wing.structural_mass"][0], 13048.465090719292, 1e-5) + assert_near_equal(prob["AS_point_0.CL"][0], 0.5, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_multipoint_parallel.py b/openaerostruct/tests/test_multipoint_parallel.py index 99ee9d6fe..3fea70afe 100644 --- a/openaerostruct/tests/test_multipoint_parallel.py +++ b/openaerostruct/tests/test_multipoint_parallel.py @@ -395,10 +395,10 @@ def test_multipoint_MPI(self): deriv_fuel_sum_spar_thickness = totals[("fuel_sum", "wing.spar_thickness_cp")] assert_near_equal(MPI.COMM_WORLD.size, 2, 1e-8) - assert_near_equal(prob.get_val("fuel_sum", units="kg"), 5649.1290836, 1e-5) + assert_near_equal(prob.get_val("fuel_sum", units="kg"), 5663.04182905, 1e-5) assert_near_equal( deriv_fuel_sum_spar_thickness, - np.array([[1712.12137573, 2237.99650867, 3036.45032547, 5065.16727605]]), + np.array([[1467.2504797, 2271.82835456, 3133.0901236, 5247.87365798]]), 1e-5, ) diff --git a/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py b/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py index 2180ab9d2..64217956f 100644 --- a/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py +++ b/openaerostruct/tests/test_multipoint_wingbox_aerostruct.py @@ -1,4 +1,5 @@ from openmdao.utils.assert_utils import assert_near_equal +from openaerostruct.utils.testing import assert_opt_successful import unittest import numpy as np @@ -454,13 +455,14 @@ def test(self): # Set up the problem prob.setup() - prob.run_driver() + optResult = prob.run_driver() - print(prob["AS_point_0.fuelburn"][0]) - print(prob["wing.structural_mass"][0] / 1.25) + assert_opt_successful(self, optResult) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 87313.4177585217, 1e-5) - assert_near_equal(prob["wing.structural_mass"][0] / 1.25, 26352.1600542036, 1e-5) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 87326.95014538494, 1e-5) + assert_near_equal(prob["wing.structural_mass"][0], 32947.84007488438, 1e-5) + assert_near_equal(prob["AS_point_0.CL"][0], 0.5, 1e-5) + assert_near_equal(prob["AS_point_1.L_equals_W"][0], 0.0, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_scaneagle.py b/openaerostruct/tests/test_scaneagle.py index 9458a69ad..b67ba5e45 100644 --- a/openaerostruct/tests/test_scaneagle.py +++ b/openaerostruct/tests/test_scaneagle.py @@ -206,10 +206,10 @@ def test_opt(self): # Actually run the optimization problem self.prob.run_driver() - assert_near_equal(self.prob["AS_point_0.fuelburn"][0], 4.6365011384888275, 1e-5) - assert_near_equal(self.prob["wing.twist_cp"], np.array([2.25819837, 10.39881572, 5.0]), 1e-5) - assert_near_equal(self.prob["wing.sweep"][0], 18.964409030629632, 1e-5) - assert_near_equal(self.prob["alpha"][0], 2.0366563718492547, 1e-5) + assert_near_equal(self.prob["AS_point_0.fuelburn"][0], 4.518756027353296, 1e-5) + assert_near_equal(self.prob["wing.twist_cp"], np.array([2.74161203, 12.22389255, 5.0]), 1e-5) + assert_near_equal(self.prob["wing.sweep"][0], 18.909083171987344, 1e-5) + assert_near_equal(self.prob["alpha"][0], 1.4756577579439902, 1e-5) def test_totals(self): # Set up the problem diff --git a/openaerostruct/tests/test_simple_rect_AS.py b/openaerostruct/tests/test_simple_rect_AS.py index 88cfc2f0b..36763bd16 100644 --- a/openaerostruct/tests/test_simple_rect_AS.py +++ b/openaerostruct/tests/test_simple_rect_AS.py @@ -1,4 +1,5 @@ from openmdao.utils.assert_utils import assert_near_equal +from openaerostruct.utils.testing import assert_opt_successful import unittest import numpy as np @@ -150,9 +151,12 @@ def test(self): # Set up the problem prob.setup() - prob.run_driver() + optResult = prob.run_driver() - assert_near_equal(prob["AS_point_0.fuelburn"][0], 73196.44377669816, 1e-5) + assert_opt_successful(self, optResult) + + assert_near_equal(prob["AS_point_0.fuelburn"][0], 81707.1815730769, 1e-5) + assert_near_equal(prob["AS_point_0.L_equals_W"][0], 0.0, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_v1_aero_opt.py b/openaerostruct/tests/test_v1_aero_opt.py index 9137bb893..61c0b01e8 100644 --- a/openaerostruct/tests/test_v1_aero_opt.py +++ b/openaerostruct/tests/test_v1_aero_opt.py @@ -119,7 +119,14 @@ def test(self): prob.run_driver() # docs checkpoint 5 - assert_near_equal(prob["aero_point_0.wing_perf.CD"][0], 0.0049392534859265614, 1e-6) + assert_near_equal(prob["aero_point_0.CD"][0], 0.004938282205728244, 1e-6) + assert_near_equal(prob["aero_point_0.CL"][0], 0.5, 1e-6) + assert_near_equal(prob["aero_point_0.CM"][1], -0.7630284313966209, 1e-6) + assert_near_equal(prob["wing.dihedral"][0], -2.9553117192703464, 1e-6) + assert_near_equal(prob["wing.sweep"][0], 30.0, 1e-6) + np.testing.assert_allclose( + prob["wing.twist_cp"], [-2.8855929739789588, 4.483359585932103], rtol=1e-6, atol=1e-6 + ) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_v1_aerostruct_analysis.py b/openaerostruct/tests/test_v1_aerostruct_analysis.py index 9d3b572d3..e7fb2dab7 100644 --- a/openaerostruct/tests/test_v1_aerostruct_analysis.py +++ b/openaerostruct/tests/test_v1_aerostruct_analysis.py @@ -146,10 +146,10 @@ def test(self): prob.run_model() - assert_near_equal(prob["AS_point_0.wing_perf.CL"][0], 0.510849206378, 1e-6) - assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], -0.483587598753, 1e-6) - assert_near_equal(prob["AS_point_0.fuelburn"][0], 68894.2100988, 1e-4) - assert_near_equal(prob["AS_point_0.CM"][1], -1.539189058161678, 1e-5) + assert_near_equal(prob["AS_point_0.CL"][0], 0.45051341630308567, 1e-6) + assert_near_equal(prob["AS_point_0.wing_perf.failure"][0], -0.5727332449460827, 1e-6) + assert_near_equal(prob["AS_point_0.fuelburn"][0], 74882.84587656212, 1e-4) + assert_near_equal(prob["AS_point_0.CM"][1], -1.343178727111471, 1e-5) if __name__ == "__main__": diff --git a/openaerostruct/tests/test_wingbox_analysis.py b/openaerostruct/tests/test_wingbox_analysis.py index cf6108097..67b12c60a 100644 --- a/openaerostruct/tests/test_wingbox_analysis.py +++ b/openaerostruct/tests/test_wingbox_analysis.py @@ -332,7 +332,7 @@ def test(self): assert_check_partials(data, atol=1e20, rtol=1e-6) prob.run_driver() - assert_near_equal(prob["wing.structural_mass"], 16704.10113356, 1e-6) + assert_near_equal(prob["wing.structural_mass"], 16675.586037621928, 1e-6) if __name__ == "__main__": diff --git a/openaerostruct/utils/interpolation.py b/openaerostruct/utils/interpolation.py new file mode 100644 index 000000000..72a1eeef0 --- /dev/null +++ b/openaerostruct/utils/interpolation.py @@ -0,0 +1,26 @@ +def get_normalized_span_coords(surface, mid_panel=False): + """Get the normalised coordinates used for interpolating values along the wingspan + + These normalized coordinates range from 0 at the tip of the wing to 1 at the root. + + Parameters + ---------- + surface : OpenAeroStruct surface dictionary + Surface to generate coordinates for + mid_panel : bool, optional + Whether the normalized coordinate should be of the panel midpoints rather than the mesh nodes, by default False + + Returns + ------- + np.array + Normalized coordinate values + """ + spanwise_coord = surface["mesh"][0, :, 1] + span_range = spanwise_coord[-1] - spanwise_coord[0] + span_offset = spanwise_coord[0] + if mid_panel: + x_real = (spanwise_coord[:-1] + spanwise_coord[1:]) / 2 + else: + x_real = spanwise_coord + x_norm = (x_real - span_offset) / span_range + return x_norm diff --git a/openaerostruct/utils/testing.py b/openaerostruct/utils/testing.py index 5d6d4b0e3..cccd2a9d4 100644 --- a/openaerostruct/utils/testing.py +++ b/openaerostruct/utils/testing.py @@ -5,6 +5,25 @@ from openaerostruct.geometry.utils import generate_mesh +def assert_opt_successful(test, optResult): + """Check whether an OpenMDAO optimization successfully converged + + Parameters + ---------- + test : unittest.TestCase + The test case that is being run + optResult : + Result returned by OpenMDAO's run_driver() method + """ + # In older versions of OpenMDAO, the run_driver() method returns a boolean that indicates whether the + # optimization failed, but in newer versions it returns an object that contains the optimization results, + # including a `success` attribute. + if isinstance(optResult, bool): + test.assertFalse(optResult) + else: + test.assertTrue(optResult.success) + + def view_mat(mat1, mat2=None, key="Title", tol=1e-10): # pragma: no cover """ Helper function used to visually examine matrices. It plots mat1 and mat2 side by side,