def orientations(url_path, orientation): """View to list different orientation axes in the material database. """ #can only handle three digit or_axis atm. url_path = url_path+'/'+orientation path = os.path.join(app.config['GRAIN_DATABASE'], url_path) #load serialized grain data with open(os.path.join(path, 'or_axis.json'), 'r') as json_file: oraxis = json.load(json_file) oraxis = oraxis['oraxis'] gb_type = request.args.get('gb_type', 'tilt') if gb_type == 'tilt': gbs = (GrainBoundary.select().where(GrainBoundary.orientation_axis==oraxis) .where(GrainBoundary.boundary_plane !=oraxis) .order_by(GrainBoundary.angle)) elif gb_type == 'twist': gbs = (GrainBoundary.select().where(GrainBoundary.orientation_axis==oraxis) .where(GrainBoundary.boundary_plane == oraxis) .order_by(GrainBoundary.angle)) else: gbs = GrainBoundary.select().where(GrainBoundary.orientation_axis==oraxis).order_by(GrainBoundary.angle) #only valid directories beginning with orientation axis will be shown. grains = [] for gb in gbs: grains.append({'gbid':gb.gbid, 'angle':round(gb.angle*180/(3.14159), 2), 'bp':deserialize_vector_int(gb.boundary_plane)}) return render_template('orientation.html', url_path=url_path, grains=grains)
def pull_minen_structs(self, material="alphaFe", or_axis="1,1,1", pots=['PotBH.xml'], gb_type='tilt'): """Grab the minimum energy structure json dictionaries for a given material, orientation_axis, and potential(s) parameter filenames. Args: material(str,optional): Material to investigate. or_axis(str,optional): Orientation axis "1,1,1". pots(list): list of potentials parameter files. gb_type(str): Options 'tilt' or 'twist'. Returns: list[:py:class:`SubGrainBoundary`]: List of :py:class:`SubGrainBoundary` :py:class:`Model` represented as dictionaries. """ from gb_models import database, GrainBoundary, SubGrainBoundary from collections import OrderedDict database.connect() pot_param = PotentialParameters() ener_per_atom = pot_param.gs_ener_per_atom() if gb_type == 'tilt': gbs = (GrainBoundary.select().where( GrainBoundary.orientation_axis == or_axis).where( GrainBoundary.boundary_plane != or_axis)) elif gb_type == 'twist': gbs = (GrainBoundary.select().where( GrainBoundary.orientation_axis == or_axis).where( GrainBoundary.boundary_plane == or_axis)) else: sys.exit("Unsupported gb_type. Options:'tilt' or 'twist'") dict_list = [] for gb in gbs.order_by(GrainBoundary.angle): pot_dict = OrderedDict({}) for potential in pots: subgbs = (gb.subgrains.select( GrainBoundary, SubGrainBoundary).where( SubGrainBoundary.potential == potential).join( GrainBoundary).order_by( SubGrainBoundary.E_gb).dicts()) subgbs = [(16.02 * (subgb['E_gb'] - float(subgb['n_at'] * ener_per_atom[potential])) / (2.0 * subgb['area']), subgb) for subgb in subgbs] subgbs.sort(key=lambda x: x[0]) try: if subgbs[0][1]['converged'] == True: pot_dict[potential] = subgbs[0][0] dict_list.append(subgbs[0][1]) except IndexError: print 'No subgbs for: ', gb.gbid, potential #print '{:.3f}'.format(180.0/np.pi*gb.angle), ' '.join(['{:.3f}'.format(x) for x in pot_dict.values()]) database.close() return dict_list
def analysis(): """This view collates data from the grain boundary database and forwards it to d3 analysis tools. """ # User chooses what orientation angle to look at via a GET argument: # This should be a separate Table. pot_param = PotentialParameters() ener_per_atom = pot_param.gs_ener_per_atom() or_axis = request.args.get('oraxisselect', default='001') gb_type = request.args.get('gbtypeselect', default='tilt') material = request.args.get('materialselect', default='alphaFe') gbdat = [] oraxis = ','.join([c for c in or_axis]) # Creates list of grain boundaries ordered by angle. for potential in ener_per_atom.keys(): # GrainBoundary Energies in J/m^{2} if gb_type == 'tilt': gbs = (GrainBoundary.select() .where(GrainBoundary.orientation_axis==oraxis) .where(GrainBoundary.boundary_plane != oraxis)) elif gb_type == 'twist': gbs = (GrainBoundary.select() .where(GrainBoundary.orientation_axis==oraxis) .where(GrainBoundary.boundary_plane == oraxis)) else: sys.exit('Invalid gb_type!') for gb in gbs.order_by(GrainBoundary.angle): subgbs = (gb.subgrains.select(GrainBoundary, SubGrainBoundary) .where(SubGrainBoundary.potential==potential) .join(GrainBoundary) .order_by(SubGrainBoundary.E_gb) .dicts()) app.logger.debug(gb.gbid) subgbs = [(16.02*(subgb['E_gb']-float(subgb['n_at']*ener_per_atom[potential]))/(2.0*subgb['area']), subgb) for subgb in subgbs] subgbs.sort(key = lambda x: x[0]) if (len(subgbs) > 0): if (subgbs[0][1]['converged'] == True and subgbs[0][0] < 3.0): gbdat.append({'param_file' : potential, 'or_axis' : ' '.join(map(str, subgbs[0][1]['orientation_axis'].split(','))), 'angle' : subgbs[0][1]['angle']*(180./(3.14159)), 'min_en' : subgbs[0][0], 'bp' : ' '.join(map(str, map(int, deserialize_vector_int(subgbs[0][1]['boundary_plane'])))), 'url' : 'http://127.0.0.1:5000/grain/alphaFe/' + ''.join(map(str, deserialize_vector_int(subgbs[0][1]['orientation_axis']))) + '/' + gb.gbid}) else: pass return render_template('analysis.html', gbdat=json.dumps(gbdat))
def list_gb(self, potential="PotBH.xml", or_axis="001", print_unconverged=True): """ :method:`list_gb` list energies, and convergence for grain boundaries for a particular potential and orientation axis. :attributes: potential: Potential used to determine energies and forces. or_axis: orientation_axis print_unconverged: If true prints the files for unconverged grainboundaries which can be resubmitted with `sub_unconv.py`. """ pot_param = PotentialParameters() ener_per_atom = pot_param.gs_ener_per_atom() #serialize orientation vector: oraxis = ','.join([c for c in or_axis]) gbs = GrainBoundary.select().where( GrainBoundary.orientation_axis == oraxis).order_by( GrainBoundary.angle) unconverged = [] for gb in gbs: print "OR axis: {or_axis}, Angle: {angle}".format( or_axis=gb.orientation_axis, angle=round(gb.angle * (180.0 / 3.14159), 2)) subgbs = (gb.subgrains.select( GrainBoundary, SubGrainBoundary).where( SubGrainBoundary.potential == potential).join( GrainBoundary).order_by(SubGrainBoundary.E_gb).dicts()) if len(subgbs) > 0: subgbs = [ (16.02 * (subgb['E_gb'] - float(subgb['n_at'] * ener_per_atom['PotBH.xml'])) / (2.0 * subgb['area']), subgb) for subgb in subgbs ] subgbs.sort(key=lambda x: x[0]) for subgb in subgbs: print "\t", subgb[1]['gbid'], subgb[0], subgb[1][ 'converged'] if not subgb[1]['converged']: unconverged.append( (subgb[1]['gbid'], subgb[1]['path'])) else: print "No Subgrains." print "{} unconverged subgrains".format(len(unconverged)) if print_unconverged: with open( 'unconv_list_{or_axis}_{pot}.txt'.format( or_axis=or_axis, pot=potential.split('.')[0]), 'w') as f: for unconv in unconverged: print >> f, unconv[1]
def calc_gap(): oraxis = '0,0,1' pot_param = PotentialParameters() ener_per_atom = pot_param.gs_ener_per_atom() selected_grains = GrainBoundary.select().where( GrainBoundary.orientation_axis == oraxis).where( GrainBoundary.boundary_plane != oraxis) f = open('./locenviron/gap_energies.dat', 'a') for gb in selected_grains.order_by(GrainBoundary.angle)[2:]: subgbs = (gb.subgrains.select( GrainBoundary, SubGrainBoundary).where(SubGrainBoundary.potential == 'PotBH.xml').join(GrainBoundary).dicts()) subgbs = [ (16.02 * (subgb['E_gb'] - float(subgb['n_at'] * ener_per_atom['PotBH.xml'])) / (2.0 * subgb['area']), subgb) for subgb in subgbs ] subgbs.sort(key=lambda x: x[0]) try: print subgbs[0][1]['path'] continue target_dir = os.path.join('./grain_boundaries', subgbs[0][1]['path']) struct_file = os.path.join(target_dir, subgbs[0][1]['gbid']) + '_traj.xyz' print struct_file ats = AtomsReader(struct_file)[-1] pot = Potential('IP GAP', param_filename='gp33b.xml') ats.set_calculator(pot) print subgbs[0][1]['n_at'], subgbs[0][1]['area'] strain_mask = [0, 0, 1, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) FORCE_TOL = 0.1 opt.run(fmax=FORCE_TOL) gap_en = ats.get_potential_energy() print gap_en print round(gb.angle * (180.0 / 3.14159), 3), round( subgbs[0][0], 3), 16.02 * (gap_en - float( subgbs[0][1]['n_at'] * ener_per_atom['gp33b.xml'])) / ( 2.0 * subgbs[0][1]['area']) print >> f, round(gb.angle * (180.0 / 3.14159), 3), round( subgbs[0][0], 3), 16.02 * (gap_en - float( subgbs[0][1]['n_at'] * ener_per_atom['gp33b.xml'])) / ( 2.0 * subgbs[0][1]['area']) ats.write('./locenviron/{}.xyz'.format(subgbs[0][1]['gbid'])) except IndexError: print '\t', round(gb.angle * (180.0 / 3.14159), 3), subgbs