def test_comment_char(self): # Check to see if the use of the comment # characters works data = '\n'.join([ "Junk", "CAnchor", " Z 11, 22 344, Test 1e65", " B 4 Stuff", " $ Anchor", " Q 1, 2 34, Test 1e65", " B 4 Stuff", "Anchor", " A 1, 2 34, Test 1e65", " B 4 Stuff", "Anchor", " C 77 False NaN 333.444", " 1,2,3,4,5", " Inf 1.#QNAN -1.#IND" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() # Test full line comments gen = FileParser(full_line_comment_char="C") gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('Anchor') val = gen.transfer_var(1, 1) self.assertEqual(val, 'A') # Test end of line comments also gen = FileParser(full_line_comment_char="C", end_of_line_comment_char="$") gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('Anchor') val = gen.transfer_var(1, 1) self.assertEqual(val, 'A')
def test_comment_char(self): # Check to see if the use of the comment # characters works data = '\n'.join([ "Junk", "CAnchor", " Z 11, 22 344, Test 1e65", " B 4 Stuff", " $ Anchor", " Q 1, 2 34, Test 1e65", " B 4 Stuff", "Anchor", " A 1, 2 34, Test 1e65", " B 4 Stuff", "Anchor", " C 77 False NaN 333.444", " 1,2,3,4,5", " Inf 1.#QNAN -1.#IND" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() # Test full line comments gen = FileParser(full_line_comment_char="C") gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('Anchor') val = gen.transfer_var(1, 1) self.assertEqual(val, 'A') # Test end of line comments also gen = FileParser(full_line_comment_char="C", end_of_line_comment_char="$") gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('Anchor') val = gen.transfer_var(1, 1) self.assertEqual(val, 'A')
def compute(self, inputs, outputs): x = inputs['RadLen'] var = '{0};'.format(float(x)) # generate the input file for esatan thermal analysis generator = InputFileGenerator() generator.set_template_file('radiator_templ.txt') generator.set_generated_file('radiator.d') generator.mark_anchor("$CONSTANTS") generator.transfer_var(var, 4, 3) generator.generate() # the parent compute function actually runs the external code super(Radiator, self).compute(inputs, outputs) # parse the output file from the external code and set the value of T_max parser = FileParser() parser.set_file('radiator.out') parser.mark_anchor("+RADIATOR ") T_max = parser.transfer_var(5, 6) outputs['T_max'] = T_max
def test_output_parse_same_anchors(self): data = '\n'.join([ "CQUAD4 1 3.456", "CQUAD4 2 4.123", "CQUAD4 3 7.222", "CQUAD4 4" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() gen = FileParser() gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('CQUAD4') val = gen.transfer_var(0, 3) self.assertEqual(val, 3.456) gen.mark_anchor('CQUAD4') val = gen.transfer_var(0, 3) self.assertEqual(val, 4.123) gen.mark_anchor('CQUAD4', 2) val = gen.transfer_var(0, 2) self.assertEqual(val, 4) gen.reset_anchor() gen.mark_anchor('CQUAD4', -1) val = gen.transfer_var(0, 2) self.assertEqual(val, 4) gen.mark_anchor('CQUAD4', -1) val = gen.transfer_var(0, 3) self.assertEqual(val, 7.222) gen.mark_anchor('CQUAD4', -2) val = gen.transfer_var(0, 3) self.assertEqual(val, 4.123)
def test_output_parse_same_anchors(self): data = '\n'.join([ "CQUAD4 1 3.456", "CQUAD4 2 4.123", "CQUAD4 3 7.222", "CQUAD4 4" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() gen = FileParser() gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('CQUAD4') val = gen.transfer_var(0, 3) self.assertEqual(val, 3.456) gen.mark_anchor('CQUAD4') val = gen.transfer_var(0, 3) self.assertEqual(val, 4.123) gen.mark_anchor('CQUAD4', 2) val = gen.transfer_var(0, 2) self.assertEqual(val, 4) gen.reset_anchor() gen.mark_anchor('CQUAD4', -1) val = gen.transfer_var(0, 2) self.assertEqual(val, 4) gen.mark_anchor('CQUAD4', -1) val = gen.transfer_var(0, 3) self.assertEqual(val, 7.222) gen.mark_anchor('CQUAD4', -2) val = gen.transfer_var(0, 3) self.assertEqual(val, 4.123)
def test_more_delims(self): data = '\n'.join([ "anchor,1.0,2.0", "abc=123.456", "c=1,2,Word,6", "d=C:/abc/def,a+b*c^2,(%#%),!true", "a^33 1.#QNAN^#$%^" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() op = FileParser() op.set_file(self.filename) op.set_delimiters(' \t,=') op.mark_anchor('anchor') val = op.transfer_var(0, 1) self.assertEqual(val, 'anchor') val = op.transfer_var(0, 2) self.assertEqual(val, 1.0) val = op.transfer_var(1, 1) self.assertEqual(val, 'abc') val = op.transfer_var(1, 2) self.assertEqual(val, 123.456) val = op.transfer_var(2, 4) self.assertEqual(val, 'Word') val = op.transfer_var(2, 5) self.assertEqual(val, 6) val = op.transfer_var(3, 2) self.assertEqual(val, 'C:/abc/def') val = op.transfer_var(3, 3) self.assertEqual(val, 'a+b*c^2') val = op.transfer_var(3, 4) self.assertEqual(val, '(%#%)') val = op.transfer_var(3, 5) self.assertEqual(val, '!true') op.set_delimiters(' \t^') val = op.transfer_var(4, 1) self.assertEqual(val, 'a') val = op.transfer_var(4, 2) self.assertEqual(val, 33) val = op.transfer_var(4, 3) self.assertEqual(isnan(val), True) val = op.transfer_var(4, 4) self.assertEqual(val, '#$%')
def test_output_parse(self): data = '\n'.join([ "Junk", "Anchor", " A 1, 2 34, Test 1e65", " B 4 Stuff", "Anchor", " C 77 False NaN 333.444", " 1,2,3,4,5", " Inf 1.#QNAN -1.#IND" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() gen = FileParser() gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('Anchor') val = gen.transfer_var(1, 1) self.assertEqual(val, 'A') gen.reset_anchor() val = gen.transfer_var(3, 2) self.assertEqual(val, 4) self.assertEqual(type(val), int) gen.mark_anchor('Anchor',2) val = gen.transfer_var(1, 4) self.assertEqual(isnan(val), True) val = gen.transfer_var(3, 1) self.assertEqual(isinf(val), True) val = gen.transfer_var(3, 2) self.assertEqual(isnan(val), True) val = gen.transfer_var(3, 3) self.assertEqual(isnan(val), True) val = gen.transfer_line(-1) self.assertEqual(val, ' B 4 Stuff') # Now, let's try column delimiters gen.set_delimiters('columns') gen.mark_anchor('Anchor',-1) val = gen.transfer_var(1, 8, 10) self.assertEqual(val, 'als') val = gen.transfer_var(1, 17) self.assertEqual(val, 333.444) # Test some errors try: gen.mark_anchor('C 77', 3.14) except ValueError as err: msg = "The value for occurrence must be an integer" self.assertEqual(str(err), msg) else: self.fail('ValueError expected') try: gen.mark_anchor('C 77', 0) except ValueError as err: msg = "0 is not valid for an anchor occurrence." self.assertEqual(str(err), msg) else: self.fail('ValueError expected') try: gen.mark_anchor('ZZZ') except RuntimeError as err: msg = "Could not find pattern ZZZ in output file filename.dat" self.assertEqual(str(err), msg) else: self.fail('RuntimeError expected')
def test_more_delims(self): data = '\n'.join([ "anchor,1.0,2.0", "abc=123.456", "c=1,2,Word,6", "d=C:/abc/def,a+b*c^2,(%#%),!true", "a^33 1.#QNAN^#$%^" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() op = FileParser() op.set_file(self.filename) op.set_delimiters(' \t,=') op.mark_anchor('anchor') val = op.transfer_var(0, 1) self.assertEqual(val, 'anchor') val = op.transfer_var(0, 2) self.assertEqual(val, 1.0) val = op.transfer_var(1, 1) self.assertEqual(val, 'abc') val = op.transfer_var(1, 2) self.assertEqual(val, 123.456) val = op.transfer_var(2, 4) self.assertEqual(val, 'Word') val = op.transfer_var(2, 5) self.assertEqual(val, 6) val = op.transfer_var(3, 2) self.assertEqual(val, 'C:/abc/def') val = op.transfer_var(3, 3) self.assertEqual(val, 'a+b*c^2') val = op.transfer_var(3, 4) self.assertEqual(val, '(%#%)') val = op.transfer_var(3, 5) self.assertEqual(val, '!true') op.set_delimiters(' \t^') val = op.transfer_var(4, 1) self.assertEqual(val, 'a') val = op.transfer_var(4, 2) self.assertEqual(val, 33) val = op.transfer_var(4, 3) self.assertEqual(isnan(val), True) val = op.transfer_var(4, 4) self.assertEqual(val, '#$%')
def test_output_parse(self): data = '\n'.join([ "Junk", "Anchor", " A 1, 2 34, Test 1e65", " B 4 Stuff", "Anchor", " C 77 False NaN 333.444", " 1,2,3,4,5", " Inf 1.#QNAN -1.#IND" ]) outfile = open(self.filename, 'w') outfile.write(data) outfile.close() gen = FileParser() gen.set_file(self.filename) gen.set_delimiters(' ') gen.mark_anchor('Anchor') val = gen.transfer_var(1, 1) self.assertEqual(val, 'A') gen.reset_anchor() val = gen.transfer_var(3, 2) self.assertEqual(val, 4) self.assertEqual(type(val), int) gen.mark_anchor('Anchor', 2) val = gen.transfer_var(1, 4) self.assertEqual(isnan(val), True) val = gen.transfer_var(3, 1) self.assertEqual(isinf(val), True) val = gen.transfer_var(3, 2) self.assertEqual(isnan(val), True) val = gen.transfer_var(3, 3) self.assertEqual(isnan(val), True) val = gen.transfer_line(-1) self.assertEqual(val, ' B 4 Stuff') # Now, let's try column delimiters gen.set_delimiters('columns') gen.mark_anchor('Anchor', -1) val = gen.transfer_var(1, 8, 10) self.assertEqual(val, 'als') val = gen.transfer_var(1, 17) self.assertEqual(val, 333.444) # Test some errors try: gen.mark_anchor('C 77', 3.14) except ValueError as err: msg = "The value for occurrence must be an integer" self.assertEqual(str(err), msg) else: self.fail('ValueError expected') try: gen.mark_anchor('C 77', 0) except ValueError as err: msg = "0 is not valid for an anchor occurrence." self.assertEqual(str(err), msg) else: self.fail('ValueError expected') try: gen.mark_anchor('ZZZ') except RuntimeError as err: msg = "Could not find pattern ZZZ in output file filename.dat" self.assertEqual(str(err), msg) else: self.fail('RuntimeError expected')
def compute(self, inputs, outputs): # Results Folder creation if needed -------------------------------------------------------- result_folder_path = self.options[OPTION_RESULT_FOLDER_PATH] if result_folder_path != "": os.makedirs(result_folder_path, exist_ok=True) # Creation of the temporary directory ------------------------------------------------------ tmp_dir = TemporaryDirectory() if self.options[OPTION_AVL_EXE_PATH] != "": copy_resource(xfoil_resources, _PROFILE_FILE_NAME, tmp_dir.name) self.options["command"] = [self.options[OPTION_AVL_EXE_PATH]] else: copy_resource(avl336, _AVL_EXE_NAME, tmp_dir.name) copy_resource(xfoil_resources, _PROFILE_FILE_NAME, tmp_dir.name) self.options["command"] = [pth.join(tmp_dir.name, _AVL_EXE_NAME)] self.stdin = pth.join(tmp_dir.name, _STDIN_FILE_NANE) self.stdout = pth.join(tmp_dir.name, _STDOUT_FILE_NAME) self.stderr = pth.join(tmp_dir.name, _STDERR_FILE_NAME) # AVL geometry file (.avl) creation -------------------------------------------------------- input_geom_file = pth.join(tmp_dir.name, _AVL_GEOM_NAME) profile_file = pth.join(tmp_dir.name, _PROFILE_FILE_NAME) self._get_avl_geom_file(inputs, input_geom_file, _PROFILE_FILE_NAME) # AVL session file creation ---------------------------------------------------------------- s_ref = inputs["data:geometry:wing:area"] b_ref = inputs["data:geometry:wing:span"] c_ref = inputs["data:geometry:wing:MAC:length"] mach = inputs["data:aerostructural:load_case:mach"] alt = inputs["data:aerostructural:load_case:altitude"] rho = Atm(alt).density vtas = Atm(alt).speed_of_sound * mach q = 0.5 * rho * vtas ** 2 m_lc = inputs["data:aerostructural:load_case:weight"] nz = inputs["data:aerostructural:load_case:load_factor"] cl = nz * m_lc * g / (q * s_ref) tmp_result_file = pth.join(tmp_dir.name, self.options[OPTION_RESULT_AVL_FILENAME]) parser = InputFileGenerator() with path(ressources, _STDIN_FILE_NANE) as stdin_template: parser.set_template_file(stdin_template) parser.set_generated_file(self.stdin) # Update session file with target values: parser.mark_anchor("LOAD") parser.transfer_var(input_geom_file, 1, 1) parser.mark_anchor("OPER") parser.transfer_var(float(cl), 1, 3) parser.mark_anchor("M") parser.transfer_var(float(mach), 1, 2) parser.transfer_var(float(vtas), 2, 2) parser.transfer_var(float(rho), 3, 2) parser.mark_anchor("W") parser.transfer_var(tmp_result_file, 1, 1) parser.generate() # Check for input and output file presence ------------------------------------------------- self.options["external_input_files"] = [ self.stdin, input_geom_file, profile_file, ] self.options["external_output_files"] = [tmp_result_file] # Launch AVL ------------------------------------------------------------------------------- super().compute(inputs, outputs) # Gather results --------------------------------------------------------------------------- parser_out = FileParser() parser_out.set_file(tmp_result_file) parser_out.mark_anchor("Alpha =") aoa = parser_out.transfer_var(0, 3) parser_out.mark_anchor("CLtot =") outputs["data:aerostructural:aerodynamic:CL"] = parser_out.transfer_var(0, 3) parser_out.mark_anchor("CDind =") outputs["data:aerostructural:aerodynamic:CDi"] = parser_out.transfer_var(0, 6) outputs["data:aerostructural:aerodynamic:Oswald_Coeff"] = parser_out.transfer_var(2, 6) for (comp, sect) in zip(self.options["components"], self.options["components_sections"]): size = sect # default number of section for non symmetric components if comp in ("wing", "horizontal_tail", "strut"): size = sect * 2 # number of sections doubled for symmetric components elif comp == "fuselage": size = 4 # particular case for fuselage due to specific VLM modelling avl_comp = AVL_COMPONENT_NAMES[comp] parser_out.mark_anchor(avl_comp) comp_coef = parser_out.transfer_2Darray(0, 3, size - 1, 8) # Reorganise result array to have coefficient in direct axis order comp_coef[:, :] = comp_coef[:, [1, 3, 0, 5, 2, 4]] # Comvert coefficients into forces and moments comp_coef[:, :3] *= q * s_ref comp_coef[:, [3, 5]] *= q * s_ref * b_ref comp_coef[:, 4] *= q * s_ref * c_ref # Change forces and moment from aerodynamic to body axis r_mat = self._get_rotation_matrix(aoa * degree, axis="y") comp_coef[:, :3] = np.dot(comp_coef[:, :3], r_mat) comp_coef[:, 3:] = np.dot(comp_coef[:, 3:], r_mat) # Moments in std axis ie X fwd outputs["data:aerostructural:aerodynamic:" + comp + ":forces"] = comp_coef # outputs["data:aerostructural:aerodynamic:forces"] = q * s_ref * surface_coef # Store input and result files if necessary ------------------------------------------------ if self.options[OPTION_RESULT_FOLDER_PATH]: if pth.exists(tmp_result_file): forces_file = pth.join(result_folder_path, self.options[OPTION_RESULT_AVL_FILENAME]) shutil.move(tmp_result_file, forces_file) if pth.exists(input_geom_file): geometry_file = pth.join(result_folder_path, _AVL_GEOM_NAME) shutil.move(input_geom_file, geometry_file) if pth.exists(self.stdin): stdin_path = pth.join(result_folder_path, _STDIN_FILE_NANE) shutil.move(self.stdin, stdin_path) if pth.exists(self.stdout): stdout_path = pth.join(result_folder_path, _STDOUT_FILE_NAME) shutil.move(self.stdout, stdout_path) if pth.exists(self.stderr): stderr_path = pth.join(result_folder_path, _STDERR_FILE_NAME) shutil.move(self.stderr, stderr_path) tmp_dir.cleanup()
def compute(self, inputs, outputs): eff = inputs['eff'] length = inputs['length'] alp = inputs['alp'] eps = inputs['eps'] GL107_200 = 1 / inputs['R_m'] GL111_300 = 1 / inputs['R_p'] GL103_400 = inputs['GlTether'] GL102_601 = 1 / inputs['R_s'] GL107_111 = inputs['ci1'] GL107_109 = inputs['ci2'] GL103_109 = inputs['ci3'] GL101_109 = inputs['ci4'] GL109_111 = inputs['ci5'] GL101_103 = inputs['ci6'] GL103_111 = inputs['ci7'] GL101_107 = inputs['ci8'] GL103_105 = inputs['ci9'] GL101_105 = inputs['ci10'] GL105_111 = inputs['ci11'] GL105_107 = inputs['ci12'] r_bat = inputs['r_bat'] ht_gain = inputs['ht_gain'] q_s = inputs['q_s'] eff = '{0};'.format(float(eff)) length = '{0};'.format(float(length)) ht_gain = '{0};'.format(float(ht_gain)) r_bat = '{0};'.format(float(r_bat)) q_s = '{0};'.format(float(q_s)) alp = '{0},'.format(float(alp)) eps = '{0},'.format(float(eps)) GL107_200 = '{0};'.format(float(GL107_200)) GL111_300 = '{0};'.format(float(GL111_300)) GL103_400 = '{0};'.format(float(GL103_400)) GL102_601 = '{0};'.format(float(GL102_601)) GL107_111 = '{0};'.format(float(GL107_111)) GL107_109 = '{0};'.format(float(GL107_109)) GL103_109 = '{0};'.format(float(GL103_109)) GL101_109 = '{0};'.format(float(GL101_109)) GL109_111 = '{0};'.format(float(GL109_111)) GL101_103 = '{0};'.format(float(GL101_103)) GL103_111 = '{0};'.format(float(GL103_111)) GL101_107 = '{0};'.format(float(GL101_107)) GL103_105 = '{0};'.format(float(GL103_105)) GL101_105 = '{0};'.format(float(GL101_105)) GL105_111 = '{0};'.format(float(GL105_111)) GL105_107 = '{0};'.format(float(GL105_107)) # generate the input file for RU_tm thermal analysis generator = InputFileGenerator() generator.set_template_file('./esatan/RU_template.txt') generator.set_generated_file('./esatan/RU_tm.d') generator.mark_anchor("$LOCALS") generator.transfer_var(length, 21, 3) generator.transfer_var(eff, 23, 3) generator.transfer_var(r_bat, 25, 3) generator.transfer_var(ht_gain, 27, 3) generator.transfer_var(q_s, 29, 3) generator.mark_anchor("$NODES") generator.transfer_var(alp, 53, 6) generator.transfer_var(eps, 53, 9) generator.transfer_var(alp, 61, 6) generator.transfer_var(eps, 61, 9) generator.transfer_var(alp, 69, 6) generator.transfer_var(eps, 69, 9) generator.transfer_var(alp, 77, 6) generator.transfer_var(eps, 77, 9) generator.transfer_var(alp, 85, 6) generator.transfer_var(eps, 85, 9) generator.transfer_var(alp, 93, 6) generator.transfer_var(eps, 93, 9) generator.mark_anchor("Generated conductors") generator.transfer_var(GL107_200, 3, 3) generator.transfer_var(GL111_300, 4, 3) generator.transfer_var(GL107_111, 5, 3) generator.transfer_var(GL107_109, 6, 3) generator.transfer_var(GL103_109, 7, 3) generator.transfer_var(GL101_109, 8, 3) generator.transfer_var(GL109_111, 9, 3) generator.transfer_var(GL101_103, 10, 3) generator.transfer_var(GL103_111, 11, 3) generator.transfer_var(GL101_107, 12, 3) generator.transfer_var(GL103_105, 13, 3) generator.transfer_var(GL101_105, 14, 3) generator.transfer_var(GL105_111, 15, 3) generator.transfer_var(GL105_107, 16, 3) generator.transfer_var(GL102_601, 17, 3) generator.transfer_var(GL103_400, 45, 3) generator.generate() # the parent compute function actually runs the external code super(RUextCodeComp, self).compute(inputs, outputs) # parse the output file from the external code and set the value of T_max parser = FileParser() parser.set_file('./esatan/RU_TM.out') parser.mark_anchor("+RU_TM") tBat = parser.transfer_var(7, 3) tMain = parser.transfer_var(34, 3) tProp = parser.transfer_var(35, 3) tTether = parser.transfer_var(36, 3) tBPanel = parser.transfer_var(41, 3) tDPanel = parser.transfer_var(43, 3) outputs['tBat'] = tBat outputs['tMain'] = tMain outputs['tProp'] = tProp outputs['tTether'] = tTether outputs['tBPanel'] = tBPanel outputs['tDPanel'] = tDPanel