|
| 1 | +""" |
| 2 | +Unittest for FUN3D 14.0.2 finite-difference test |
| 3 | +""" |
| 4 | + |
| 5 | +import numpy as np, unittest, importlib, os |
| 6 | +from mpi4py import MPI |
| 7 | +import time |
| 8 | + |
| 9 | +# Imports from FUNtoFEM |
| 10 | +from funtofem.model import ( |
| 11 | + FUNtoFEMmodel, |
| 12 | + Variable, |
| 13 | + Scenario, |
| 14 | + Body, |
| 15 | + Function, |
| 16 | +) |
| 17 | +from funtofem.interface import ( |
| 18 | + TacsSteadyInterface, |
| 19 | + SolverManager, |
| 20 | + TestResult, |
| 21 | + make_test_directories, |
| 22 | +) |
| 23 | +from funtofem.driver import FUNtoFEMnlbgs, TransferSettings |
| 24 | + |
| 25 | +# check whether fun3d is available |
| 26 | +fun3d_loader = importlib.util.find_spec("fun3d") |
| 27 | +has_fun3d = fun3d_loader is not None |
| 28 | +if has_fun3d: |
| 29 | + from funtofem.interface import Fun3d14AeroelasticTestInterface |
| 30 | + |
| 31 | +np.random.seed(1234567) |
| 32 | +comm = MPI.COMM_WORLD |
| 33 | +base_dir = os.path.dirname(os.path.abspath(__file__)) |
| 34 | +bdf_filename = os.path.join(base_dir, "meshes", "nastran_CAPS.dat") |
| 35 | +results_folder, output_dir = make_test_directories(comm, base_dir) |
| 36 | + |
| 37 | +# TEST SETTINGS |
| 38 | +# get more accurate derivatives when early stopping is off and fully converges |
| 39 | +early_stopping = True |
| 40 | +forward_tol = 1e-15 |
| 41 | +adjoint_tol = 1e-15 |
| 42 | + |
| 43 | + |
| 44 | +class TestFun3dTacs(unittest.TestCase): |
| 45 | + FILENAME = "aero_module_quads.txt" |
| 46 | + FILEPATH = os.path.join(results_folder, FILENAME) |
| 47 | + |
| 48 | + def test_alpha_turbulent_aeroelastic_quads(self): |
| 49 | + # build the funtofem model with one body and scenario |
| 50 | + model = FUNtoFEMmodel("plate") |
| 51 | + plate = Body.aeroelastic("plate", boundary=2) |
| 52 | + plate.register_to(model) |
| 53 | + |
| 54 | + # build the scenario |
| 55 | + test_scenario = Scenario.steady( |
| 56 | + "plate_flow_quads", |
| 57 | + steps=25, |
| 58 | + forward_coupling_frequency=20, # 500 total fun3d steps |
| 59 | + adjoint_steps=25, |
| 60 | + adjoint_coupling_frequency=20, |
| 61 | + uncoupled_steps=10, |
| 62 | + ) |
| 63 | + test_scenario.set_stop_criterion( |
| 64 | + early_stopping=early_stopping, min_forward_steps=50 |
| 65 | + ) |
| 66 | + test_scenario.set_temperature(T_ref=300.0, T_inf=300.0) |
| 67 | + # Function.lift().register_to(test_scenario) |
| 68 | + Function.ksfailure().register_to(test_scenario) |
| 69 | + aoa = test_scenario.get_variable("AOA", set_active=True) |
| 70 | + aoa.set_bounds(lower=5.0, value=10.0, upper=15.0) |
| 71 | + test_scenario.set_flow_ref_vals(qinf=1.05e5) |
| 72 | + test_scenario.register_to(model) |
| 73 | + |
| 74 | + # build the solvers and coupled driver |
| 75 | + solvers = SolverManager(comm) |
| 76 | + solvers.flow = Fun3d14AeroelasticTestInterface( |
| 77 | + comm, model, test_aero_module=True, fun3d_dir="meshes" |
| 78 | + ) |
| 79 | + solvers.structural = TacsSteadyInterface.create_from_bdf( |
| 80 | + model, comm, nprocs=1, bdf_file=bdf_filename, prefix=output_dir |
| 81 | + ) |
| 82 | + |
| 83 | + max_rel_error = Fun3d14AeroelasticTestInterface.finite_diff_test_aero_module( |
| 84 | + solvers.flow, epsilon=1e-4, filename=self.FILEPATH |
| 85 | + ) |
| 86 | + self.assertTrue(max_rel_error < 1e-7) |
| 87 | + |
| 88 | + |
| 89 | +if __name__ == "__main__": |
| 90 | + # open and close the file to reset it |
| 91 | + if comm.rank == 0: |
| 92 | + open(TestFun3dTacs.FILEPATH, "w").close() |
| 93 | + |
| 94 | + unittest.main() |
0 commit comments