#!/usr/bin/env python # -*- coding: UTF-8 no BOM -*- import os,sys,string from optparse import OptionParser, OptionGroup, Option, SUPPRESS_HELP # ----------------------------- class extendedOption(Option): # ----------------------------- # used for definition of new option parser action 'extend', which enables to take multiple option arguments # taken from online tutorial http://docs.python.org/library/optparse.html ACTIONS = Option.ACTIONS + ("extend",) STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",) TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",) ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",) def take_action(self, action, dest, opt, value, values, parser): if action == "extend": lvalue = value.split(",") values.ensure_value(dest, []).extend(lvalue) else: Option.take_action(self, action, dest, opt, value, values, parser) # ----------------------- MAIN ------------------------------- parser = OptionParser(option_class=extendedOption, usage='%prog [options] spectralOut[s]', description = """ Generate datafile of converged iteration per increment. """ + string.replace('$Id$','\n','\\n') ) parser.add_option('-m','--memory', dest='memory', action='store_true', \ help='load complete file into memory [%default]') parser.add_option('-g','--gap', dest='gap', type='float', \ help='value to indicate gap between increments [%default]') parser.set_defaults(memory = False) parser.set_defaults(gap = -1) (options, filenames) = parser.parse_args() # ------------------------------------------ setup file handles --------------------------------------- files = [] if filenames == []: files.append({'name':'STDIN', 'input':sys.stdin, 'output':sys.stdout}) else: for name in filenames: if os.path.exists(name): (head,tail) = os.path.split(name) files.append({'name':name, 'input':open(name), 'output':open(os.path.join(head,'convergence_'+os.path.splitext(tail)[0]+'.txt'), 'w')}) # ------------------------------------------ loop over input files --------------------------------------- for file in files: print file['name'] inc = 1 step = 1 # ------------------------------------------ assemble header --------------------------------------- output = '1\theader\n' + \ '\t'.join(['inc','err_div']) + '\n' if options.memory: data = file['input'].readlines() else: data = [] file['output'].write(output) output = '' # ------------------------------------------ read file --------------------------------------- divergences = [] for line in {True : data, False : file['input']}[options.memory]: items = line.split() if len(items) > 7 and items[0] == 'Loadcase': # 'magic' line? if int(items[5]) != step: divergences.append(options.gap) for i,div in enumerate(divergences): output += '\t'.join(map(str,[inc+float(i)/(len(divergences)-1),div])) + '\n' step = int(items[5]) # store current step count inc += 1 # is next inc divergences = [] # reset divergences list if not options.memory: file['output'].write(output) output = '' if len(items) > 2 and items[0] == 'error' and items[1] == 'divergence:': # 'magic' line? divergences.append(float(items[2])) for i,div in enumerate(divergences): # process last step (for which, of course, no further step can be found) output += '\t'.join(map(str,[inc+float(i)/len(divergences),div])) + '\n' file['input'].close() # ------------------------------------------ output result --------------------------------------- file['output'].write(output) if file['name'] != 'STDIN': file['output'].close