def test_plotting(): """ Make sure that all plot functions run and image files are generated """ shutil.rmtree(PATHS.DIR.TEMPLATE_ROOT, ignore_errors=True) project_dir = project_setup.setup_wkdir() # ----- Modify settings file ----- settings_file = os.path.join(project_dir, PATHS.DIR.SETTINGS, 'template.json') with open(settings_file, 'r') as fp: settings = json.load(fp) for plot_name in ['geometry', 'lattice', 'matrix_downwash', 'results']: settings['plot'][plot_name]['save'] = True settings['plot'][plot_name]['show'] = False with open(settings_file, 'w') as fp: json.dump(settings, fp) # ----- Run PyTornado ----- standard_run(args=StdRunArgs(run=settings_file)) # ----- Checks ----- plot_dir = os.path.join(project_dir, PATHS.DIR.PLOTS, 'template_000') created_files = [f for f in os.listdir(plot_dir) if os.path.isfile(os.path.join(plot_dir, f))] # Check that file have correct suffix assert all([f.endswith('.png') for f in created_files]) # Check that number of created plots is correct assert len(created_files) == 7 # ----- Clean up ----- shutil.rmtree(project_dir, ignore_errors=True)
def test_basic_analysis(): """ Check that panel forces are located at the correct positions """ state = { "aero": { "airspeed": None, "density": None, "mach": None, "altitude": None, "alpha": 0, "beta": 0, "rate_P": 0, "rate_Q": 0, "rate_R": 0, } } # Combination 1 state['aero']['airspeed'] = 100 state['aero']['density'] = 1.225 state['aero']['mach'] = None state['aero']['altitude'] = None set_state_file(state) results = standard_run(ARGS) assert results['state'].aero['airspeed'][0] == approx(100) assert results['state'].aero['density'][0] == approx(1.225) # Combination 2 state['aero']['airspeed'] = 100 state['aero']['density'] = None state['aero']['mach'] = None state['aero']['altitude'] = 0 set_state_file(state) results = standard_run(ARGS) assert results['state'].aero['airspeed'][0] == approx(100) assert results['state'].aero['density'][0] == approx(1.225) # Combination 3 state['aero']['airspeed'] = None state['aero']['density'] = None state['aero']['mach'] = 1 state['aero']['altitude'] = 0 set_state_file(state) results = standard_run(ARGS) assert results['state'].aero['airspeed'][0] == approx(340.2939) assert results['state'].aero['density'][0] == approx(1.225) # Invalid combination state['aero']['airspeed'] = 100 state['aero']['density'] = None state['aero']['mach'] = 1 state['aero']['altitude'] = 0 set_state_file(state) with raises(ValueError): standard_run(ARGS)
def test_panel_forces(): """ Check that panel forces are located at the correct positions """ testdir = "test1" args = StdRunArgs() args.run = os.path.join(HERE, testdir, 'settings', 'test.json') standard_run(args) # ------------------------------------------------------------------------- # Panel forces should act at theses coordinates # ------------------------------------------------------------------------- path = os.path.join(HERE, testdir, "_results/test_000/loads_UID_wing1.json") with open(path, "r") as fp: loads = json.load(fp) exp_coords = np.array([ [0.25, 0.25, 0], [0.125, 0.75, 0], [0.625, 0.75, 0], ]) for entry, exp_coord in zip(loads, exp_coords): assert np.testing.assert_array_equal(entry['coord'], exp_coord) is None # ------------------------------------------------------------------------- # Make sure panel forces sum up correctly # ------------------------------------------------------------------------- Fx = 0 Fy = 0 Fz = 0 for entry in loads: fx, fy, fz, _, _, _ = entry['load'] Fx += fx Fy += fy Fz += fz path = os.path.join(HERE, testdir, "_results/test_000/test_global.json") with open(path, "r") as fp: glob_results = json.load(fp) assert Fx == pytest.approx(glob_results['global_forces']['x']) assert Fy == pytest.approx(glob_results['global_forces']['y']) assert Fz == pytest.approx(glob_results['global_forces']['z'])
def __init__(self, root_path, shared, settings): super().__init__(root_path, shared, settings) # PyTornado files self.own_files = {} self.own_files['settings'] = join(self.root_path, settings.get('run', '')) self.own_files['deformation_dir'] = join(self.root_path, 'cfd', 'deformation') self.own_files['deformation'] = join(self.own_files['deformation_dir'], f'{uuid4()}.json') # Locate the PyTornado main settings file if not os.path.isfile(self.own_files['settings']): raise FileNotFoundError( f"PyTornado settings file '{self.own_files['settings']}' not found" ) # Create a PyTornado deformation folder and a empty deformation file if not os.path.exists(self.own_files['deformation_dir']): os.makedirs(self.own_files['deformation_dir']) open(self.own_files['deformation'], 'w').close() # Get the bound leg midpoints of the undeformed (!) mesh self._toggle_deformation(turn_on=False) pytornado_results = pyt.standard_run(args=pyt.StdRunArgs( run=self.own_files['settings'])) self.points_of_attack_undeformed = pytornado_results[ 'lattice'].bound_leg_midpoints
def test_basic_analysis(): """ Check that panel forces are located at the correct positions """ # ----- Single value input ----- state = { "aero": { "airspeed": 100, "density": 1.225, "alpha": 0, "beta": 0, "rate_P": 0, "rate_Q": 0, "rate_R": 0, } } set_state_file(state) results = standard_run(ARGS) # assert # ----- Table input ----- state = { "aero": { "airspeed": [100, 100], "density": [1.225, 1.225], "alpha": [0, 5], "beta": [0, 0], "rate_P": [0, 0], "rate_Q": [0, 0], "rate_R": [0, 0], } } set_state_file(state) results = standard_run(ARGS) print(results['state'].aero) print(results['state'].results)
def run_analysis(self, turn_off_deform=False): """ Run the PyTornado analysis Args: :turn_off_deform: Flag which can be used to turn off all deformations """ if turn_off_deform: self._toggle_deformation(turn_on=False) else: self._toggle_deformation(turn_on=True) dump_json_def_fields(self.own_files['deformation'], self.shared.structure.def_fields) # ----- Run the PyTornado analysis ----- pytornado_results = pyt.standard_run(args=pyt.StdRunArgs(run=self.own_files['settings'])) self.last_solution = pytornado_results # Save the last solution # ----- Share load data ----- self.shared.cfd.load_fields = self._get_load_fields(pytornado_results)
def test_basic_analysis(): """ Check that panel forces are located at the correct positions """ results = standard_run(ARGS)
def main(): """ Command line interface """ HELP_RUN = f"Settings file (entry point for {stdrun.__prog_name__})" HELP_CPACS2JSON = "Convert a CPACS file to native JSON format" HELP_MAKE_EXAMPLE = "Generate a minimal working example" HELP_LIST_EXAMPLE_FROM_DB = "List example aircraft in the database" HELP_MAKE_EXAMPLE_FROM_DB = "Pick an aircraft from the database and generate a project directory" parser = argparse.ArgumentParser( prog=f'{stdrun.__prog_name__} {__version__}') group = parser.add_mutually_exclusive_group() group.add_argument('-r', '--run', metavar='<Settings file>', type=str, help=HELP_RUN) group.add_argument('--cpacs2json', metavar='<CPACS file>', type=str, help=HELP_CPACS2JSON) group.add_argument('--make-example', action='store_true', help=HELP_MAKE_EXAMPLE) group.add_argument('--list-example-from-db', '--ldb', action='store_true', help=HELP_LIST_EXAMPLE_FROM_DB) group.add_argument('--make-example-from-db', '--mdb', metavar='<Aircraft name>', type=str, help=HELP_MAKE_EXAMPLE_FROM_DB) group = parser.add_mutually_exclusive_group() group.add_argument('-v', '--verbose', action='store_true') group.add_argument('-d', '--debug', action='store_true') group.add_argument('-q', '--quiet', action='store_true') group = parser.add_mutually_exclusive_group() group.add_argument("-c", "--clean", help="remove old project files", action="store_true") group.add_argument("--clean-only", help="clean and exit", action="store_true") args = parser.parse_args() if args.clean or args.clean_only: # TODO: more general way (maybe --run must not be provided) if args.run is None: raise RuntimeError("Settings file must be specified with '--run'") stdrun.clean_project_dir(stdrun.get_settings(args.run)) if args.clean_only: return if args.run: stdrun.standard_run(args) elif args.cpacs2json: project_setup.cpacs2pytornado(args.cpacs2json) elif args.make_example: project_setup.setup_wkdir() elif args.make_example_from_db is not None: aircraft_name = Path(args.make_example_from_db).stem print(f"Loading '{aircraft_name}' from database...") try: filepath_aircraft = dbtools.get_aircraft_file_path(aircraft_name) except FileNotFoundError: dbtools.print_available_aircraft() print(f"\nAircraft '{aircraft_name}' file not found. Exit...", file=sys.stderr) sys.exit(1) print(f"Aircraft found at '{truncate_filepath(filepath_aircraft)}'...") project_setup.setup_wkdir(filepath_aircraft) elif args.list_example_from_db: dbtools.print_available_aircraft() else: parser.print_help()