def parse_output(self): """Parses the PCYL output file and extracts data.""" infile = FileParser() infile.set_file(self.stdout) self.wwingt = infile.transfer_keyvar("Total Wing Structural Weight", 1) self.wfuselaget = infile.transfer_keyvar("Fuselage Total Structural Weight", 1)
def execute(self): lenght = self.lenght radius_2 = self.radius_2 radius_4 = self.radius_4 alpha = self.alpha beta = self.beta # Prepare the input file system('del ark_stent.py') # deletes previous input file parser = InputFileGenerator() parser.set_template_file('template.py') parser.set_generated_file('ark_stent.py') parser.reset_anchor() parser.mark_anchor("lenght") parser.transfer_var(lenght, 0, 2) parser.reset_anchor() parser.mark_anchor("radius_2") parser.transfer_var(radius_2, 0, 2) parser.reset_anchor() parser.mark_anchor("radius_4") parser.transfer_var(radius_4, 0, 2) parser.reset_anchor() parser.mark_anchor("alpha") parser.transfer_var(alpha, 0, 2) parser.reset_anchor() parser.mark_anchor("beta") parser.transfer_var(beta, 0, 2) parser.generate() #Run Abaqus vi External's code execute function super(WrapAbaqus_stent, self).execute() #Parse the output files from abaqus parser = FileParser() parser.set_file('output.txt') parser.reset_anchor() parser.mark_anchor("max_mises") var = parser.transfer_var(1, 1) self.max_mises = var parser.reset_anchor() parser.mark_anchor("minus_max_displacement") var = parser.transfer_var(1, 1) self.minus_max_displacement = var print self.return_code
def load_model(self, filename): """Reads in an existing PDCYL input file and populates the variable tree with its values.""" infile = FileParser() infile.set_file(filename) # Title is a string self.title = infile.transfer_line(2) # Print flag becomes a Bool if infile.transfer_var(4, 1) == 3: self.icalc = True else: self.icalc = False # Named variables in dictionary for key, val in self._fields.iteritems(): self.set(val, infile.transfer_var(key, 1))
def execute(self): """Runs the NastranComponent. We are overiding ExternalCode's execute function. First, we setup the input file (by running NastranReplacer and then NastranMaker). Next, we run Nastran by calling our parent's execute function. Finally, we parse the data and set the output variables given to us. RuntimeError The component relies on ExternalCode which can throw all sorts of RuntimeError-like exceptions (RunStopped, RunInterrupted also included). Filesystem-type Errors NastranComponent makes a temporary directory with mkdtemp in the temp module. If that fails, the error just propagates up. While there are no explicit parameters or return values for this function, it gets all the input it needs from the design variables that are connected to the subclass of NastranComponent. This should be described pretty well in the :ref:`documentation<NastranComponent>`. """ # We are going to keep track of all the ways we # can manage input/output: # - the crude way (NastranReplacer, NastranOutput) # correspond to input_variables, output_variables # - the better way (NastranMaker, NastranParser) # correspond to smart_replacements and grid_outputs # all of these are {"traitname" : trait} input_variables = {} smart_replacements = {} output_variables = {} grid_outputs = {} for name, trait in self.traits().iteritems(): if trait.iotype == "in": # nastran_var is a variable that should be replaced if trait.nastran_var: # if the variable is longer than seven characters # it won't fit in the nastran file, since the limit # there is 8 characters (%xxxxxxx) if len(trait.nastran_var) > 7: raise ValueError("The variable " + trait.nastran + \ " is too long to be a variable") input_variables[name] = trait # it could also be a smart replacement, but we'll have # to specify the card, id, and fieldnum if trait.nastran_card and trait.nastran_id and trait.nastran_fieldnum: smart_replacements[name] = trait elif trait.nastran_card or trait.nastran_id or trait.nastran_fieldnum: raise RuntimeError("You specified at least one of " + \ "nastran_card, nastran_id, and " + \ "nastran_fieldnum, but you did " + \ "not specify all of them. You " + \ "most probably mistyped.") elif trait.iotype == "out": # if we want to supply a function that will parse # out the wanted information from the output object # and the fileparser, then this if trait.nastran_func: output_variables[name] = trait # this is the grid method of accessing. We have to # specify a header, row, and attribute and # the output variable will be set to that value if trait.nastran_header and trait.nastran_constraints and trait.nastran_columns: grid_outputs[name] = trait elif trait.nastran_header or trait.nastran_constraints or trait.nastran_columns: raise RuntimeError("You specified at least one of " + \ "nastran_header, nastran_constrains"+\ ", and nastran_columns, but you " + \ "did not specify all them. You " + \ "most probably mistyped") # let's do our work in a tmp dir # let's do our work in a tmp dir tmpdir = mkdtemp(dir = self.output_tempdir_dir) tmppath = path.join(tmpdir, "input.bdf") tmpfh = open(tmppath, "w") # raw nastran file supplied by user fh = open(self.nastran_filename, "r") # note: fh.readlines() won't work because it doesn't # strip the newline at the end for you. So whatever, # we'll just use split on newlines. nastran_text = fh.read().split("\n") fh.close() # replace the variables in the nastran text using Replacer replacer = NastranReplacer(nastran_text) varname2value = {} for name, trait in input_variables.iteritems(): varname2value[trait.nastran_var] = getattr(self, name) replacer.replace(varname2value) nastran_text = replacer.text # use nastran maker to intelligently replace # values in cards maker = NastranMaker(nastran_text) for name, trait in smart_replacements.iteritems(): value = getattr(self, name) maker.set(trait.nastran_card, trait.nastran_id, trait.nastran_fieldnum, value) self.nastran_maker_hook(maker) maker.write_to_file(tmpfh, 10001) tmpfh.close() # what is the new file called? self.output_filename = path.join(tmpdir, "input.out") # perhaps this should be logged, or something print self.output_filename # Then we run the nastran file self.command = self.nastran_command + " " + \ tmppath + " " + self.nastran_command_args + \ " batch=no out=" + tmpdir + \ " dbs=" + tmpdir # This calls ExternalCode's execute which will run # the nastran command via subprocess super(NastranComponent, self).execute() # And now we parse the output filep = FileParser() filep.set_file(self.output_filename) filep.set_delimiters(" ") # Before we start, we want to make sure we aren't # dealing with a failed run. So we search for "FATAL" for line in filep.data: if "FATAL" in line: raise RuntimeError("There was a problem with " + \ "Nastran. It failed to run " + \ "correctly. If you want to see " +\ "the output, check out " + \ self.output_filename) for output_name, output_trait in output_variables.iteritems(): # We run trait.nastran_func on filep and get the # final value we want setattr(self, output_name, output_trait.nastran_func(filep)) # This is the grid parser. self.parser = NastranParser(filep.data) self.parser.parse() for name, trait in grid_outputs.iteritems(): header = trait.nastran_header subcase = trait.nastran_subcase constraints = trait.nastran_constraints columns = trait.nastran_columns result = self.parser.get(header, subcase, \ constraints, columns) # nastran_{row,column} might be kinda silly # in most cases, the user will probably just call # self.parser.get on her own nastran_row = trait.nastran_row nastran_column = trait.nastran_column row = nastran_row or 0 col = nastran_column or 0 # Now we'll try to guess the conversion we should # perform by inspecting the type of trait that # is requesting this value converter = lambda x: x type_understood_as = "unsure" if isinstance(trait.trait_type, Float): converter = float type_understood_as = "float" elif isinstance(trait.trait_type, Int): converter = lambda x: int(float(x)) type_understood_as = "int" elif isinstance(trait.trait_type, Array): # we aren't actually going to return the entire # grid because you should use parser if you # want to do that. converter = lambda x: [x] type_understood_as = "array" try: setattr(self, name, converter(result[row][col])) except ValueError, ve: print >> sys.stderr, "Unable to convert string " + \ result[row][col] + " to " + type_understood_as raise
def parse_output(self): """Parses the HSRNOISE output file and extracts data.""" outfile = FileParser() outfile.set_file('test.output') outfile.mark_anchor("JN8C4 JET NOISE MODULE") outfile.mark_anchor("TOTAL") self.thetas = outfile.transfer_array(4, 2, 4, 18) self.Freq = outfile.transfer_2Darray(7, 1, 30, 1) self.SPL = outfile.transfer_2Darray(7, 2, 30, 18) outfile.mark_anchor("DBA") self.OASPL = outfile.transfer_array(-1, 2, -1, 18) self.OASPL30 = outfile.transfer_var(-1, 4) self.OASPL60 = outfile.transfer_var(-1, 7) self.OASPL90 = outfile.transfer_var(-1, 10) self.OASPL120 = outfile.transfer_var(-1, 13) self.OASPL150 = outfile.transfer_var(-1, 16) outfile.mark_anchor("EPNL SUMMARY") self.TotalEPNL = outfile.transfer_var(9, 2) self.TotalMaxPNLT = outfile.transfer_var(9, 5) self.JetEPNL = outfile.transfer_var(8, 2)
def test_more_delims(self): data = "anchor,1.0,2.0\n" + \ "abc=123.456\n" + \ "c=1,2,Word,6\n" + \ "d=C:/abc/def,a+b*c^2,(%#%),!true\n" + \ "a^33 1.#QNAN^#$%^" outfile = open(self.filename, 'w') outfile.write(data) outfile.close() op = FileParser() op.set_file(self.filename) olddelims = op.delimiter 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_comment_char(self): # Check to see if the use of the comment # characters works data = "Junk\n" + \ "CAnchor\n" + \ " Z 11, 22 344, Test 1e65\n" + \ " B 4 Stuff\n" + \ " $ Anchor\n" + \ " Q 1, 2 34, Test 1e65\n" + \ " B 4 Stuff\n" + \ "Anchor\n" + \ " A 1, 2 34, Test 1e65\n" + \ " B 4 Stuff\n" + \ "Anchor\n" + \ " C 77 False NaN 333.444\n" + \ " 1,2,3,4,5\n" + \ " Inf 1.#QNAN -1.#IND\n" 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_output_parse_2Darray(self): data = ''' Anchor FREQ DELTA -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 -8.5 Hz 50. 1.0 30.0 34.8 36.3 36.1 34.6 32.0 28.4 23.9 18.5 12.2 5.0 -3.1 -12.3 -22.5 -34.0 -47.2 -63.7 63. 1.0 36.5 41.3 42.8 42.6 41.1 38.5 34.9 30.4 25.0 18.7 11.5 3.4 -5.8 -16.0 -27.5 -40.7 -57.2 80. 1.0 42.8 47.6 49.1 48.9 47.4 44.8 41.2 36.7 31.3 25.0 17.8 9.7 0.5 -9.7 -21.2 -34.4 -50.9 100. 1.0 48.4 53.1 54.7 54.5 53.0 50.4 46.8 42.3 36.9 30.6 23.3 15.2 6.1 -4.2 -15.7 -28.9 -45.4 125. 1.0 53.6 58.3 59.9 59.6 58.1 55.5 52.0 47.5 42.0 35.7 28.5 20.4 11.2 1.0 -10.5 -23.7 -40.2 160. 1.0 58.9 63.7 65.2 65.0 63.5 60.9 57.3 52.8 47.4 41.0 33.8 25.7 16.5 6.3 -5.2 -18.4 -34.9 200. 1.0 63.4 68.1 69.6 69.4 67.9 65.3 61.7 57.2 51.8 45.5 38.3 30.1 21.0 10.7 -0.8 -14.0 -30.5 250. 1.0 67.5 72.2 73.7 73.5 72.0 69.4 65.8 61.3 55.9 49.5 42.3 34.2 25.0 14.8 3.3 -10.0 -26.5 315. 1.0 71.3 76.1 77.6 77.4 75.8 73.2 69.7 65.1 59.7 53.4 46.1 38.0 28.8 18.6 7.1 -6.2 -22.7 400. 1.0 74.9 79.7 81.2 81.0 79.4 76.8 73.2 68.7 63.2 56.9 49.7 41.5 32.4 22.1 10.6 -2.7 -19.2 500. 1.0 77.9 82.7 84.2 83.9 82.4 79.8 76.2 71.6 66.2 59.8 52.6 44.4 35.3 25.0 13.5 0.2 -16.3 630. 1.0 80.7 85.4 86.9 86.6 85.1 82.4 78.8 74.3 68.8 62.5 55.2 47.0 37.9 27.6 16.1 2.8 -13.7 800. 1.0 83.1 87.8 89.2 89.0 87.4 84.8 81.2 76.6 71.1 64.8 57.5 49.3 40.1 29.9 18.3 5.0 -11.5 1000. 1.0 84.9 89.6 91.1 90.8 89.2 86.6 82.9 78.4 72.9 66.5 59.2 51.0 41.8 31.5 20.0 6.6 -9.9 1250. 1.0 86.4 91.1 92.5 92.2 90.7 88.0 84.3 79.7 74.2 67.8 60.5 52.3 43.1 32.8 21.2 7.9 -8.7 1600. 1.0 87.6 92.3 93.7 93.4 91.8 89.1 85.4 80.8 75.2 68.8 61.5 53.3 44.0 33.7 22.1 8.7 -7.9 2000. 1.0 88.4 93.0 94.4 94.0 92.4 89.6 85.9 81.3 75.7 69.3 61.9 53.7 44.4 34.0 22.4 9.0 -7.6 2500. 1.0 88.7 93.3 94.6 94.2 92.6 89.8 86.1 81.4 75.8 69.3 61.9 53.6 44.3 33.9 22.2 8.8 -7.9 3150. 1.0 88.7 93.2 94.5 94.1 92.4 89.5 85.7 81.0 75.4 68.8 61.4 53.0 43.7 33.3 21.5 8.1 -8.6 4000. 1.0 88.3 92.7 94.0 93.5 91.7 88.8 85.0 80.2 74.5 67.9 60.4 52.0 42.5 32.0 20.2 6.7 -10.0 5000. 1.0 87.5 91.9 93.1 92.5 90.7 87.7 83.8 78.9 73.2 66.5 58.9 50.4 40.9 30.4 18.5 4.9 -11.9 6300. 1.0 86.5 90.8 91.9 91.2 89.3 86.2 82.2 77.3 71.4 64.6 57.0 48.4 38.8 28.1 16.2 2.5 -14.5 8000. 1.0 85.3 89.5 90.4 89.6 87.6 84.4 80.2 75.2 69.2 62.3 54.5 45.8 36.1 25.3 13.2 -0.6 -17.7 10000. 1.0 84.2 88.2 89.0 88.1 85.9 82.5 78.3 73.0 66.9 59.9 51.9 43.1 33.2 22.3 10.1 -3.9 -21.1 ''' outfile = open(self.filename, 'w') outfile.write(data) outfile.close() gen = FileParser() gen.set_file(self.filename) # whitespace delim; with end field gen.set_delimiters(' \t') gen.mark_anchor('Anchor') val = gen.transfer_2Darray(3, 2, 26, 19) self.assertEqual(val[0, 1], 30.0) self.assertEqual(val[0, 17], -63.7) self.assertEqual(val[1, 17], -57.2) self.assertEqual(val[23, 17], -21.1) self.assertEqual(val.shape[0], 24) self.assertEqual(val.shape[1], 18) # whitespace delim; no end field val = gen.transfer_2Darray(3, 2, 26) self.assertEqual(val[0, 1], 30.0) self.assertEqual(val[23, 17], -21.1) self.assertEqual(val.shape[0], 24) self.assertEqual(val.shape[1], 18) # column delim; with end field gen.set_delimiters('columns') val = gen.transfer_2Darray(3, 19, 26, 125) self.assertEqual(val[0, 1], 30.0) self.assertEqual(val[0, 17], -63.7) self.assertEqual(val[1, 17], -57.2) self.assertEqual(val[23, 17], -21.1) self.assertEqual(val.shape[0], 24) self.assertEqual(val.shape[1], 18) # column delim; no end field val = gen.transfer_2Darray(3, 19, 26) self.assertEqual(val[0, 1], 30.0) self.assertEqual(val[0, 17], -63.7) self.assertEqual(val[1, 17], -57.2) self.assertEqual(val[23, 17], -21.1) self.assertEqual(val.shape[0], 24) self.assertEqual(val.shape[1], 18) # make sure single line works gen.set_delimiters(' \t') val = gen.transfer_2Darray(5, 3, 5, 5) self.assertEqual(val[0, 2], 49.1) # Small block read val = gen.transfer_2Darray(7, 3, 9, 6) self.assertEqual(val[0, 0], 53.6) self.assertEqual(val[2, 0], 63.4) # Error messages for bad values try: gen.transfer_2Darray(7, 3, 9, 1) except ValueError, err: msg = "fieldend must be greater than fieldstart" self.assertEqual(str(err), msg)
def test_output_parse_array(self): data = "Anchor\n" + \ "10 20 30 40 50 60 70 80\n" + \ "11 21 31 41 51 61 71 81\n" + \ "Key a b c d e\n" 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_array(1, 1, 1, 8) self.assertEqual(val[0], 10) self.assertEqual(val[7], 80) val = gen.transfer_array(1, 5, 2, 6) self.assertEqual(val[0], 50) self.assertEqual(val[9], 61) gen.mark_anchor('Key') val = gen.transfer_array(0, 2, 0, 6) self.assertEqual(val[4], 'e') val = gen.transfer_array(0, 2, fieldend=6) self.assertEqual(val[4], 'e') # Now, let's try column delimiters gen.reset_anchor() gen.mark_anchor('Anchor') gen.set_delimiters('columns') val = gen.transfer_array(1, 7, 1, 15) self.assertEqual(val[0], 30) self.assertEqual(val[2], 50) val = gen.transfer_array(1, 10, 2, 18) self.assertEqual(val[0], 40) self.assertEqual(val[5], 61) val = gen.transfer_array(3, 5, 3, 10) self.assertEqual(val[0], 'a b c') try: gen.transfer_array(1, 7, 1) except ValueError, err: msg = "fieldend is missing, currently required" self.assertEqual(str(err), msg)
def execute(self): """Runs the NastranComponent. We are overiding ExternalCode's execute function. First, we setup the input file (by running NastranReplacer and then NastranMaker). Next, we run Nastran by calling our parent's execute function. Finally, we parse the data and set the output variables given to us. RuntimeError The component relies on ExternalCode which can throw all sorts of RuntimeError-like exceptions (RunStopped, RunInterrupted also included). Filesystem-type Errors NastranComponent makes a temporary directory with mkdtemp in the temp module. If that fails, the error just propagates up. While there are no explicit parameters or return values for this function, it gets all the input it needs from the design variables that are connected to the subclass of NastranComponent. This should be described pretty well in the :ref:`documentation<NastranComponent>`. """ # We are going to keep track of all the ways we # can manage input/output: # - the crude way (NastranReplacer, NastranOutput) # correspond to input_variables, output_variables # - the better way (NastranMaker, NastranParser) # correspond to smart_replacements and grid_outputs # all of these are {"traitname" : trait} input_variables = {} smart_replacements = {} output_variables = {} grid_outputs = {} for name, trait in self.traits().iteritems(): if trait.iotype == "in": # nastran_var is a variable that should be replaced if trait.nastran_var: # if the variable is longer than seven characters # it won't fit in the nastran file, since the limit # there is 8 characters (%xxxxxxx) if len(trait.nastran_var) > 7: raise ValueError("The variable " + trait.nastran + \ " is too long to be a variable") input_variables[name] = trait # it could also be a smart replacement, but we'll have # to specify the card, id, and fieldnum if trait.nastran_card and trait.nastran_id and trait.nastran_fieldnum: smart_replacements[name] = trait elif trait.nastran_card or trait.nastran_id or trait.nastran_fieldnum: raise RuntimeError("You specified at least one of " + \ "nastran_card, nastran_id, and " + \ "nastran_fieldnum, but you did " + \ "not specify all of them. You " + \ "most probably mistyped.") elif trait.iotype == "out": # if we want to supply a function that will parse # out the wanted information from the output object # and the fileparser, then this if trait.nastran_func: output_variables[name] = trait # this is the grid method of accessing. We have to # specify a header, row, and attribute and # the output variable will be set to that value if trait.nastran_header and trait.nastran_constraints and trait.nastran_columns: grid_outputs[name] = trait elif trait.nastran_header or trait.nastran_constraints or trait.nastran_columns: raise RuntimeError("You specified at least one of " + \ "nastran_header, nastran_constrains"+\ ", and nastran_columns, but you " + \ "did not specify all them. You " + \ "most probably mistyped") # let's do our work in a tmp dir tmpdir = mkdtemp(dir=self.output_tempdir_dir) tmppath = path.join(tmpdir, "input.bdf") tmpfh = open(tmppath, "w") # raw nastran file supplied by user fh = open(self.nastran_filename, "r") # note: fh.readlines() won't work because it doesn't # strip the newline at the end for you. So whatever, # we'll just use split on newlines. nastran_text = fh.read().split("\n") fh.close() # replace the variables in the nastran text using Replacer replacer = NastranReplacer(nastran_text) varname2value = {} for name, trait in input_variables.iteritems(): varname2value[trait.nastran_var] = getattr(self, name) replacer.replace(varname2value) nastran_text = replacer.text # use nastran maker to intelligently replace # values in cards maker = NastranMaker(nastran_text) for name, trait in smart_replacements.iteritems(): value = getattr(self, name) maker.set(trait.nastran_card, trait.nastran_id, trait.nastran_fieldnum, value) self.nastran_maker_hook(maker) maker.write_to_file(tmpfh, 10001) tmpfh.close() # what is the new file called? self.output_filename = path.join(tmpdir, "input.out") # perhaps this should be logged, or something print self.output_filename # Then we run the nastran file if self.nastran_command == 'python': # True when using fake_nastran.py self.command = [ self.nastran_command, self.nastran_command_args[0], tmppath ] self.command.extend(self.nastran_command_args[1:]) else: self.command = [self.nastran_command, tmppath] self.command.extend(self.nastran_command_args) self.command.extend(["batch=no", "out=" + tmpdir, "dbs=" + tmpdir]) # This calls ExternalCode's execute which will run # the nastran command via subprocess super(NastranComponent, self).execute() # And now we parse the output filep = FileParser() filep.set_file(self.output_filename) filep.set_delimiters(" ") # Before we start, we want to make sure we aren't # dealing with a failed run. So we search for "FATAL" for line in filep.data: if "FATAL" in line: raise RuntimeError("There was a problem with " + \ "Nastran. It failed to run " + \ "correctly. If you want to see " +\ "the output, check out " + \ self.output_filename) for output_name, output_trait in output_variables.iteritems(): # We run trait.nastran_func on filep and get the # final value we want setattr(self, output_name, output_trait.nastran_func(filep)) # This is the grid parser. self.parser = NastranParser(filep.data) self.parser.parse() for name, trait in grid_outputs.iteritems(): header = trait.nastran_header subcase = trait.nastran_subcase constraints = trait.nastran_constraints columns = trait.nastran_columns result = self.parser.get(header, subcase, \ constraints, columns) # nastran_{row,column} might be kinda silly # in most cases, the user will probably just call # self.parser.get on her own nastran_row = trait.nastran_row nastran_column = trait.nastran_column row = nastran_row or 0 col = nastran_column or 0 # Now we'll try to guess the conversion we should # perform by inspecting the type of trait that # is requesting this value converter = lambda x: x type_understood_as = "unsure" if isinstance(trait.trait_type, Float): converter = float type_understood_as = "float" elif isinstance(trait.trait_type, Int): converter = lambda x: int(float(x)) type_understood_as = "int" elif isinstance(trait.trait_type, Array): # we aren't actually going to return the entire # grid because you should use parser if you # want to do that. converter = lambda x: [x] type_understood_as = "array" try: setattr(self, name, converter(result[row][col])) except ValueError, ve: print >> sys.stderr, "Unable to convert string " + \ result[row][col] + " to " + type_understood_as raise
def test_output_parse_same_anchors(self): data = "CQUAD4 1 3.456\n" + \ "CQUAD4 2 4.123\n" + \ "CQUAD4 3 7.222\n" + \ "CQUAD4 4\n" 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 load_model(self, filename="test.input"): """Loads an existing HSRNOISE input file.""" infile = FileParser() infile.set_file(filename) infile.mark_anchor('$GEOM') self.HMIC = float(infile.transfer_keyvar("HMIC", 2)) self.SL = float(infile.transfer_keyvar("SL", 2)) infile.mark_anchor('$FLIPATH') self.ALTEVO = float(infile.transfer_keyvar("ALTEVO", 2)) self.HMIC = int(infile.transfer_keyvar("JETMETHOD", 2)) infile.mark_anchor('$JET1IN') self.geo_in.Apri = float(infile.transfer_keyvar("APRI", 2)) self.geo_in.Asec = float(infile.transfer_keyvar("ASEC", 2)) self.ATHP = float(infile.transfer_keyvar("ATHP", 2)) self.DELMIX = float(infile.transfer_keyvar("DELMIX", 2)) self.DELPE = float(infile.transfer_keyvar("DELPE", 2)) self.DELPI = float(infile.transfer_keyvar("DELPI", 2)) self.geo_in.ChuteAngles = float(infile.transfer_keyvar("DIVANG", 2)) self.geo_in.AR = float(infile.transfer_keyvar("EJASP", 2)) self.EJD = float(infile.transfer_keyvar("EJD", 2)) self.geo_in.length = float(infile.transfer_keyvar("EJL", 2)) self.EJLIN = float(infile.transfer_keyvar("EJLIN", 2)) self.FLIN = float(infile.transfer_keyvar("FLIN", 2)) self.geo_in.LhMh = float(infile.transfer_keyvar("PEN", 2)) self.PLUGD = float(infile.transfer_keyvar("PLUGD", 2)) self.PSI0 = float(infile.transfer_keyvar("PSI0", 2)) self.SPOKE = float(infile.transfer_keyvar("SPOKE", 2)) self.flow_in.pri.Tt = float(infile.transfer_keyvar("TPRI", 2)) self.flow_in.sec.Tt = float(infile.transfer_keyvar("TSEC", 2)) self.flow_in.pri.Vel = float(infile.transfer_keyvar("VPRI", 2)) self.flow_in.sec.Vel = float(infile.transfer_keyvar("VSEC", 2)) self.flow_in.pri.W = float(infile.transfer_keyvar("WPRI", 2)) self.flow_in.sec.W = float(infile.transfer_keyvar("WSEC", 2)) self.geo_in.AeAt = float(infile.transfer_keyvar("XMAR", 2)) infile.mark_anchor('$JET2IN') self.APT = float(infile.transfer_keyvar("APT", 2)) self.AS = float(infile.transfer_keyvar("AS", 2)) self.CER = float(infile.transfer_keyvar("CER", 2)) self.DHP = float(infile.transfer_keyvar("DHP", 2)) self.DL = float(infile.transfer_keyvar("DL", 2)) self.DM = float(infile.transfer_keyvar("DM", 2)) self.FPK = float(infile.transfer_keyvar("FPK", 2)) self.GAMMAC = float(infile.transfer_keyvar("GAMMAC", 2)) self.HEX = float(infile.transfer_keyvar("HEX", 2)) self.IEX = int(infile.transfer_keyvar("IEX", 2)) self.ISUPPR = int(infile.transfer_keyvar("ISUPPR", 2)) self.LBE = float(infile.transfer_keyvar("LBE", 2)) self.LBS = float(infile.transfer_keyvar("LBS", 2)) self.LE = float(infile.transfer_keyvar("LE", 2)) self.LPE = float(infile.transfer_keyvar("LPE", 2)) self.LPS = float(infile.transfer_keyvar("LPS", 2)) self.MMC = float(infile.transfer_keyvar("MMC", 2)) self.MPD = float(infile.transfer_keyvar("MPD", 2)) self.PC = float(infile.transfer_keyvar("PC", 2)) self.PEN = float(infile.transfer_keyvar("PEN", 2)) self.SAR = float(infile.transfer_keyvar("SAR", 2)) self.SUPPK = float(infile.transfer_keyvar("SUPPK", 2)) self.TC = float(infile.transfer_keyvar("TC", 2)) self.TEX = float(infile.transfer_keyvar("TEX", 2)) self.VEX = float(infile.transfer_keyvar("VEX", 2)) self.WEX = float(infile.transfer_keyvar("WEX", 2)) self.WSWP = float(infile.transfer_keyvar("WSWP", 2)) # Set derived values down in the variable trees. self.LinFrac = self.EJLIN/self.geo_in.length self.phi = degrees(arcsin(0.1*self.SL)) self.geo_in.Num_Lobes = self.SPOKE self.geo_in.Aexit = pi*(0.5*self.EJD)**2 # Where does gamma come from? self.flow_in.gamma = 1.4 # use fixed-point iteration to solve for mach mach = 1.0 gam = self.flow_in.gamma apri = self.geo_in.Apri athp = self.ATHP term1 = ((gam+1)/2)**((-gam-1)/(2*(gam-1))) exp1 = ((gam+1)/(2*(gam-1))) for i in range(135): mach = athp/(apri/(term1*(1+(gam-1)/2*mach**2)**exp1)) self.flow_in.pri.Mach = mach
def execute(self): super(Comp_Plate, self).execute() parser = FileParser() parser.set_file(self.nastran_filename) self.comp_elm_dict = {} parser.reset_anchor() for cquad4 in range(1,26): parser.mark_anchor("CQUAD4") elmtype = parser.transfer_var(0, 1) elmid = parser.transfer_var(0, 2) pid = parser.transfer_var(0, 3) if pid not in self.comp_elm_dict: self.comp_elm_dict[ pid ] = [] self.comp_elm_dict[pid].append( elmid ) max_minor_strain_by_pid, max_major_strain_by_pid = self.calculate_max_strains() self.property1_max_major_strain = max_major_strain_by_pid[ 801 ] self.property2_max_major_strain = max_major_strain_by_pid[ 802 ] self.property3_max_major_strain = max_major_strain_by_pid[ 803 ] self.property1_max_minor_strain = max_minor_strain_by_pid[ 801 ] self.property2_max_minor_strain = max_minor_strain_by_pid[ 802 ] self.property3_max_minor_strain = max_minor_strain_by_pid[ 803 ] # Calculate the maximum strain (max(major,minor)) for each property self.property1_max_major_minor_strain = max( self.property1_max_major_strain, self.property1_max_minor_strain ) self.property2_max_major_minor_strain = max( self.property2_max_major_strain, self.property2_max_minor_strain ) self.property3_max_major_minor_strain = max( self.property3_max_major_strain, self.property3_max_minor_strain )
def parse_output(self,FabriOrSub): """Parses the DREA output file and extracts data.""" infile = FileParser() infile.set_file('ejectd.out') infile.mark_anchor('EJECTOR SOLUTION') if FabriOrSub == 'Fabri': self.GrossThrust = infile.transfer_keyvar("SUPERSONIC GROSS THRUST (OVERALL)=", 1) self.ExitMassFlow = infile.transfer_keyvar("SUPERSONIC EXIT MASS FLOW RATE=", 1) self.ExitVelocity = infile.transfer_keyvar("SUP VELOCITY=", 1) self.ExitMach = infile.transfer_keyvar("SUPERSONIC MACH=", 1) self.ExitStaticTemp = infile.transfer_keyvar("SUP TEMPERATURE=", 1) self.ExitTotalTemp = infile.transfer_keyvar("SUPERSONIC TOTAL TEMPERATURE=", 1) self.CFG = infile.transfer_keyvar("SUPERSONIC CFG=", 1) if FabriOrSub == 'Subsonic': self.GrossThrust = infile.transfer_keyvar("SUBSONIC GROSS THRUST (OVERALL)=", 1) self.ExitMassFlow = infile.transfer_keyvar("SUBSONIC EXIT MASS FLOW RATE=", 1) self.ExitVelocity = infile.transfer_keyvar("SUB VELOCITY=", 1) self.ExitMach = infile.transfer_keyvar("SUBSONIC MACH=", 1) self.ExitStaticTemp = infile.transfer_keyvar("SUB TEMPERATURE=", 1) self.ExitTotalTemp = infile.transfer_keyvar("SUBSONIC TOTAL TEMPERATURE=", 1) self.CFG = infile.transfer_keyvar("SUBSONIC CFG=", 1) self.flow_out.pri.Vel = infile.transfer_keyvar("U1D=",1) self.flow_out.sec.Vel = infile.transfer_keyvar("U2D=",1) self.flow_out.pri.W = infile.transfer_keyvar("RMD1D=",1)*2*32.17405 #Doubled since half of the area is used self.flow_out.sec.W = infile.transfer_keyvar("RMD2D=",1)*2*32.17405 #Doubled since half of the area is used self.PumpingRatio = infile.transfer_keyvar("PUMPING RATIO W2/W1=",1) self.flow_out.sec.Mach = infile.transfer_keyvar("RM2=", 1) self.DegreeOfMixing = infile.transfer_keyvar("DEGREE OF MIXING IN PRESSURE CONSTRAINT",0,rowoffset=1) self.NPR = infile.transfer_keyvar("NPR=",1)
def load_model(self, control_input='control.in', flocond_input='flocond.in', expnd_input='expnd.in', zrdmix_input='zrdmix.in', hwall_input='hwall.in'): '''Reads in an existing set of input files and populates the model.''' ignore = ['ist', 'ifab'] ct = Namelist(self) ct.set_filename(control_input) ct.parse_file() ct.load_model(ignore=ignore) ignore = ['p01d', 'p02d', 't01d', 't02d', 'rm1', 'rm2', 'gam', 'pinf', 'a1d', 'a2d', 'a3d'] fc = Namelist(self) fc.set_filename(flocond_input) fc.parse_file() fc.load_model(ignore=ignore) self.flow_in.pri.Pt = fc.find_card('floc', 'p01d') self.flow_in.sec.Pt = fc.find_card('floc', 'p02d') self.flow_in.pri.Tt = fc.find_card('floc', 't01d') self.flow_in.sec.Tt = fc.find_card('floc', 't02d') self.flow_in.pri.Mach = fc.find_card('floc', 'rm1') self.flow_in.sec.Mach = fc.find_card('floc', 'rm2') self.flow_in.gamma = fc.find_card('floc', 'gam') self.flow_in.Pstatic = fc.find_card('floc', 'pinf') a1d = fc.find_card('floc', 'a1d') a2d = fc.find_card('floc', 'a2d') a3d = fc.find_card('floc', 'a3d') ep = Namelist(self) ep.set_filename(expnd_input) ep.parse_file() ep.load_model() ignore = ['RLD', 'H0LM', 'H0HY', 'ALP1', 'ALP2', 'BWID'] zr = Namelist(self) zr.set_filename(zrdmix_input) zr.parse_file() zr.load_model(ignore=ignore) self.geo_in.length = zr.find_card('zrd', 'RLD') self.geo_in.LhWave = zr.find_card('zrd', 'H0LM') self.geo_in.LhMh = zr.find_card('zrd', 'H0HY') self.geo_in.ChuteAngles = zr.find_card('zrd', 'ALP1') #self.geo_in.ChuteAngles = zr.find_card('zrd', 'ALP2') BWID = zr.find_card('zrd', 'BWID') parser = FileParser() parser.set_file(hwall_input) parser.set_delimiters(", ") nrow = parser.transfer_var(0, 1) geom = zeros((nrow, 2), 'd') for index in range(nrow): geom[index, :] = parser.transfer_array(1+index, 1, 1+index, 2) self.geom = geom # Reverse area calculations for AsAp, AeAt and AR # Note that DREA only uses half the area as it assumes a plane of symmetry self.geo_in.Apri = 2.0*a1d self.geo_in.AsAp = 2.0*a2d/self.geo_in.Apri self.geo_in.Asec = self.geo_in.AsAp*self.geo_in.Apri self.geo_in.AeAt = 2.0*a3d/(self.geo_in.Apri+self.geo_in.Asec) self.geo_in.AR = BWID*BWID/(self.geo_in.Apri+self.geo_in.Asec) #self.geo_in.length = self.geom[-1, 0] self.geo_in.width = 0.5*(self.geo_in.Apri + self.geo_in.Asec)/self.geom[0,1] self.geo_in.Aexit = 2.0*self.geom[-1,1]*self.geo_in.width
def parse_output(self): """Parses the HSRNOISE output file and extracts data.""" outfile = FileParser() outfile.set_file('test.output') outfile.mark_anchor("JN8C4 JET NOISE MODULE") outfile.mark_anchor("TOTAL") self.thetas = outfile.transfer_array(4,2,4,18) self.Freq = outfile.transfer_2Darray(7,1,30,1) self.SPL = outfile.transfer_2Darray(7,2,30,18) outfile.mark_anchor("DBA") self.OASPL = outfile.transfer_array(-1, 2, -1, 18) self.OASPL30 = outfile.transfer_var(-1, 4) self.OASPL60 = outfile.transfer_var(-1, 7) self.OASPL90 = outfile.transfer_var(-1, 10) self.OASPL120 = outfile.transfer_var(-1, 13) self.OASPL150 = outfile.transfer_var(-1, 16) outfile.mark_anchor("EPNL SUMMARY") self.TotalEPNL = outfile.transfer_var(9, 2) self.TotalMaxPNLT = outfile.transfer_var(9, 5) self.JetEPNL = outfile.transfer_var(8, 2)
def test_output_parse_keyvar(self): data = "Anchor\n" + \ " Key1 1 2 3.7 Test 1e65\n" + \ " Key1 3 4 3.2 ibg 0.0003\n" + \ " Key1 5 6 6.7 Tst xxx\n" 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_keyvar('Key1', 3) self.assertEqual(val, 3.7) val = gen.transfer_keyvar('Key1', 4, -2) self.assertEqual(val, 'ibg') val = gen.transfer_keyvar('Key1', 4, -2, -1) self.assertEqual(val, 'Test') try: gen.transfer_keyvar('Key1', 4, 0) except ValueError, err: msg = "The value for occurrence must be a nonzero integer" self.assertEqual(str(err), msg)
def test_output_parse(self): data = "Junk\n" + \ "Anchor\n" + \ " A 1, 2 34, Test 1e65\n" + \ " B 4 Stuff\n" + \ "Anchor\n" + \ " C 77 False NaN 333.444\n" + \ " 1,2,3,4,5\n" + \ " Inf 1.#QNAN -1.#IND\n" 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, err: msg = "The value for occurrence must be an integer" self.assertEqual(str(err), msg)
def parse_output(self, FabriOrSub): """Parses the DREA output file and extracts data.""" infile = FileParser() infile.set_file('ejectd.out') infile.mark_anchor('EJECTOR SOLUTION') if FabriOrSub == 'Fabri': self.GrossThrust = infile.transfer_keyvar( "SUPERSONIC GROSS THRUST (OVERALL)=", 1) self.ExitMassFlow = infile.transfer_keyvar( "SUPERSONIC EXIT MASS FLOW RATE=", 1) self.ExitVelocity = infile.transfer_keyvar("SUP VELOCITY=", 1) self.ExitMach = infile.transfer_keyvar("SUPERSONIC MACH=", 1) self.ExitStaticTemp = infile.transfer_keyvar("SUP TEMPERATURE=", 1) self.ExitTotalTemp = infile.transfer_keyvar( "SUPERSONIC TOTAL TEMPERATURE=", 1) self.CFG = infile.transfer_keyvar("SUPERSONIC CFG=", 1) if FabriOrSub == 'Subsonic': self.GrossThrust = infile.transfer_keyvar( "SUBSONIC GROSS THRUST (OVERALL)=", 1) self.ExitMassFlow = infile.transfer_keyvar( "SUBSONIC EXIT MASS FLOW RATE=", 1) self.ExitVelocity = infile.transfer_keyvar("SUB VELOCITY=", 1) self.ExitMach = infile.transfer_keyvar("SUBSONIC MACH=", 1) self.ExitStaticTemp = infile.transfer_keyvar("SUB TEMPERATURE=", 1) self.ExitTotalTemp = infile.transfer_keyvar( "SUBSONIC TOTAL TEMPERATURE=", 1) self.CFG = infile.transfer_keyvar("SUBSONIC CFG=", 1) self.flow_out.pri.Vel = infile.transfer_keyvar("U1D=", 1) self.flow_out.sec.Vel = infile.transfer_keyvar("U2D=", 1) self.flow_out.pri.W = infile.transfer_keyvar( "RMD1D=", 1) * 2 # Doubled since half of the area is used self.flow_out.sec.W = infile.transfer_keyvar( "RMD2D=", 1) * 2 # Doubled since half of the area is used self.PumpingRatio = infile.transfer_keyvar("PUMPING RATIO W2/W1=", 1) self.flow_out.sec.Mach = infile.transfer_keyvar("RM2=", 1) self.DegreeOfMixing = infile.transfer_keyvar( "DEGREE OF MIXING IN PRESSURE CONSTRAINT", 0, rowoffset=1) self.NPR = infile.transfer_keyvar("NPR=", 1)