def run_abq(inp, outdir, np, descr): wd = path.join(outdir, path.splitext(path.basename(inp))[0]) if descr != "": wd += '-' + descr print '\n' print '--------------------------------------------------------------------------------' print '-- RUNNING ABAQUS:', inp, descr, '(' + str(np) + ' processors)' print '-- IN:', wd print '--------------------------------------------------------------------------------' if path.exists(wd): shutil.rmtree(wd) if not inp.endswith('.inp'): utility.print_error('Input file must be a .inp Abaqus run file.', False) return 0 # Prepare the directories. os.makedirs(wd) inpNEW = path.join(wd, 'job.inp') if not utility.safe_hardlink(inp, inpNEW): shutil.rmtree(wd) return 0 create_env(np, wd) # Run the simulation. rootdir = os.getcwd() os.chdir(wd) tstart = time.time() cmd = [ABAQUS, 'job=job', 'input=job.inp', 'interactive'] try: utility.run_cmd_screen(cmd) except Exception: utility.print_error(sys.exc_info()[0], False) return 0 finally: print 'TIME ELAPSED: ', utility.time_elapsed(tstart) os.chdir(rootdir) return 1
def get(self, key): if not self.initialized: utility.print_error(f'PRM NOT initialized') raise Exception if key in self.param_list: return self.param_list[key] return None
def print_parameter(self): if not self.initialized: utility.print_error(f'PRM NOT initialized') raise Exception utility.print_info(f'PRM print parameter') for key, val in param_list.items(): utility.print_info(f'PRM key = {key + ",":18} ' + f'val = {val}')
def get_name(t): name = str() if t.find('u') >= 0: name += 'Uniaxial' if t.find('b') >= 0: name += 'Biaxial' if t.find('p') >= 0: name += 'Planar' if len(name) == 0: utility.print_error('Invalid type in get_name: ' + t, True) return name
def predict_mean(y_train, y_test): print('Running mean-value prediction model...') mean = np.mean(y_train) print('Mean value: ' + str(mean)) print('Training set:') utility.print_error(np.repeat(mean, len(y_train)), y_train) print('Test set:') utility.print_error(np.repeat(mean, len(y_test)), y_test) print()
def calc_params(data, descr, terms, poisson, num_points, ext): maxitr = 100 # Default = 100 nparams = 2 * terms + 2 print '---------------------------------------------------------' print ' Calculating', str( terms) + '-term fit with', num_points, 'guess(es)' print '---------------------------------------------------------' S_best = -1.0e8 iname = descr + '--' + str(terms) + 'terms' + ext title = 'Prony Series ' + str(terms) + '-term Fit' for i in range(num_points): p0 = np.longdouble(np.random.random_sample(nparams)) p0[range(3, nparams, 2)] = p0[range(3, nparams, 2)] * 5.0 print '\tStarting point ' + str(i) try: if poisson == 0.5: popt = CF.curve_fit1_basinhopping(prony, data[:, 0], data[:, 1], p0, maxitr) else: # TODO - how to do the bulk fitting? Completely seperately? U.print_error("Bulk fitting not yet supported, use nu=0.5", True) popt = CF.curve_fit2(prony, data[:, 0], data[:, 1], prony, data[:, 0], data[:, 2], p0, maxitr) except Exception: print '\t\tERROR:', sys.exc_info()[1] continue S = calculate_rsquared(data, poisson, popt) print '\t\tRsquared: ', S if S <= S_best: continue if (popt[range(2, nparams, 2)] / popt[0] > 1.0).any(): print '\t\t** Good result, but invalid for Abaqus. Continuing... **' continue S_best = S print '\t\tM0: ', popt[0] print '\t\t** New Best Result. Updating Plots **' # Plot results. ax = [] fig = pyplot.figure(figsize=(10, 6)) ax.append(fig.add_subplot(121)) ax.append(ax[0].twinx()) ax.append(fig.add_subplot(122)) create_data_plots(ax, data, popt) create_error_plot(ax[2], data, popt, S) pyplot.suptitle(title, fontweight="bold") pyplot.savefig(iname) pyplot.close() MU.write_viscomatfile(descr, popt[0], popt[2:]) params = np.concatenate((popt, [S_best])) if S_best != -1.0e8: print '\n\tBest-fit Rsquared:', params[-1] else: U.print_error("No suitable fit found.", False) return np.zeros(nparams + 1) print '\n\n' return params
def get_model(mname): for model in model_list(): if model.name() == mname: break else: utility.print_error('Invalid material model: ' + mname, False) print 'Options are:' for model in model_list(): print '\t', model.name(), '\t', model.pname(), ' - ', model.descr() print '\n' exit(1) return model
def plot_fem_energy(axis,rpt): try: data = np.loadtxt(rpt,skiprows=3) except: utility.print_error('Problem reading .rpt file: '+rpt,False) return if len(data.shape)==1: print '\tNot enough datapoints, skipping file.' return axis.plot(data[:,0], data[:,1], 'ko-', label='Internal Energy', markersize=3) axis.plot(data[:,0], data[:,2], 'rs-', label='Kinetic Energy', markersize=3) axis.set_xlabel('Time (meaningless units)') axis.set_ylabel('Energy')
def plot_exp_data(axis, fname, test, line='', labelpref=''): # Load the file. try: if fname.endswith('.csv'): alldata = np.loadtxt(fname, delimiter=',') elif fname.endswith('.txt'): alldata = np.loadtxt(fname) except: utility.print_error('Problem reading experimental data file: ' + fname, True) cm = pyplot.get_cmap('gist_rainbow') if test == 'linU': axis.plot([2.0, 2.0], [0.0, 50.0], '-', color='0.35', linewidth=3) if labelpref != '': labelpref = labelpref + ' - ' npress = alldata.shape[1] / 2 colors = [cm(float(i) / npress) for i in range(npress)] for i in range(npress): # Note that we skip the first row, since it contains the pressure data. # label = labelpref + str(alldata[0,2*i]) + r' ${}^N\!/{}_{mm^2}$' label = labelpref + str(int(1000 * alldata[0, 2 * i])) + ' kPa' axis.plot(alldata[1:, 2 * i], alldata[1:, 2 * i + 1], line, color=colors[i], label=label) elif test == 'linF' or test == 'bndF': if labelpref != '': labelpref = labelpref + ' - ' pressures = np.unique(alldata[:, 2]) npress = len(pressures) - 1 # Don't seperately plot the 0 pressure. colors = [cm(float(i) / npress) for i in range(npress)] T = [] F = [] P = alldata[0, 2] for i in range(alldata.shape[0]): if alldata[i, 2] == P or alldata[i, 2] == 0.0: P = max(alldata[i, 2], P) T.append(alldata[i, 0]) F.append(alldata[i, 1]) else: label = labelpref + str(P) + r' ${}^N\!/{}_{mm^2}$' cidx = np.where(pressures == P)[0] - 1 axis.plot(T, F, line, color=colors[cidx], label=label) T = [alldata[i, 0]] F = [alldata[i, 1]] P = alldata[i, 2] label = labelpref + str(P) + r' ${}^N\!/{}_{mm^2}$' cidx = np.where(pressures == P)[0] - 1 axis.plot(T, F, line, color=colors[cidx], label=label) elif test == 'bndU': axis.plot(alldata[:, 0], alldata[:, 1], line, label=labelpref) else: utility.print_error('Invalid test type in plot_exp_data.', True)
def cluster_properties(name): cp = dict() if name == 'bellatrix': cp['name'] = 'bellatrix' cp['np'] = 16 cp['mem'] = 32000 cp['modules'] = ''' # NOTE: a different queue is required for jobs on Bellatrix longer than 3 days. module list # module purge # module load intelmpi/5.0.1 # module load abaqus/6.14-1/intel-14.0.1 # module load python/2.7.9/intel-15.0.0 ''' elif name == 'aries': cp['name'] = 'aries' cp['np'] = 48 cp['mem'] = 192000 cp['modules'] = ''' eval `modulecmd bash purge` eval `modulecmd bash load intel/14.0.1` eval `modulecmd bash load intelmpi/4.1.3` eval `modulecmd bash load abaqus/6.14-1/intel-14.0.1` eval `modulecmd bash load python/2.7.8` ''' elif name == 'deneb': cp['name'] = 'deneb' cp['np'] = 16 cp['mem'] = 64000 cp['modules'] = ''' module list # module purge # module load intelmpi/5.0.1 # module load abaqus/6.14-1/intel-14.0.1 # module load python/2.7.9/intel-15.0.0 ''' elif name == 'deneb_himem': cp['name'] = 'deneb_himem' cp['np'] = 16 cp['mem'] = 256000 cp['modules'] = ''' module list # module purge # module load intelmpi/5.0.1 # module load abaqus/6.14-1/intel-14.0.1 # module load python/2.7.9/intel-15.0.0 ''' else: utility.print_error('Unrecognized cluster.', True) return cp
def import_dataset(datafile, data, key): # fliplr swaps the stress and strain columns. Data is now in "strain,stress" format. if not datafile.lower() == 'none': if not path.isfile(datafile): utility.print_error('File does not exist: ' + datafile, True) data[key] = np.fliplr( np.loadtxt(datafile, comments='#', delimiter=',', dtype=np.longdouble)) data[key] = np.vstack(([0.0, 0.0], data[key])) # Add a (0,0) datapoint. print ' Imported', data[key].shape[0], 'datapoints for', get_name( key), 'data.'
def initialize(self, param_file): self.param_file = param_file self.param_list = dict() utility.print_info(f'PRM read {self.param_file}') if os.path.isfile(self.param_file): self.param_list['param_file'] = self.param_file with open(self.param_file, 'r') as f: for line in f: columns = line.split() if len(columns) < 2 or '#' in columns[0]: continue self.param_list[columns[0]] = columns[1] utility.print_info(f'PRM key = {columns[0] + ",":18} ' + f'val = {columns[1]}') utility.print_info(f'PRM initialized') self.initialized = True else: utility.print_error(f'PRM NOT initialized') self.initialized = False
def add_server(session, url, ext_dir, debug=False): server_name, cpu_id, disk_info, mac_addr, server_type, ip_addr = get_server_info( ext_dir, debug) user_files = { "csrfmiddlewaretoken": (None, get_csrf_token(session, url)), "name": (None, server_name), "cpu": (None, cpu_id), "disk": (None, disk_info), "mac": (None, mac_addr), "service_type": (None, server_type), "ip": (None, ip_addr), "_save": (None, "Save") } r = session.post(url, files=user_files) ret = search_element(r, '<ul class="errorlist"><li>') if (ret == True and debug): print_error('Same MAC address with other server') return False return True
def run_ACT(act,test,dist_to_force,geomcmd,i): PROCS = 8 try: U.run_cmd_screen(geomcmd) # Create the test. except Exception: U.print_error('Failed to create geometry! Non-physical dimensions?',False) return dict() results = dict() RT.run_abq('test_geom-'+act+test+'.inp','.',PROCS,str(i)) # Run the test. if RT.run_post('test_geom-'+act+test+'.inp','.',str(i)): # Postprocess the test. try: data = np.loadtxt(path.join('test_geom-'+act+test+'-'+str(i),'data.rpt'),skiprows=4) except Exception: U.print_error('Failed to load data.rpt file, skipping dataset.',False) return dict() if len(data.shape)==1: return dict() if act=='lin' and test=='U': data = data[:,[1,4]] # Pressure, Z-displacement. data[:,1] = -1.0*data[:,1] elif act=='bnd' and test=='U': L = data[0,-1] - data[0,-2] # Initial length of the actuator. angles = np.degrees(np.arctan(-data[:,3]/(L-data[:,4]))) angles[angels<0.0] = angles[angles<0.0] + 180 data = data[:,[1,2]] data[:,1] = angles elif act=='lin' and test=='F': data= data[:,[1,4]] # Pressure, Z-Force. elif act=='bnd' and test=='F': # Need to calculate the force perpendicular to the plate. alpha = np.radians(dist_to_force) beta = np.radians(90 - dist_to_force) f_normal = np.abs(data[:,3]*np.cos(alpha)) + np.abs(data[:,4]*np.cos(beta)) data = data[:,[1,2]] data[:,1] = f_normal # Pressure, Normal-Force. results[act+test] = data try: # strains are time (same indices as pressure), nominal strain. strains = np.loadtxt(path.join('test_geom-'+act+test+'-'+str(i),'data-strain.csv'),delimiter=',') strains[:,0] = data[:,0] results[act+test+'--strain'] = strains except: pass return results
def run_post(inp,outdir,descr): wd = path.join(outdir,path.splitext(path.basename(inp))[0]) if descr!="": wd+='-'+descr print '\n' print '--------------------------------------------------------------------------------' print '-- RUNNING POSTPROCESSOR:',path.join(wd,'job.odb') print '--------------------------------------------------------------------------------' # Run the extraction. rootdir = os.getcwd() try: os.chdir(wd) except Exception: utility.print_error(sys.exc_info()[0],False) return 0 tstart = time.time() script = utility.find_file('python/abq_extract_data.py') cmd=[ABAQUS,'cae','noGUI='+script,'--','job.odb','data.rpt'] try: utility.run_cmd_screen(cmd) with open('data.tmp','w') as of, open('data.rpt','r') as f: for line in f: line = line.rstrip() # Remove newline/carriage-return. if line.find('NoValue') < 0: of.write(line+'\n') shutil.move('data.tmp','data.rpt') except Exception: utility.print_error(sys.exc_info()[0],False) print 'TIME ELAPSED: ',utility.time_elapsed(tstart) os.chdir(rootdir) return 0 try: import create_result_plots, numpy from matplotlib import pyplot pyplot.rc('mathtext',default='regular') # Don't use italics for mathmode. fig,ax = pyplot.subplots() create_result_plots.plot_fem_data(ax,'data.rpt') lgd = ax.legend(loc='best',frameon=False,framealpha=0) pyplot.savefig('plot.png',bbox_extra_artists=(lgd,), bbox_inches='tight') pyplot.close() if path.exists('data-energy.rpt'): fig,ax = pyplot.subplots() create_result_plots.plot_fem_energy(ax,'data-energy.rpt') lgd = ax.legend(loc='best',frameon=False,framealpha=0) pyplot.savefig('plot-energy.png',bbox_extra_artists=(lgd,), bbox_inches='tight') pyplot.close() if path.exists('data-strain.csv'): fig,ax = pyplot.subplots() data = numpy.loadtxt('data-strain.csv',delimiter=',') ax.plot(data[:,0],data[:,1],'o-',label='Nominal Strain') ax.set_xlabel('Time (meaningless units)') ax.set_ylabel('Nominal Strain') ax.grid() pyplot.savefig('plot-strain.png', bbox_inches='tight') pyplot.close() except Exception: utility.print_error('Failed to create result plots.',False) print 'TIME ELAPSED: ',utility.time_elapsed(tstart) os.chdir(rootdir) return 1
def crop_data(data, NCC): if NCC < 0: return data, [] # Reduce noise by only using 1 point of out PPS. sign = 0 PPS = 2 for i in range(10): cycles = [] samples = range(0, data.shape[0], PPS) strain_diff = np.sign(np.diff(data[samples, 0])) for i, s in enumerate(strain_diff): if s != sign: sign = s cycles.append(PPS * i) cycles.append(data.shape[0]) NC = (len(cycles) - 1.0) / 2.0 print 'Found cycles: ', NC if NC > 20 or NC != int(NC): print '\tWARNING: Failed to find cycles with PPS =', PPS PPS = PPS + 1 else: break else: utility.print_error('Failed to find cycles.', False) print '\n' return data, [] print 'Number of cycles cropped: ', NC - NCC for i in range(len(cycles) - 1, 1, -2): if i == 2.0 * (NC - NCC): indices = range(0, cycles[i] + PPS) data = np.delete(data, indices, axis=0) break else: indices = range(cycles[i - 1] - PPS, cycles[i] + PPS) data = np.delete(data, indices, axis=0) return data, cycles
def create_and_exec_install_shell(ext_object): try: cmd = '#!/bin/bash\nsudo apt-get update\n' for package_name in ext_object['install_packages']: cmd += 'sudo apt-get install -y %s\n' % package_name install_shell = open('./install.sh', 'w+') cmd += '\n' install_shell.write(cmd) install_shell.close() ret = call('sudo chmod a+x install.sh', shell=True) if (ret != 0): exit_with_msg('chmod for install') ret = call('./install.sh', shell=True) if (ret != 0): exit_with_msg('exec install.sh') ret = call('sudo rm -f install.sh', shell=True) if (ret != 0): exit_with_msg('rm install.sh') except KeyboardInterrupt: print_info('Keyboard interrupt by user - when install shell') sys.exit(1) except IOError: print_error('IO Error - when install shell') sys.exit(1)
def plot_fem_data(axis,rpt,test='unknown',color='',labelpref='',fulllabel='',dist_to_force=0): # Load the file. try: data = np.loadtxt(rpt,skiprows=3) except: try: data = np.loadtxt(rpt,skiprows=4) except: utility.print_error('Problem reading .rpt file: '+rpt,False) return if len(data.shape)==1: print '\tNot enough datapoints, skipping file.' return # Get the initial length of the actuator. L = data[0,-1] - data[0,-2] if test=='unknown': # Columns are: X (time), Pressure, Fx, Fy, Fz, Zmin, Zmax # or maybe: X (time), Pressure, Ux, Uy, Uz, Zmin, Zmax if data.shape[1]==7: labels = ('$X$','$Y$','$Z$') ylabel = 'Value - Blocked Force (N) or Displacement (mm)' title = 'Todo' # Columns are: X (time), Fz, Uz elif data.shape[1]==3: axis.set_xlabel('Displacement (mm)') axis.set_ylabel('Force (N/mm2)') axis.set_title('Displacement versus Force') axis.grid() axis.plot(data[:,2], data[:,1], label='$F_z$') return # Columns are X (time), Pressure, Ux, Uy, Uz elif data.shape[1]==5: labels = ('$X$','$Y$','$Z$') ylabel = 'Displacement (mm)' title = 'Bubble Displacement' else: utility.print_error('Didn\'t recognize data format for plotting.',False) print data return if axis.get_ylabel()=='': axis.set_ylabel(ylabel) axis.set_title(title) axis.grid() elif axis.get_ylabel()!=ylabel: utility.print_error('Multiple plot types. Plotting anyway...',False) else: if test=='linU': data[:,2] = -data[:,4] labels = ('$U_z$',) elif test=='linF': data[:,2] = data[:,4] labels = ('$F_z$',) elif test=='bndU': # Calculate the "bending angle". Assumes positive z-displacement is a shorter actuator. data[:,2] = np.degrees(np.arctan(-data[:,3]/(L-data[:,4]))) data[data[:,2]<0.0,2] = data[data[:,2]<0.0,2] + 180 labels = ('angle',) elif test=='bndF': alpha = np.radians(dist_to_force) beta = np.radians(90 - dist_to_force) f_normal = np.abs(data[:,3]*np.cos(alpha)) + np.abs(data[:,4]*np.cos(beta)) data[:,2] = f_normal # Pressure, Normal-Force. labels = ('$F_y$',) elif test=='bubU': data[:,2] = data[:,4] labels = ('$U_z$',) else: utility.print_error('Invalid test type in plot_fem_data.',True) # Set the plot properties and create the plot. # axis.set_xlabel(r'Internal Pressure $\left({}^N\!/{}_{mm^2}\right)$') data[:,1] = data[:,1] * 1000.0 axis.set_xlabel('Internal Pressure (kPa)') linetypes = ['o-','s-','^-'] for i in range(len(labels)): if not fulllabel: if labelpref=='': label = labels[i] else: label = labelpref + ' - ' + labels[i] else: label = fulllabel if color=='': axis.plot(data[:,1], data[:,2+i], linetypes[i], label=label) else: axis.plot(data[:,1], data[:,2+i], linetypes[i], color=color, label=label, markersize=3, markeredgecolor=color)
def run_slurm(inp, cp, time, outdir, nn, np, descr): outdir = path.abspath(outdir) dirname = path.splitext(path.basename(inp))[0] if descr != "": dirname += '-' + descr wd = path.join(outdir, dirname) if wd.startswith('/home'): print 'ERROR: /home is readonly during execution, use /scratch.' return 0, '' if path.exists(wd): shutil.rmtree(wd) if not inp.endswith('.inp'): utility.print_error('Input file must be a .inp Abaqus run file.', False) return 0, '' # Prepare the directories. os.makedirs(wd) shutil.copyfile(inp, path.join(wd, 'job.inp')) create_env(np, wd, nn) # Create the submission script. extfile = path.abspath(utility.find_file('python/abq_extract_data.py')) jobfile = path.join(wd, dirname + '.job') runcmd = ABAQUS + ' job=job input=job.inp interactive' postcmd = ABAQUS + ' cae noGUI=' + extfile + ' -- job.odb data.rpt' # TODO - need ability to set email address here. with open(jobfile, 'w') as f: f.write('''#!/bin/bash # mem directive is per node. #SBATCH --nodes ''' + str(nn) + ''' #SBATCH --cpus-per-task 1 #SBATCH --ntasks-per-node ''' + str(np) + ''' #SBATCH --mem ''' + str(cp['mem'] * np / cp['np']) + ''' #SBATCH --time ''' + time + ''' #SBATCH --workdir ''' + wd + ''' #SBATCH --mail-type=END #SBATCH --mail-type=FAIL #SBATCH [email protected] #SBATCH --share ''') f.write(cp['modules']) f.write( '''echo '**********************************************************************' echo 'Starting execution at' `date` echo 'Job script:' $0 ''') if nn != 1: f.write(''' scontrol show hostname $SLURM_JOB_NODELIST | paste -d -s > hostlist HLIST="[" for i in $(cat hostlist) do HLIST="$HLIST['$i',''' + str(np) + ''']," done HLIST=`echo $HLIST | sed -e "s/,$/]/"` echo "mp_host_list=$HLIST" >> abaqus_v6.env echo "Hostlist: $HLIST" ''') f.write( '''echo '**********************************************************************' ''' + runcmd + ''' sleep 5 echo echo '**********************************************************************' echo 'Running postprocessor.' echo '**********************************************************************' ''' + postcmd + ''' echo echo 'Finished execution at' `date` echo " ****** END OF JOB ******"''') return 1, jobfile
def plot_exp_data(axis, fname, test, color='', labelpref='', fulllabel=''): # Load the file. try: if fname.endswith('.csv'): alldata = np.loadtxt(fname,delimiter=',') elif fname.endswith('.txt'): alldata = np.loadtxt(fname) except: utility.print_error('Problem reading experimental data file: '+fname,True) if test=='linU': try: T = path.splitext(fname)[0] T = float(T[T.rindex('-t')+2:]) npress = alldata.shape[1]/2 data = np.zeros([npress,2]) for i in range(npress): # Note that we skip the first row, since it contains the pressure data. row = 0 col = 2*i for r in range(alldata.shape[0]): if alldata[r,col]>=T: break row = r data[i,:] = alldata[0,col] data[i,1] = alldata[row,col+1] descr = '$U_z(t='+str(alldata[row,col])+'s)$' except Exception: utility.print_error('Problem determining cutoff time from filename.\n' 'Filename should be in this format: <fname>-t<time>.csv',False) print 'Assuming no cutoff, printing all data.' data = np.zeros([alldata.shape[0],2]) data[:,0] = alldata[:,0] data[:,1] = alldata[:,1] descr = '$U_z$' line = 'o--' elif test=='linF' or test=='bndF': # Extract the unique pressures into a column of an array. pressures = np.unique(alldata[:,2]) data = np.zeros((pressures.shape[0],3)) data[:,0] = pressures # This extracts the last experimental datapoint at each pressure. for i in range(alldata.shape[0]): P = alldata[i,2] idx = np.where(pressures==P) data[idx,1] = alldata[i,1] data[idx,2] = alldata[i,0] # Legend label includes the time of the data sampled. # We take the average time, not including for the 0 pressure. tavg = np.around(np.average(data[1:,2]),2) descr = '$F_z(t='+str(tavg)+'s)$' line = 'o--' elif test=='bndU': data = np.zeros([alldata.shape[0],2]) data[:,0] = alldata[:,0] data[:,1] = alldata[:,1] descr = 'angle' line = '--' elif test=='bubU': data = alldata descr = '$U_z$' line = '--' else: utility.print_error('Invalid test type in plot_exp_data.',True) # Set the plot properties and create the plot. # axis.set_xlabel(r'Internal Pressure $\left({}^N\!/{}_{mm^2}\right)$') data[:,0] = data[:,0] * 1000.0 axis.set_xlabel('Internal Pressure (kPa)') if not fulllabel: if labelpref=='': label = labels[i] else: label = labelpref + ' - ' + descr else: label = fulllabel if color=='': axis.plot(data[:,0], data[:,1], line, label=label) else: axis.plot(data[:,0], data[:,1], line, color=color, label=label)
parser.add_argument('img',help='Output image to create.') parser.add_argument('data',nargs='+',help='Data file(s) to plot. RPT files are assumed to be Abaqus FEM output, CSV or TXT files are assumed to be experimental data.') parser.add_argument('--sort',action='store_true',help='Numerically sort inputs from smallest to largest.') parser.add_argument('--sort_reverse',action='store_true',help='Numerically sort inputs from largest to smallest.') parser.add_argument('--xlim',nargs=2,type=float,metavar=('MIN','MAX'),help='Optional min and max for x-axis.') parser.add_argument('--ylim',nargs=2,type=float,metavar=('MIN','MAX'),help='Optional min and max for y-axis.') parser.add_argument('--title',help='Optional title for plot.') parser.add_argument("--paper",action='store_true',help="Create plots designed for the paper, rather than for general use.") parser.add_argument("--labels",nargs='+',help="Labels for lines (all FEM labels first, then experimental labels).") parser.add_argument('--dist_to_force',type=float,default=0.0,help='Distance (or angle for bending actuators) to the blocked force plate in blocked-force tests (default 0.0).') args = parser.parse_args() # pyplot.rc('savefig',dpi=300) # pyplot.rc('font',size=8) pyplot.rc('mathtext',default='regular') # Don't use italics for mathmode. if args.labels and len(args.labels)<len(args.data): utility.print_error('Number of given labels must be the same as the number of given files.',True) # Separate the data files into FEM and EXP. femdata = [] expdata = [] for df in args.data: if df.endswith('.rpt'): femdata.append(df) else: expdata.append(df) # Try to sort the data. if args.sort or args.sort_reverse: try: from natsort import natsort femdata = natsort(femdata) expdata = natsort(expdata)
def get_function(model, t): if t == 'u': return model.stressU if t == 'b': return model.stressB if t == 'p': return model.stressP utility.print_error('Invalid type in get_function: ' + t, True)
if args.cmd == 'bubble': acg_args = [ cae_file, args.test, args.mesh_size, args.press, args.time, str(args.diameter), str(args.thickness), str(args.inlet), mat_file ] cmd = [ABAQUS, 'cae', 'noGUI=' + acg_file, '--'] + acg_args #------------------------------------------------------------------------------------ # Attempt to run Abaqus to create the geometry. #------------------------------------------------------------------------------------ try: utility.run_cmd_screen(cmd) except Exception: utility.print_error(sys.exc_info()[0], False) print 'Check above to see if Abaqus printed an error. Otherwise, check the Abaqus log files.' print 'Tried to run command:' print ' '.join(cmd) print 'In directory:', caedir print else: # Cleanup. os.remove('abaqus.rpy') os.remove(path.splitext(cae_file)[0] + '.jnl') # Read .inp file to determine number of elements and nodes. with open(inp_file + '.tmp', 'w') as of, open(inp_file, 'r') as f: countN = False countE = False nn = 0 ne = 0
parser_ACT.add_argument('--width_constraints',nargs=2,type=float,default=[0,0],metavar=('MIN','MAX'), help='Optional constraints for initial width of actuator (default=no constraints).') parser_ACT.add_argument('--max_strain',type=float,help='Maximum strain (default=none).') # TODO - add option for random starting point. args = parser.parse_args() np.set_printoptions(precision=4,linewidth=130,suppress=True) # Disable scientific notation for small numbers. pyplot.rc('savefig',dpi=300) pyplot.rc('font',size=8) pyplot.rc('mathtext',default='regular') # Don't use italics for mathmode. #-------------------------------------------------------------------------------- # Read in the given datasets. #-------------------------------------------------------------------------------- if len(args.test)!=len(args.fittingdata): U.print_error('Number of fittingdata files must be equal to the number of tests.',True) print '--------------------------------------------------------------------' print ' Importing data file(s)...' data = dict() pressures = [] for i,fname in enumerate(args.fittingdata): T = args.actuator + args.test[i] data[T] = np.loadtxt(fname,comments='#',delimiter=',') pressures.append(max(data[T][:,0])) print ' Imported',data[T].shape[0],'points from',fname,'for test type:',T if args.max_strain: data['strain'] = np.array([[0.0,0.0],[min(pressures),args.max_strain]]) #-------------------------------------------------------------------------------- # Prepare variables. #--------------------------------------------------------------------------------
help="Create eps plots instead of png.") args = parser.parse_args() ext = '.png' if not args.eps else '.eps' # 'suppress' disables scientific notation for small numbers. np.set_printoptions(precision=4, linewidth=130, suppress=True) np.seterr(all='raise') pyplot.rc('savefig', dpi=300) pyplot.rc('font', size=8) pyplot.rc('mathtext', default='regular') # Don't use italics for mathmode. # Error checking on the given method. min_opts = ('nelder-mead', 'powell', 'cg', 'bfgs', 'newton-cg', 'l-bfgs-b', 'tnc', 'cobyla', 'slsqp', 'dogleg', 'trust-ncg') if args.method.lower() in min_opts: method = args.method else: U.print_error('Invalid minimization method: ' + args.method, False) print 'Options are:', min_opts exit(1) # Find the model module. model = MU.get_model(args.model) if not args.volumetric.lower() == 'none': U.print_error('Volumetric fitting is unsupported.', True) # Read in the given datasets. data = dict() print '--------------------------------------------------------------------' print ' Importing datasets...' MU.import_dataset(args.uniaxial, data, 'u') MU.import_dataset(args.biaxial, data, 'b') MU.import_dataset(args.planar, data, 'p')
def calc_fit(OF,cmd,expdata,init_nc,interpBOOL,optfunc,*popt): fig,axis = pyplot.subplots(1,1) popt_display = np.abs(list(popt)) popt_display[0] = calc_nc(popt[0],init_nc) print '\n********************************************************************' print '** Testing with parameters: ',popt_display print '********************************************************************' # Get the simulation results. if not hasattr(calc_fit, "iter"): calc_fit.iter=0 simdata = optfunc((calc_fit.iter,)+popt) if len(simdata)==0: print '\n********************************************************************' print ' Abaqus failed, we return an average error of 1000.0' print '********************************************************************' calc_fit.iter = calc_fit.iter + 1 pyplot.close() return 1000.0 # Loop over multiple simulation results, if necessary. NP = 50 errs = dict() cm = pyplot.get_cmap('jet') colors = [cm(float(i)/(2*len(simdata))) for i in range(2*len(simdata))] cidx = 0 for T,sdata in simdata.iteritems(): if T in expdata: edata=expdata[T] elif T.endswith('--strain'): if 'strain' in expdata: edata=expdata['strain'] else: continue else: U.print_error('Failed to find comparison data for '+T,True) # Plot the simulation data. axis.plot(1000.0*sdata[:,0],sdata[:,1],'o-',color=colors[cidx],label='Sim '+T) # Interpolate the simulation results to remove zigzags and evenly space the points. # This is important because otherwise we may weight solutions very heavily at one point # in one solution, and completely differently in another. u,idx = np.unique(sdata[:,0],return_index=True) try: if interpBOOL: sim_smooth = np.zeros((NP,2)) sim_smooth[:,0] = np.linspace(min(sdata[idx,0]),max(sdata[idx,0]),NP) # xvals = 1.0 - (np.logspace(0,np.log10(NP+1.0),NP,endpoint=True)-1.0)/(NP+1.0) # sim_smooth[:,0] = min(sdata[idx,0]) + (max(sdata[idx,0])-min(sdata[idx,0]))*xvals else: sim_smooth = np.zeros(edata.shape) sim_smooth[:,0] = edata[:,0] dataF = interp.UnivariateSpline(sdata[idx,0],sdata[idx,1],k=3,s=0) sim_smooth[:,1] = dataF(sim_smooth[:,0]) # Remove any extrapolations, replace with the max calculated value. sim_smooth[sim_smooth[:,0]>max(sdata[:,0]),1] = max(sdata[:,1]) axis.plot(1000.0*sim_smooth[:,0],sim_smooth[:,1],'.--',color=colors[cidx],label='Sim '+T+' (Smoothed)') except: print '** Failed to smooth simulation data. Proceding with untouched data.' sim_smooth = 1.0*sdata[idx,:] interpBOOL = True # Interpolate the experimental results to find comparable data. axis.plot(1000.0*edata[:,0],edata[:,1],'-',color=colors[cidx+1],label='Exp '+T) if interpBOOL: try: dataF = interp.UnivariateSpline(edata[:,0], edata[:,1],k=3,s=0) exp_smooth = np.zeros(sim_smooth.shape) exp_smooth[:,0] = sim_smooth[:,0] exp_smooth[:,1] = dataF(exp_smooth[:,0]) except: U.print_error('Failed to fit a spline to experimental data, consider using the ' '--no_interpolate option or adding more datapoints.',True) else: exp_smooth = 1.0*edata axis.plot(1000.0*exp_smooth[:,0],exp_smooth[:,1],'.--',color=colors[cidx+1],label='Exp '+T+' (Smoothed)') # Make the comparison. # Try to handle a case where Abaqus failed early, but we have partial results. if max(sdata[:,0])<0.666*max(edata[:,0]): errs[T] = 1000.0 - 1000.0*max(sdata[:,0])/max(edata[:,0]) print '\n********************************************************************' print ' Abaqus only reached',max(sdata[:,0]),' (out of '+str(max(edata[:,0]))+')!' print '********************************************************************' else: # For errors on max strain, no penalty for being too low. if T.endswith('--strain'): if max(exp_smooth[:,1])>=max(sim_smooth[:,1]): errs[T]=0.0 else: errs[T] = 1.0 - CH.rsquared(exp_smooth,sim_smooth) else: errs[T] = 1.0 - CH.rsquared(exp_smooth,sim_smooth) cidx = cidx+2 # Record to file. if calc_fit.iter==0: OF.write('# Each row shows the iteration #, the '+str(len(popt))+' parameters,\n') OF.write('# and then the '+str(len(errs.keys()))+' errors: '+str(errs.keys())+'\n') record_string = str(calc_fit.iter)+',' for p in popt_display: record_string = record_string + str(p) + ',' for err in errs.values(): record_string = record_string + str(err) + ',' OF.write(record_string[:-1]+'\n') # Plot settings. if cmd=='act': axis.set_xlabel('Internal Pressure (kPa)') if len(simdata)>1: axis.set_ylabel('Displacement (mm) or Force (N)') else: if 'linU' in simdata or 'bndU' in simdata: axis.set_ylabel('Displacement (mm)') elif 'linF' in simdata or 'bndF' in simdata: axis.set_ylabel('Force (N)') axis.grid() # Plot with the same axis every time. if not hasattr(calc_fit, "xlim"): calc_fit.xlim = axis.get_xlim() calc_fit.ylim = axis.get_ylim() axis.set_xlim(calc_fit.xlim) axis.set_ylim(calc_fit.ylim) axis.set_aspect(np.diff(calc_fit.xlim)/np.diff(calc_fit.ylim)) # Square axis. err_str = ', '.join("{:}:{:g}".format(key,val) for (key,val) in errs.iteritems()) title = axis.set_title('\n'.join(textwrap.wrap(str(popt_display),100))+'\nitr='+str(calc_fit.iter)+'\nerrs=['+err_str+']\nerr_sum='+str(sum(errs.values()))) title.set_y(1.05) fig.subplots_adjust(top=0.8) L = axis.legend(loc='best',frameon=False,framealpha=0) for legobj in L.legendHandles: legobj.set_linewidth(2.0) pyplot.tight_layout() pyplot.savefig('results--'+str(calc_fit.iter)+'.png') pyplot.savefig('results--latest.png') pyplot.close() print '\n********************************************************************' print ' Calculated sum-of-squares error:',errs,'=',sum(errs.values()) print '********************************************************************' calc_fit.iter = calc_fit.iter + 1 return sum(errs.values())
ax1[1].set_color_cycle(colors) ax2[0].set_color_cycle(colors) ax2[1].set_color_cycle(colors) # Iterate over datafiles. for datafile in datafiles: # Read in the given dataset. print '--------------------------------------------------------------------' print ' Loading datafile', datafile print ' (assuming column0=time, column1=length, column2=force, additional columns ignored)' print '--------------------------------------------------------------------' try: dataO = np.loadtxt(datafile, usecols=(0, 1, 2), dtype=np.longdouble) except: utility.print_error('Failed to read file.', False) print '\n' continue print 'Number of points imported:', dataO.shape[0] fname = path.splitext(datafile) data = np.zeros(dataO.shape) data[:, 0] = dataO[:, 0] # Time (s). data[:, 1] = dataO[:, 1] # Total length (mm). data[:, 2] = dataO[:, 2] # Force (N). moduli = np.zeros(data.shape) moduli[:, 0] = data[:, 0] # Calculate the moduli. data, moduli = calc_moduli(data, moduli, args.planar, args.area, args.nu) # Break up the time into step-time.
comments='#', delimiter=',', dtype=np.longdouble) print ' Imported', data.shape[0], 'datapoints.' # TODO - smooth dataset? # Prep variables. matfile = path.abspath(args.matfile) max_strain = max(data[:, 1]) A = float(args.dims[0]) * float(args.dims[1]) L = float(args.dims[2]) # Divided by two later, in abq_hysttest.py time = L * max_strain / args.rate # Change directory. if path.exists(args.dirname): U.print_error('Output directory exists.', True) os.makedirs(args.dirname) rootdir = os.getcwd() os.chdir(args.dirname) script = U.find_file('python/abq_hysttest.py') # Calculate optimal parameters. print '---------------------------------------------------------' print ' Calculating parameters...' cmd0 = [ 'abaqus', 'cae', 'noGUI=' + script, '--', matfile, args.dims[0], args.dims[1], args.dims[2], str(max_strain), str(time) ] maxitr = 1000
def calc_params(data, descr, model, method, poisson, t, num_points, params, ext, xlim=[], ylim=[], ylimerr=[]): maxitr = 5000 # Default = 100*(len(data[t][:,0])+1) nparams = len(inspect.getargspec(model.stressU)[0]) - 1 print '---------------------------------------------------------' print ' Calculating fit to', MU.get_name(t), 'data' print ' with', num_points, 'guess(es)' print ' using the \'' + method + '\' fitting method' print '---------------------------------------------------------' S_best = -1.0e8 iname = descr + '--' + model.name() + '--' + MU.get_name(t) + ext title = model.pname() + ' fit to ' + MU.get_name(t) + ' Data' for i in range(num_points): p0 = np.longdouble(6.0 * np.random.random_sample(nparams) - 1.0) print '\tStarting point ' + str(i) + ':\t', p0 try: if len(t) == 1: mfun = MU.get_function(model, t) popt = CF.curve_fit1(mfun, data[t][:, 0], data[t][:, 1], method, p0, maxitr) elif len(t) == 2: mfun0 = MU.get_function(model, t[0]) mfun1 = MU.get_function(model, t[1]) popt = CF.curve_fit2(mfun0, data[t[0]][:, 0], data[t[0]][:, 1], mfun1, data[t[1]][:, 0], data[t[1]][:, 1], method, p0, maxitr) elif len(t) == 3: mfun0 = MU.get_function(model, t[0]) mfun1 = MU.get_function(model, t[1]) mfun2 = MU.get_function(model, t[2]) popt = CF.curve_fit3(mfun0, data[t[0]][:, 0], data[t[0]][:, 1], mfun1, data[t[1]][:, 0], data[t[1]][:, 1], mfun2, data[t[2]][:, 0], data[t[2]][:, 1], method, p0, maxitr) else: print_error('Invalid fit.', True) except Exception: print '\t\tERROR:', sys.exc_info()[1] continue # TODO - check if u*a>0 for each pair. Implement as a check function in model? # TODO - check if sum(ui*ai) = 2*shear_modulus # TODO - test Drucker stability, as in Abaqus. # TODO - always iterate towards best global residual? Not exactly what the user is asking for... S = calculate_rsquared(data, model, popt, t) print '\t\tFinal: ', popt print '\t\tLocal Rsquared: ', S if S <= S_best: continue S_best = S S_global = calculate_rsquared(data, model, popt, 'ubp') print '\t\tGlobal Rsquared:', S_global print '\t\t** New Best Result. Updating Plots **' params[t] = np.append(popt, [S_best, S_global]) # Plot. D = model.compressibility(poisson, *params[t][:-2]) create_plots( model, data, popt, S, D, iname, title + '\n' + args.uniaxial + '\n' + args.biaxial + '\n' + args.planar, xlim, ylim, ylimerr) MU.write_matfile(model, descr, t, params[t][:-2], D) if S_best != -1.0e8: print '\n\tBest-fit LRsquared:', params[t][-2] print '\tBest-fit GRsquared:', params[t][-1] else: U.print_error("No suitable fit found.", False) print '\n\n'
ax2[2].axis('off') ax1[0].set_color_cycle(colors) ax1[1].set_color_cycle(colors) ax2[0].set_color_cycle(colors) ax2[1].set_color_cycle(colors) # Iterate over datafiles. for datafile in datafiles: # Read in the given dataset. print '--------------------------------------------------------------------' print ' Loading datafile', datafile print ' (assuming column0=time, column1=length, column2=force, additional columns ignored)' print '--------------------------------------------------------------------' try: dataO = np.loadtxt(datafile, usecols=(1, 2), dtype=np.longdouble) except: utility.print_error('Failed to read file.', False) print '\n' continue print 'Number of points imported:', dataO.shape[0] fname = path.splitext(datafile) data = np.zeros(dataO.shape) data[:, 0] = dataO[:, 0] data[:, 1] = dataO[:, 1] # Calculate/determine the area over which the force is applied. if args.area: A = args.area else: try: size = fname[0].split('--')[2] dims = size.split('x') if len(dims) > 2: raise Exception('Too many dimensions.')