Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ project(
'optvl',
'c',
# don't forget to change the value in pyproject.toml
version: '2.2.2',
version: '2.2.3',
license: 'GPL-3.0',
meson_version: '>= 0.64.0',
default_options: [
Expand Down
21 changes: 19 additions & 2 deletions optvl/optvl_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ class OVLSolver(object):
"XYZref": ["CASE_R", "XYZREF"],
}

# this is a special list of variables that store the value in the
# geometry file
avl_params_to_defauls = {
"Mach" : ["CASE_R", "MACH0"],
"CD0": ["CASE_R", "CDREF0"],
"XYZref": ["CASE_R", "XYZREF0"],
}

case_derivs_to_fort_var = {
# derivative of coefficents wrt control surface deflections

Expand Down Expand Up @@ -1607,10 +1615,15 @@ def get_reference_data(self) -> Dict[str, float]:

return ref_data

def set_reference_data(self, ref_data: Dict[str, float]) -> None:
def set_reference_data(self, ref_data: Dict[str, float], set_default_value:bool = True) -> None:
for key, val in ref_data.items():
avl_key = self.ref_var_to_fort_var[key]

self.set_avl_fort_arr(*avl_key, val)

if set_default_value:
if key in self.avl_params_to_defauls:
self.set_avl_fort_arr(*self.avl_params_to_defauls[key], val)

return ref_data

Expand Down Expand Up @@ -1765,7 +1778,7 @@ def get_constraint(self, con_key: str) -> float:

return con_val

def set_parameter(self, param_key: str, param_val: float) -> None:
def set_parameter(self, param_key: str, param_val: float, set_default_value:bool = True) -> None:
"""Modify a parameter of the run (analogous to M from the OPER menu in AVL).

Args:
Expand All @@ -1788,6 +1801,10 @@ def set_parameter(self, param_key: str, param_val: float) -> None:

self.set_avl_fort_arr("CASE_R", "PARVAL", parvals)

if set_default_value:
if param_key in self.avl_params_to_defauls:
self.set_avl_fort_arr(*self.avl_params_to_defauls[param_key], param_val)

# (1) here because we want to set the first runcase with fortran indexing (the only one)
self.avl.set_params(1)

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ dependencies = [
"numpy>=1.19",
]
readme = "README.md"
version = "2.2.2" # this automatically updates __init__.py and setup_deprecated.py
version = "2.2.3" # this automatically updates __init__.py and setup_deprecated.py
# don't forget to change the value in meson.build!


Expand Down
86 changes: 62 additions & 24 deletions tests/test_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ def tearDown(self):
print(f"{self.id():80} Memory usage: {mb_memory:.2f} MB")

def test_read_geom(self):
ovl_solver = OVLSolver(geo_file=geom_file)
assert ovl_solver.get_num_surfaces() == 5
assert ovl_solver.get_num_strips() == 90
assert ovl_solver.get_mesh_size() == 780
ovl = OVLSolver(geo_file=geom_file)
assert ovl.get_num_surfaces() == 5
assert ovl.get_num_strips() == 90
assert ovl.get_mesh_size() == 780

def test_read_geom_and_mass(self):
ovl_solver = OVLSolver(geo_file=geom_file, mass_file=mass_file)
assert ovl_solver.get_avl_fort_arr("CASE_L", "LMASS")
ovl = OVLSolver(geo_file=geom_file, mass_file=mass_file)
assert ovl.get_avl_fort_arr("CASE_L", "LMASS")


class TestOutput(unittest.TestCase):
Expand All @@ -58,15 +58,16 @@ def tearDown(self):

def test_write_geom(self):
"""check that the file written by OptVL is the same as the original file"""
ovl_solver = OVLSolver(geo_file=supra_geom_file)
ovl_solver.write_geom_file(geom_output_file)
baseline_data = ovl_solver.get_surface_params(include_airfoils=True, include_con_surf=True, include_des_vars=True, include_paneling=True)
baseline_data_body = ovl_solver.get_body_params()
ovl = OVLSolver(geo_file=supra_geom_file)
geom_output_file = "test_write_geom_output.avl"
ovl.write_geom_file(geom_output_file)
baseline_data = ovl.get_surface_params(include_airfoils=True, include_con_surf=True, include_des_vars=True, include_paneling=True)
baseline_data_body = ovl.get_body_params()

del ovl_solver
ovl_solver = OVLSolver(geo_file=geom_output_file)
new_data = ovl_solver.get_surface_params(include_airfoils=True, include_con_surf=True, include_des_vars=True, include_paneling=True)
new_data_body = ovl_solver.get_body_params()
del ovl
ovl = OVLSolver(geo_file=geom_output_file)
new_data = ovl.get_surface_params(include_airfoils=True, include_con_surf=True, include_des_vars=True, include_paneling=True)
new_data_body = ovl.get_body_params()

for surf in baseline_data:
for key in baseline_data[surf]:
Expand Down Expand Up @@ -110,14 +111,16 @@ def test_write_geom(self):
def test_write_panneling_params(self):
# test that the surface is output correctly when only section or surface
# panneling is given
ovl_solver = OVLSolver(geo_file=rect_geom_file)
ovl_solver.write_geom_file(rect_geom_output_file)
baseline_data = ovl_solver.get_surface_params(include_paneling=True, include_geom=False)
ovl = OVLSolver(geo_file=rect_geom_file)
geom_output_file = "test_write_panneling_params_output.avl"

ovl.write_geom_file(geom_output_file)
baseline_data = ovl.get_surface_params(include_paneling=True, include_geom=False)
assert baseline_data["Wing"]["use surface spacing"]

del ovl_solver
ovl_solver = OVLSolver(geo_file=rect_geom_output_file)
new_data = baseline_data = ovl_solver.get_surface_params()
del ovl
ovl = OVLSolver(geo_file=geom_output_file)
new_data = baseline_data = ovl.get_surface_params()

for surf in baseline_data:
for key in baseline_data[surf]:
Expand All @@ -134,22 +137,57 @@ def test_write_panneling_params(self):
err_msg=f"Surface `{surf}` key `{key}` does not match reference data",
)

def test_ref_data(self):
ref_data = {
"Sref": 1.0,
"Cref": 2.0,
"Bref": 3.0,
"XYZref": np.array([4.0, 5.0, 6.0]),
}
ovl = OVLSolver(geo_file=rect_geom_file)
ovl.set_reference_data(ref_data)

mach0 = 0.12341234
ovl.set_parameter("Mach", mach0)

ovl.write_geom_file(rect_geom_output_file)

del ovl

ovl = OVLSolver(geo_file=rect_geom_output_file)
new_data = ovl.get_reference_data()

for key in new_data:
np.testing.assert_equal(
new_data[key],
ref_data[key],
err_msg=f"{key} does not match set value")

new_mach = ovl.get_parameter("Mach")
np.testing.assert_equal(
new_mach,
mach0,
err_msg=f"Mach does not match set value")





class TestFortranLevelAPI(unittest.TestCase):
def setUp(self):
self.ovl_solver = OVLSolver(geo_file=geom_file, mass_file=mass_file)
self.ovl = OVLSolver(geo_file=geom_file, mass_file=mass_file)

def test_get_scalar(self):
avl_version = 3.52
version = self.ovl_solver.get_avl_fort_arr("CASE_R", "VERSION")
version = self.ovl.get_avl_fort_arr("CASE_R", "VERSION")
self.assertEqual(version, avl_version)

# test that this works with lower case
version = self.ovl_solver.get_avl_fort_arr("case_r", "version")
version = self.ovl.get_avl_fort_arr("case_r", "version")
self.assertEqual(version, avl_version)

def test_get_array(self):
chords = self.ovl_solver.get_avl_fort_arr("SURF_GEOM_R", "CHORDS")
chords = self.ovl.get_avl_fort_arr("SURF_GEOM_R", "CHORDS")

self.assertEqual(chords.shape, (100, 301))
np.testing.assert_array_equal(chords[0, :5], np.array([0.45, 0.45, 0.4, 0.3, 0.2]))
Expand Down
Loading