def build_lattice(lattice): """Build the lattice based on the values stored in the lp dictionary attribute of supplied lattice instance. Returns ------- lattice : lattice_class lattice instance The instance of the lattice class, with the following attributes populated: lattice.xy = xy lattice.NL = NL lattice.KL = KL lattice.BL = BL lattice.PVx = PVx lattice.PVy = PVy lattice.PVxydict = PVxydict lattice.PV = PV lattice.lp['BBox'] : #vertices x 2 float array BBox is the polygon used to crop the lattice or defining the extent of the lattice; could be hexagonal, for instance. lattice.lp['LL'] : tuple of 2 floats LL are the linear extent in each dimension of the lattice. For ex: ( np.max(xy[:,0])-np.min(xy[:,0]), np.max(xy[:,1])-np.min(xy[:,1]) ) lattice.lp['LV'] = LV lattice.lp['UC'] = UC lattice.lp['lattice_exten'] : str A string specifier for the lattice built lattice.lp['slit_exten'] = slit_exten """ # Define some shortcut variables lattice_type = lattice.lp['LatticeTop'] shape = lattice.lp['shape'] NH = lattice.lp['NH'] NV = lattice.lp['NV'] lp = lattice.lp networkdir = lattice.lp['rootdir'] + 'networks/' check = lattice.lp['check'] if lattice_type == 'hexagonal': from build_hexagonal import build_hexagonal xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_hexagonal( lp) elif lattice_type == 'hexmeanfield': from build_hexagonal import build_hexmeanfield xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_hexmeanfield( lp) elif lattice_type == 'hexmeanfield3gyro': from build_hexagonal import build_hexmeanfield3gyro xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_hexmeanfield3gyro( lp) elif 'selregion' in lattice_type: # amorphregion_isocent or amorphregion_kagome_isocent, for ex # Example usage: python ./build/make_lattice.py -LT selregion_randorg_gammakick1p60_cent -spreadt 0.8 -NP 225 # python ./build/make_lattice.py -LT selregion_iscentroid -N 30 # python ./build/make_lattice.py -LT selregion_hyperuniform -N 80 from lepm.build.build_select_region import build_select_region xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_select_region( lp) elif lattice_type == 'frame1dhex': from build_hexagonal import build_frame1dhex # keep only the boundary of the lattice, eliminate the bulk xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_frame1dhex( lp) elif lattice_type == 'square': import lepm.build.build_square as bs print '\nCreating square lattice...' xy, NL, KL, BL, lattice_exten = bs.generate_square_lattice( shape, NH, NV, lp['eta'], lp['theta']) print 'lattice_exten = ', lattice_exten PVx = [] PVy = [] PVxydict = {} LL = (NH + 1, NV + 1) LVUC = 'none' UC = 'none' LV = 'none' BBox = np.array([[-LL[0] * 0.5, -LL[1] * 0.5], [LL[0] * 0.5, -LL[1] * 0.5], [LL[0] * 0.5, LL[1] * 0.5], [-LL[0] * 0.5, LL[1] * 0.5]]) elif lattice_type == 'triangular': import lepm.build.build_triangular as bt xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = bt.build_triangular_lattice( lp) elif lattice_type == 'linear': from lepm.build.build_linear_lattices import build_zigzag_lattice xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_zigzag_lattice( lp) lp['NV'] = 1 elif lattice_type == 'deformed_kagome': from lepm.build.build_kagome import generate_deformed_kagome xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = generate_deformed_kagome( lp) elif lattice_type == 'deformed_martini': from lepm.build.build_martini import build_deformed_martini xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_deformed_martini( lp) elif lattice_type == 'twisted_kagome': from lepm.build.build_kagome import build_twisted_kagome xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_twisted_kagome( lp) elif lattice_type == 'hyperuniform': from lepm.build.build_hyperuniform import build_hyperuniform xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hyperuniform( lp) elif lattice_type == 'hyperuniform_annulus': from lepm.build.build_hyperuniform import build_hyperuniform_annulus xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hyperuniform_annulus( lp) lp['shape'] = 'annulus' elif lattice_type == 'isostatic': from lepm.build.build_jammed import build_isostatic # Manually tune coordination of jammed packing (lets you tune through isostatic point) xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_isostatic( lp) elif lattice_type == 'jammed': from lepm.build.build_jammed import build_jammed xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_jammed( lp) elif lattice_type == 'triangularz': from lepm.build.build_triangular import build_triangularz xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_triangularz( lp) elif lattice_type == 'hucentroid': from lepm.build.build_hucentroid import build_hucentroid xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hucentroid( lp) elif lattice_type == 'hucentroid_annulus': from lepm.build.build_hucentroid import build_hucentroid_annulus xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_hucentroid_annulus( lp) lp['shape'] = 'annulus' elif lattice_type == 'huvoronoi': from lepm.build.build_voronoized import build_huvoronoi xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten = build_huvoronoi( lp) LVUC = 'none' LV = 'none' UC = 'none' elif lattice_type == 'kagome_hucent': from lepm.build.build_hucentroid import build_kagome_hucent xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_hucent( lp) elif lattice_type == 'kagome_hucent_annulus': from lepm.build.build_hucentroid import build_kagome_hucent_annulus xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_hucent_annulus( lp) lp['shape'] = 'annulus' elif lattice_type == 'kagome_huvor': from lepm.build.build_voronoized import build_kagome_huvor print('Loading hyperuniform to build lattice...') xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten = build_kagome_huvor( lp) LV, LVUC, UC = 'none', 'none', 'none' elif lattice_type == 'iscentroid': from lepm.build.build_iscentroid import build_iscentroid print('Loading isostatic to build lattice...') xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten = build_iscentroid( lp) elif lattice_type == 'kagome_isocent': from lepm.build.build_iscentroid import build_kagome_isocent xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten = build_kagome_isocent( lp) elif lattice_type == 'overcoordinated1': from lepm.build.build_overcoordinated import generate_overcoordinated1_lattice xy, NL, KL, BL, SBL, LV, UC, LVUC, lattice_exten = generate_overcoordinated1_lattice( NH, NV) PVxydict = {} PVx = [] PVy = [] if lp['check']: le.display_lattice_2D(xy, BL) elif lattice_type == 'circlebonds': from lepm.build.build_linear_lattices import generate_circle_lattice xy, NL, KL, BL, LV, UC, LVUC, lattice_exten = generate_circle_lattice( NH) PVxydict = {} PVx = [] PVy = [] lp['NV'] = 1 minx = np.min(xy[:, 0]) maxx = np.max(xy[:, 0]) miny = np.min(xy[:, 1]) maxy = np.max(xy[:, 1]) BBox = np.array([[minx, miny], [minx, maxy], [maxx, maxy], [maxx, miny]]) LL = (maxx - minx, maxy - miny) elif lattice_type == 'dislocatedRand': from lepm.build.build_dislocatedlattice import build_dislocated_lattice xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten = build_dislocated_lattice( lp) elif lattice_type == 'dislocated': if lp['dislocation_xy'] != 'none': dislocX = lp['dislocation_xy'].split('/')[0] dislocY = lp['dislocation_xy'].split('/')[1] dislocxy_exten = '_dislocxy_' + dislocX + '_' + dislocY pt = np.array([[float(dislocX), float(dislocY)]]) else: pt = np.array([[0., 0.]]) dislocxy_exten = '' if lp['Bvec'] == 'random': Bvecs = 'W' else: Bvecs = lp['Bvec'] xy, NL, KL, BL, lattice_exten = generate_dislocated_hexagonal_lattice( shape, NH, NV, pt, Bvecs=Bvecs, check=lp['check']) lattice_exten += dislocxy_exten PVx = [] PVy = [] PVxydict = {} LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) BBox = np.array([[np.min(xy[:, 0]), np.min(xy[:, 1])], [np.max(xy[:, 0]), np.min(xy[:, 1])], [np.max(xy[:, 0]), np.max(xy[:, 1])], [np.min(xy[:, 0]), np.max(xy[:, 1])]]) LV = 'none' UC = 'none' LVUC = 'none' elif lattice_type == 'penroserhombTri': if lp['periodicBC']: from lepm.build.build_quasicrystal import generate_periodic_penrose_rhombic xy, NL, KL, BL, PVxydict, BBox, PV, lattice_exten = generate_periodic_penrose_rhombic( lp) LL = (PV[0, 0], PV[1, 1]) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) else: from lepm.build.build_quasicrystal import generate_penrose_rhombic_lattice xy, NL, KL, BL, lattice_exten, Num_sub = generate_penrose_rhombic_lattice( shape, NH, NV, check=lp['check']) LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) BBox = blf.auto_polygon(shape, NH, NV, eps=0.00) PVx = [] PVy = [] PVxydict = {} LVUC = 'none' LV = 'none' UC = 'none' elif lattice_type == 'penroserhombTricent': from lepm.build.build_quasicrystal import generate_penrose_rhombic_centroid_lattice xy, NL, KL, BL, PVxydict, PV, LL, BBox, lattice_exten = generate_penrose_rhombic_centroid_lattice( lp) # deepcopy PVxydict to generate new pointers PVxydict = copy.deepcopy(PVxydict) if lp['periodicBC']: PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) else: PVx, PVy = [], [] # Rescale so that median bond length is unity bL = le.bond_length_list(xy, BL, NL=NL, KL=KL, PVx=PVx, PVy=PVy) scale = 1. / np.median(bL) xy *= scale PV *= scale print 'PV = ', PV BBox *= scale LL = (LL[0] * scale, LL[1] * scale) print 'after updating other things: PVxydict = ', PVxydict if lp['periodicBC']: PVx *= scale PVy *= scale PVxydict.update( (key, val * scale) for key, val in PVxydict.items()) else: PVx = [] PVy = [] LVUC = 'none' LV = 'none' UC = 'none' elif lattice_type == 'kagome_penroserhombTricent': from build.build_quasicrystal import generate_penrose_rhombic_centroid_lattice xy, NL, KL, BL, lattice_exten = generate_penrose_rhombic_centroid_lattice( shape, NH + 5, NV + 5, check=lp['check']) # Decorate lattice as kagome print('Decorating lattice as kagome...') xy, BL, PVxydict = blf.decorate_as_kagome(xy, BL) lattice_exten = 'kagome_' + lattice_exten xy, NL, KL, BL = blf.mask_with_polygon(shape, NH, NV, xy, BL, eps=0.00, check=False) # Rescale so that median bond length is unity bL = le.bond_length_list(xy, BL) xy *= 1. / np.median(bL) minx = np.min(xy[:, 0]) miny = np.min(xy[:, 1]) maxx = np.max(xy[:, 0]) maxy = np.max(xy[:, 1]) BBox = np.array([[minx, miny], [minx, maxy], [maxx, maxy], [maxx, miny]]) LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVx = [] PVy = [] PVxydict = {} LVUC = 'none' LV = 'none' UC = 'none' elif lattice_type == 'random': xx = np.random.uniform(low=-NH * 0.5 - 10, high=NH * 0.5 + 10, size=(NH + 20) * (NV + 20)) yy = np.random.uniform(low=-NV * 0.5 - 10, high=NV * 0.5 + 10, size=(NH + 20) * (NV + 20)) xy = np.dstack((xx, yy))[0] Dtri = Delaunay(xy) TRI = Dtri.vertices BL = le.Tri2BL(TRI) NL, KL = le.BL2NLandKL(BL, NN='min') # Crop to polygon (instead of trimming boundaries) # NL, KL, BL, TRI = le.delaunay_cut_unnatural_boundary(xy, NL, KL, BL, TRI, thres=lp['trimbound_thres']) shapedict = {shape: [NH, NV]} keep = blf.argcrop_lattice_to_polygon(shapedict, xy, check=check) xy, NL, KL, BL = le.remove_pts(keep, xy, BL, NN='min') lattice_exten = lattice_type + '_square_thres' + sf.float2pstr( lp['trimbound_thres']) polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) BBox = polygon LL = (np.max(BBox[:, 0]) - np.min(BBox[:, 0]), np.max(BBox[:, 1]) - np.min(BBox[:, 1])) PVx = [] PVy = [] PVxydict = {} LVUC = 'none' LV = 'none' UC = 'none' elif lattice_type == 'randomcent': from lepm.build.build_random import build_randomcent xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_randomcent( lp) elif lattice_type == 'kagome_randomcent': from lepm.build.build_random import build_kagome_randomcent xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_randomcent( lp) elif lattice_type == 'randomspreadcent': from lepm.build.build_randomspread import build_randomspreadcent xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_randomspreadcent( lp) elif lattice_type == 'kagome_randomspread': from lepm.build.build_randomspread import build_kagome_randomspread xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_kagome_randomspread( lp) elif 'randorg_gammakick' in lattice_type and 'kaghi' not in lattice_type: # lattice_type is like 'randorg_gamma0p20_cent' and uses Hexner pointsets # NH is width, NV is height, NP_load is total number of points. This is different than other conventions. from build_randorg_gamma import build_randorg_gamma_spread xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_randorg_gamma_spread( lp) elif 'randorg_gamma' in lattice_type and 'kaghi' not in lattice_type: # lattice_type is like 'randorg_gamma0p20_cent' and uses Hexner pointsets from build_randorg_gamma import build_randorg_gamma_spread_hexner xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = \ build_randorg_gamma_spread_hexner(lp) elif 'random_organization' in lattice_type: try: if isinstance(lp['relax_timesteps'], str): relax_tag = lp['relax_timesteps'] else: relax_tag = '{0:02d}'.format(lp['relax_timesteps']) except: raise RuntimeError( 'lattice parameters dictionary lp needs key relax_timesteps') points = np.loadtxt( networkdir + 'random_organization_source/random_organization/random/' + 'random_kick_' + relax_tag + 'relax/out_d' + '{0:02d}'.format(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) xytmp, trash1, trash2, trash3 = blf.mask_with_polygon(shape, NH, NV, points, [], eps=0.00) xy, NL, KL, BL = le.delaunay_centroid_lattice_from_pts(xytmp, polygon='auto', check=check) polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) if check: le.display_lattice_2D(xy, BL) # Rescale so that median bond length is unity bL = le.bond_length_list(xy, BL, NL=NL, KL=KL, PVx=PVx, PVy=PVy) xy *= 1. / np.median(bL) polygon *= 1. / np.median(bL) lattice_exten = lattice_type + '_relax' + relax_tag + '_' + shape + '_d' + \ '{0:02d}'.format(int(lp['loadlattice_number'])) LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict = {} PVx = [] PVy = [] BBox = polygon elif lattice_type == 'flattenedhexagonal': from lepm.build.build_hexagonal import generate_flattened_honeycomb_lattice xy, NL, KL, BL, LVUC, LV, UC, PVxydict, PVx, PVy, lattice_exten = \ generate_flattened_honeycomb_lattice(shape, NH, NV, lp['aratio'], lp['delta'], lp['phi'], eta=0., rot=0., periodicBC=False, check=check) elif lattice_type == 'cairo': from lepm.build.build_cairo import build_cairo xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = build_cairo( lp) elif lattice_type == 'kagper_hucent': from lepm.build.build_hucentroid import build_kagper_hucent xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagper_hucent( lp) elif lattice_type == 'hex_kagframe': from lepm.build.build_kagcentframe import build_hex_kagframe # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hexagonal lattice xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hex_kagframe( lp) elif lattice_type == 'hex_kagcframe': from lepm.build.build_kagcentframe import build_hex_kagcframe # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hexagonal lattice # as circlular annulus xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hex_kagcframe( lp) elif lattice_type in ['hucent_kagframe', 'hucent_kagcframe']: from lepm.build.build_kagcentframe import build_hucent_kagframe # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hucentroid decoration xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hucent_kagframe( lp) elif lattice_type == 'kaghu_centframe': from lepm.build.build_kagcentframe import build_kaghu_centframe # Use lp['alph'] to determine the beginning of the centroid frame, surrounding kagomized decoration xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kaghu_centframe( lp) elif lattice_type in ['isocent_kagframe', 'isocent_kagcframe']: from lepm.build.build_kagcentframe import build_isocent_kagframe # Use lp['alph'] to determine the beginning of the kagomized frame, surrounding hucentroid decoration xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_isocent_kagframe( lp) elif lattice_type == 'kagsplit_hex': from lepm.build.build_kagome import build_kagsplit_hex # Use lp['alph'] to determine what fraction (on the right) is kagomized xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagsplit_hex( lp) elif lattice_type == 'kagper_hex': from lepm.build.build_kagome import build_kagper_hex # Use lp['alph'] to determine what fraction of the radius/width (in the center) is kagomized xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagper_hex( lp) elif lattice_type == 'hex_kagperframe': from lepm.build.build_kagcentframe import build_hex_kagperframe # Use lp['alph'] to determine what fraction of the radius/width (in the center) is partially kagomized xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_hex_kagperframe( lp) elif lattice_type == 'kagome': from lepm.build.build_kagome import build_kagome # lets you make a square kagome xy, NL, KL, BL, PVx, PVy, PVxydict, PV, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagome( lp) elif 'uofc' in lattice_type: from lepm.build.build_kagcent_words import build_uofc # ['uofc_hucent', 'uofc_kaglow_hucent', 'uofc_kaghi_hucent', 'uofc_kaglow_isocent']: xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_uofc( lp) elif 'chicago' in lattice_type: from lepm.build.build_kagcent_words import build_chicago xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_chicago( lp) elif 'chern' in lattice_type: from lepm.build.build_kagcent_words import build_kagcentchern xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentchern( lp) elif 'csmf' in lattice_type: from lepm.build.build_kagcent_words import build_kagcentcsmf xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentcsmf( lp) elif 'thanks' in lattice_type: # example: # python ./build/make_lattice.py -LT kaghi_isocent_thanks -skip_gyroDOS -NH 300 -NV 70 -thres 5.5 -skip_polygons from lepm.build.build_kagcent_words import build_kagcentthanks xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentthanks( lp) elif 'curvys' in lattice_type: # for lattice_type in ['kaghi_isocent_curvys', 'kaglow_isocent_curvys', # 'kaghi_hucent_curvys', 'kaglow_hucent_curvys', kaghi_randorg_gammakick1p60_cent_curvys', # 'kaghi_randorg_gammakick0p50_cent_curvys', ... ] # example usage: # python ./build/make_lattice.py -LT kaghi_isocent_curvys -NH 100 -NV 70 -thres 5.5 -skip_polygons -skip_gyroDOS from lepm.build.build_kagcent_words import build_kagcentcurvys xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagcentcurvys( lp) elif 'hexannulus' in lattice_type: from lepm.build.build_conformal import build_hexannulus xy, NL, KL, BL, lattice_exten, lp = build_hexannulus(lp) LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict = {} PVx = [] PVy = [] UC = np.array([0, 0]) LV = 'none' LVUC = 'none' minx = np.min(xy[:, 0]) miny = np.min(xy[:, 1]) maxx = np.max(xy[:, 0]) maxy = np.max(xy[:, 1]) BBox = np.array([[minx, miny], [minx, maxy], [maxx, maxy], [maxx, miny]]) elif 'accordion' in lattice_type: # accordionhex accordiony accordionkagy # Example usage: # python ./build/make_lattice.py -LT accordionkag -alph 0.9 -intparam 2 -N 6 -skip_polygons -skip_gyroDOS # nzag controlled by lp['intparam'], and the rotation of the kagome element is controlled by lp['alph'] if lattice_type == 'accordionhex': from lepm.build.build_hexagonal import build_accordionhex xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp, xyvx = build_accordionhex( lp) elif lattice_type == 'accordionkag': from lepm.build.build_kagome import build_accordionkag xy, NL, KL, BL, PVx, PVy, PVxydict, PV, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_accordionkag( lp) elif lattice_type == 'accordionkag_hucent': from lepm.build.build_hucentroid import build_accordionkag_hucent xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = \ build_accordionkag_hucent(lp) elif lattice_type == 'accordionkag_isocent': from lepm.build.build_iscentroid import build_accordionkag_isocent xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten = \ build_accordionkag_isocent(lp) elif 'spindle' in lattice_type: if lattice_type == 'spindle': from lepm.build.build_spindle import build_spindle xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_spindle( lp) elif lattice_type == 'stackedrhombic': from lepm.build.build_rhombic import build_stacked_rhombic xy, NL, KL, BL, PVxydict, PVx, PVy, PV, LL, LVUC, LV, UC, BBox, lattice_exten = build_stacked_rhombic( lp) elif 'junction' in lattice_type: # accordionhex accordiony accordionkagy if lattice_type == 'hexjunction': from lepm.build.build_hexagonal import build_hexjunction xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp, xyvx = build_hexjunction( lp) elif lattice_type == 'kagjunction': from lepm.build.build_kagome import build_kagjunction xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp = build_kagjunction( lp) ########### # For reference: this is how to change z # le.cut_bonds_z(BL,lp['target_z']) # ##cut N bonds for z # N2cut = int(round((z_start-target_z)*len(BL)/z_start)) # allrows = range(len(BL)) # inds = random.sample(allrows, N2cut) # keep = np.setdiff1d(allrows,inds) # bnd_z = BL[keep] # Cut slit if lp['make_slit']: print('Cuting notch or slit...') L = max(xy[:, 0]) - min(xy[:, 0]) cutL = L * lp['cutLfrac'] x0 = -L * 0. + cutL * 0.5 - 1. # 0.25*L+0.5 BL, xy = blf.cut_slit(BL, xy, cutL + 1e-3, x0, y0=0.2) slit_exten = '_cutL' + str(cutL / L) + 'L_x0_' + str(x0) print('Rebuilding NL,KL...') NP = len(xy) if latticetop == 'deformed_kagome': nn = 4 elif lattice_type == 'linear': if NP == 1: nn = 0 else: nn = 2 else: nn = 'min' NL, KL = le.BL2NLandKL(BL, NP=NP, NN=nn) # remake BL too BL = le.NL2BL(NL, KL) else: slit_exten = '' NP = len(xy) if lp['check']: print 'make_lattice: Showing lattice before saving...' # print 'PVx = ', PVx # print 'PVy = ', PVy le.display_lattice_2D(xy, BL, PVxydict=PVxydict) ################ lattice.xy = xy lattice.NL = NL lattice.KL = KL lattice.BL = BL lattice.PVx = PVx lattice.PVy = PVy lattice.PVxydict = PVxydict lattice.LVUC = LVUC lattice.lp = lp lattice.lp['BBox'] = BBox lattice.lp['LL'] = LL lattice.lp['LV'] = LV lattice.lp['UC'] = UC lattice.lp['lattice_exten'] = lattice_exten lattice.lp['slit_exten'] = slit_exten lattice.lp['Nparticles'] = NP return lattice
def generate_deformed_martini(shape, NH, NV, x1, x2, x3, z, check=False): """creates distorted martini lattice as in Kane&Lubensky2014--> Paulose 2015 Parameters ---------- shape : string overall shape of the mesh ('square' 'circle') --> haven't built in functionality yet NH : int Number of pts along horizontal before boundary is cut NV : int Number of pts along vertical before boundary is cut x1 : float symmetrical representation of deformation (sp = xp*(a[p-1]+a[p+1])+yp*a[p]) x2 : float symmetrical representation of deformation (sp = xp*(a[p-1]+a[p+1])+yp*a[p]) x3 : float symmetrical representation of deformation (sp = xp*(a[p-1]+a[p+1])+yp*a[p]) z : float z= y1+y2+y3, symmetrical representation of deformation (sp = xp*(a[p-1]+a[p+1])+yp*a[p]) Returns ---------- xy : array of dimension nx3 Equilibrium positions of all the points for the lattice NL : array of dimension n x (max number of neighbors) Each row corresponds to a point. The entries tell the indices of the neighbors. KL : array of dimension n x (max number of neighbors) Correponds to NL matrix. 1 corresponds to a true connection while 0 signifies that there is not a connection BL : array of dimension #bonds x 2 Each row is a bond and contains indices of connected points LVUCV : NP x 4 array For each particle, gives (lattice vector, unit cell vector) coordinate position of that particle: LV1, LV2, UCV1, UCV2 lattice_type : string label, lattice type. For making output directory """ print('Setting up unit cell...') # Bravais primitive unit vecs a = np.array([[np.cos(2*np.pi*p/3.), np.sin(2*np.pi*p/3.)] for p in range(3)]) a1 = a[0] a2 = a[1] a3 = a[2] # make unit cell x = np.array([x1, x2, x3]) y = np.array([z/3. + x[np.mod(i-1, 3)]- x[np.mod(i+1, 3)] for i in [0, 1, 2]]) s = np.array([x[p]*(a[np.mod(p-1, 3)] - a[np.mod(p+1, 3)]) + y[p]*a[p] for p in range(3)]) s1 = s[0] s2 = s[1] d1 = a1/2.+s2 d2 = a2/2.-s1 d3 = a3/2. # nodes at R (from top to bottom) -- like fig 2a of KaneLubensky2014 C = np.array([d1+a2, d3+a1+a2, d2+a1, d1, d3+a1, d2-a2, d1+a3, d3, d2+a3, d1+a2+a3, d3+a2, d2]) LV = np.array([a1, 2.*a2+a1]) CU = np.arange(len(C)) tmp1 = np.ones(len(C), dtype=int) # translate by Bravais latt vecs print('Translating by Bravais lattice vectors...') inds = np.arange(len(C)) for i in np.arange(NV): print 'Building row ', i, ' of ', NV for j in np.arange(NH): if i == 0: if j == 0: # initialize R = C; LVUC = np.dstack(([0*tmp1, 0*tmp1, CU]))[0] # Rename particle 4 as particle 7 of next over in LV0, for martini trimming # LVUC[4] = np.array([1,0,7]) else: # bottom row (include point 6 in translation) R = np.vstack((R, C[0:7,:] + i*(2*a2+a1) + j*a1)) LVUCadd = np.dstack(( (i+j)*tmp1[0:7], (2*i)*tmp1[0:7], CU[0:7] ))[0] print 'LVUC = ', LVUC print 'LVUCadd = ', LVUCadd LVUC = np.vstack((LVUC, LVUCadd)) else: if j == 0: # first cell of row, include all but pt 6 R = np.vstack((R, C[inds!=6,:] + i*(2*a2+a1) + j*a1)) LVUCadd = np.dstack(( (i+j)*tmp1[inds!=6], (2*i)*tmp1[inds!=6],CU[inds!=6] ))[0] # Rename particle 4 as particle 7 of next over in LV0, for martini trimming # LVUCadd[4] = np.array([1,0,7]) LVUC = np.vstack((LVUC, LVUCadd)) else: # only points 0 through 5 included R = np.vstack((R, C[0:6,:] + i*(2*a2+a1) + j*a1)) LVUCadd = np.dstack(( (i+j)*tmp1[0:6], (2*i)*tmp1[0:6], CU[0:6] ))[0] LVUC = np.vstack((LVUC, LVUCadd)) if check: plt.plot(R[:, 0], R[:, 1], '.-') plt.show() # check for repeated points print('Checking for repeated points...') print 'len(R) =', len(R) Rcheck = le.unique_rows(R) print 'len(Rcheck) =', len(Rcheck) if len(R)-len(Rcheck) !=0: sizes = np.arange(len(xy)) plt.scatter(xy[:,0],xy[:,1],s=sizes) raise RuntimeError('Repeated points!') else: print 'No repeated points.\n' xy = R xy -= np.array([np.mean(R[1:,0]),np.mean(R[1:,1])]) ; #Triangulate print('Triangulating...') Dtri = Delaunay(xy) btri = Dtri.vertices #translate btri --> bond list BL = le.Tri2BL(btri) #remove bonds on the sides and through the hexagons print('Removing extraneous bonds from triangulation...') #calc vecs from C bonds CBL = np.array([[0,1],[1,11],[0,11],[1,2],[2,3],[3,4],[4,5],[3,5], [5,6],[6,7],[7,8],[8,9],[7,9],[9,10],[10,11]]) BL = latticevec_filter(BL,xy, C, CBL) # Now kill bonds between 1-3, 5-7, 9-11 # Also remove bonds between 4 of left kagome and 5 of right kagome BLUC = np.dstack((LVUC[BL[:,0],2], LVUC[BL[:,1],2] ))[0] print 'len(BLUC) = ', len(BLUC) print len(BL) kill1 = le.rows_matching(BLUC, np.array([1,3] )) kill2 = le.rows_matching(BLUC, np.array([5,7] )) kill3 = le.rows_matching(BLUC, np.array([9,11])) # Remove bonds between 4 of left kagome and 5 of right kagome in45a = np.in1d(BLUC[:,0], np.array([4,5])) in45b = np.in1d(BLUC[:,1], np.array([4,5])) BLLV1 = np.dstack((LVUC[BL[:,0],0], LVUC[BL[:,1],0] ))[0] kill4 = np.where(np.logical_and( np.logical_and(in45a, in45b), BLLV1[:,0] != BLLV1[:,1]))[0] # print 'BLUC = ', BLUC # print 'kill1 = ', kill1 # print 'kill2 = ', kill2 # print 'kill3 = ', kill3 keep = np.setdiff1d(np.setdiff1d(np.setdiff1d(np.setdiff1d(np.arange(len(BLUC)), kill1), kill2), kill3), kill4) # print 'keep = ', keep if check: le.display_lattice_2D(xy, BL, close=False) for ii in range(len(BL)): plt.text( np.mean([xy[BL[ii,0],0], xy[BL[ii,1],0]]), np.mean([xy[BL[ii,0],1],xy[BL[ii,1],1]]), str(BLUC[ii]) ) for ii in kill1: plt.text( np.mean([xy[BL[ii,0],0], xy[BL[ii,1],0]]), np.mean([xy[BL[ii,0],1],xy[BL[ii,1],1]]), str(BLUC[ii]), bbox=dict(facecolor='red', alpha=0.5) ) for ii in kill2: plt.text( np.mean([xy[BL[ii,0],0], xy[BL[ii,1],0]]), np.mean([xy[BL[ii,0],1],xy[BL[ii,1],1]]), str(BLUC[ii]), bbox=dict(facecolor='red', alpha=0.5) ) for ii in kill3: plt.text( np.mean([xy[BL[ii,0],0], xy[BL[ii,1],0]]), np.mean([xy[BL[ii,0],1],xy[BL[ii,1],1]]), str(BLUC[ii]), bbox=dict(facecolor='red', alpha=0.5) ) for ii in kill4: plt.text( np.mean([xy[BL[ii,0],0], xy[BL[ii,1],0]]), np.mean([xy[BL[ii,0],1],xy[BL[ii,1],1]]), str(BLUC[ii]), bbox=dict(facecolor='red', alpha=0.5) ) for ii in range(len(xy)): plt.text( xy[ii,0], xy[ii,1], str(LVUC[ii,2]) ) plt.show() BL = BL[keep,:] NL,KL = le.BL2NLandKL(BL, NN=4) lattice_exten = 'deformed_martini_' + shape + '_x1_' + '{0:.4f}'.format(x1) + '_x2_' + '{0:.4f}'.format(x2) + \ '_x3_' + '{0:.4f}'.format(x3) + '_z_' + '{0:.4f}'.format(z) UC = C return xy,NL,KL,BL,lattice_exten, LV, UC, LVUC
def generate_overcoordinated1_lattice_trip(NH, NV, ui, si, Co, CBLo): """ Moves the points of the weird lattice around to get bonds that a normal triangulation would miss. Parameters ---------- NH : int Number of pts along horizontal before boundary is cut NV : int Returns ---------- BL : array of dimension #bonds x 2 Each row is a bond and contains indices of connected points """ print('Setting up unit cell...') a0 = 2*np.array([[np.cos(n*np.pi/3+np.pi/6), np.sin(n*np.pi/3+np.pi/6), 0] for n in range(6)]) a = np.array([a0[:,0], a0[:,1]]).T A = np.array([0,0]) C = np.array([np.cos(-10*np.pi/180), np.sin(-10*np.pi/180)]) B = 0.5*np.array([np.cos(90*np.pi/180), np.sin(90*np.pi/180)]) An = A+ a Bn = B+a Cn = C+a nA = np.array([B-A, B+a[3]-A, B+a[4]-A, C-A, C+a[2]-A]) angsA = np.array([np.arctan2(nA[i,1], nA[i,0]) for i in range(len(nA))]) nB = np.array([A-B, A+a[0]-B, A+a[1]-B, C-B, C+a[1]-B]) angsB = np.array([np.arctan2(nB[i,1], nB[i,0]) for i in range(len(nB))]) nC = np.array([A-C, A+a[5]-C, B-C, B+a[4]-C]) angsC = np.array([np.arctan2(nC[i,1], nC[i,0]) for i in range(len(nC))]) aa = a.copy() a1 = aa[1] a2 = aa[2] a3 = aa[3] # nodes at R C = np.array([A, # 0 B, # 1 B+a[3], # 2 B+a[4], # 3 C, # 4 C+a[2], # 5 #A A+a[0], #6 A+a[1], #7 #C, #4 C+a[1],#8 #A A+a[5],#9 #B,#1 #B+a[4]#3 ]) CBL = np.array([[0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [1, 6], [1, 7], [1, 4], [1, 8], [3, 4], [4, 9]]) # translate by Bravais latt vecs print('Translating by Bravais lattice vectors...') print('Translating by Bravais lattice vectors...') LV = [-a2-a3, a1] inds = np.arange(len(C)) tmp0 = np.zeros(len(C), dtype='int') tmp1 = np.ones(len(C), dtype='int') for i in np.arange(NV): for j in np.arange(NH): # bottom row if i == 0: if j == 0 : R = C else: R = np.vstack((R, C + j*LV[0])) else: # vertical indices to copy over vinds = np.array([1, 2, 5, 6, 7, 8]) R = np.vstack((R, C[vinds] + j*LV[0] + i*LV[1])) print('Eliminating repeated points...') # ui = le.unique_rows_index(R) R = R[si] xy = R[ui] # Triangulate print('Triangulating...') Dtri = Delaunay(xy) btri = Dtri.vertices # translate btri --> bond list BL = le.Tri2BL(btri) # BL = latticevec_filter(BL,xy, Co, CBLo) # fig = plt.figure() # plt.triplot(xy[:,0], xy[:,1], Dtri.simplices.copy()) # plt.xlim(-10,10) # plt.ylim(-10,10) # plt.show() return BL
def generate_overcoordinated1_lattice(NH, NV, shape='square', check=False): """Generates a lattice with a made-up unit cell that is overcoordinated. Parameters ---------- NH : int Number of pts along horizontal before boundary is cut NV : int Returns ---------- xy : array of dimension nx3 Equilibrium positions of all the points for the lattice NL : array of dimension n x (max number of neighbors) Each row corresponds to a point. The entries tell the indices of the neighbors. KL : array of dimension n x (max number of neighbors) Correponds to NL matrix. 1 corresponds to a true connection while 0 signifies that there is not a connection BL : array of dimension #bonds x 2 Each row is a bond and contains indices of connected points SBL : NP x 1 int array Sublattice bond list: 0, 1, 2 for each site of the 3-particle unit cell lattice_type : string label, lattice type. For making output directory: for ex, 'overcoordinated1_square' """ print('Setting up unit cell...') a0 = 2*np.array([[np.cos(n*np.pi/3+np.pi/6), np.sin(n*np.pi/3+np.pi/6), 0] for n in range(6)]) a = np.array([a0[:, 0], a0[:, 1]]).T A = np.array([0, 0]) C = np.array([np.cos(-10*np.pi/180), np.sin(-10*np.pi/180)]) B = 1.2*np.array([np.cos(20*np.pi/180), np.sin(20*np.pi/180)]) An = A+ a Bn = B+a Cn = C+a nA = np.array([B-A, B+a[3]-A, B+a[4]-A, C-A, C+a[2]-A]) angsA = np.array([np.arctan2(nA[i, 1], nA[i, 0]) for i in range(len(nA))]) nB = np.array([A-B, A+a[0]-B, A+a[1]-B, C-B, C+a[1]-B]) angsB = np.array([np.arctan2(nB[i, 1], nB[i, 0]) for i in range(len(nB))]) nC = np.array([A-C, A+a[5]-C, B-C, B+a[4]-C]) angsC = np.array([np.arctan2(nC[i,1], nC[i,0]) for i in range(len(nC))]) aa = a.copy() print 'aa = ', aa a1 = aa[1] a2 = aa[2] a3 = aa[3] # nodes at R C = np.array([A,#0 B, # 1 B + a[3], # 2 B + a[4], # 3 C, # 4 C + a[2], # 5 A+a[0], # 6 A+a[1], # 7 C+a[1], # 8 A+a[5], # 9 ]) CU = np.arange(len(C), dtype='int') sbl = np.array([0,#0 1,#1 1,#2 1,#3 2,#4 2,#5 #A 0, #6 0, #7 #C, #4 2,#8 #A 0,#9 #B,#1 #B+a[4]#3 ]) CBL = np.array([ [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [1, 6], [1, 7], [1, 4], [1, 8], [3, 4], [4, 9] ]) # translate by Bravais latt vecs print('Translating by Bravais lattice vectors...') LV = [-a2-a3, a1] inds = np.arange(len(C)) tmp0 = np.zeros(len(C), dtype='int') tmp1 = np.ones(len(C), dtype='int') print 'sbl = ', sbl for i in np.arange(NV): for j in np.arange(NH): # bottom row if i == 0: if j == 0 : Bprev = C R = C SBL = sbl.tolist() LVUC = np.dstack((tmp0, tmp0, CU))[0] # # Check # colorvals = np.linspace(0,1,len(R)) # #plt.plot(R[:,0],R[:,1], 'k-') #,c=colorvals, cmap='spectral') # le.display_lattice_2D(R,CBL,close=False) # for ii in range(len(R)): # plt.text(R[ii,0]+0.05,R[ii,1],str(ii)) # plt.arrow(0, 0, a1[0], a1[1], head_width=0.05, head_length=0.1, fc='r', ec='r') # plt.arrow(0, 0, a2[0], a2[1], head_width=0.05, head_length=0.1, fc='b', ec='b') # plt.arrow(0, 0, a3[0], a3[1], head_width=0.05, head_length=0.1, fc='g', ec='g') # plt.show() else: R = np.vstack((R, C + j*LV[0])) SBL += sbl.tolist() # np.vstack((SBL, sbl)) LVUCadd = np.dstack((j*tmp1, tmp0, CU))[0] # print 'LVUCadd = ', LVUCadd LVUC = np.vstack((LVUC, LVUCadd)) # # Check # colorvals = np.linspace(0,1,len(R)) # plt.scatter(R[:,0],R[:,1],c=colorvals, cmap='spectral') # for ii in range(len(R)): # plt.text(R[ii,0]+0.05,R[ii,1],str(ii)) # plt.arrow(0, 0, a1[0], a1[1], head_width=0.05, head_length=0.1, fc='r', ec='r') # plt.arrow(0, 0, a2[0], a2[1], head_width=0.05, head_length=0.1, fc='b', ec='b') # plt.arrow(0, 0, a3[0], a3[1], head_width=0.05, head_length=0.1, fc='g', ec='g') # plt.pause(1) else: # vertical indices to copy over vinds = np.array([1,2,5,6,7,8]) R = np.vstack((R, C[vinds] + j*LV[0] + i*LV[1])) SBL += sbl[vinds].tolist() LVUCadd = np.dstack((j*tmp1[vinds],i*tmp1[vinds],CU[vinds] ))[0] # print 'LVUCadd = ', LVUCadd LVUC = np.vstack((LVUC,LVUCadd)) # # Check # sizevals = np.arange(len(R))+10 # colorvals = np.linspace(0,1,len(R)) # plt.scatter(R[:,0],R[:,1],s=sizevals,c=colorvals, cmap='afmhot') # for ii in range(len(R)): # plt.text(R[ii,0]+0.05,R[ii,1],str(ii)) # plt.arrow(0, 0, a1[0], a1[1], head_width=0.05, head_length=0.1, fc='r', ec='r') # plt.arrow(0, 0, a2[0], a2[1], head_width=0.05, head_length=0.1, fc='b', ec='b') # plt.arrow(0, 0, a3[0], a3[1], head_width=0.05, head_length=0.1, fc='g', ec='g') # plt.show() # if i%2 ==0: # Bprev = Bprev + a2 # else: # Bprev = Bprev + a3 SBL = np.asarray(SBL) # get rid of repeated points print('Eliminating repeated points...') ######### # check if check: plt.clf() sizevals = np.arange(len(R))+10 colorvals = np.linspace(0,1,len(R)) plt.scatter(R[:,0],R[:,1],s=sizevals,c=colorvals, cmap='afmhot', alpha=0.2) plt.show() ######### print 'R = ', R print 'shape(R) = ', np.shape(R) R, si, ui = le.args_unique_rows_threshold(R, 0.01) print 'shape(R) = ', np.shape(R) ######### # check if check: sizevals = np.arange(len(R))+50 colorvals = np.linspace(0, 1, len(R)) plt.scatter(R[:, 0], R[:, 1], s=sizevals, c=colorvals, cmap='afmhot', alpha=0.2) plt.show() ######### BL2 = generate_overcoordinated1_lattice_trip(NH, NV, ui, si, C, CBL) SBL = SBL.flatten() SBL = SBL[si] SBL = SBL[ui] # get rid of first row (0,0)a xy = le.unique_rows_threshold(R, 0.05) - np.array([np.mean(R[1:, 0]), np.mean(R[1:, 1])]) # xy = R[ui] # Triangulate print('Triangulating...') Dtri = Delaunay(xy) btri = Dtri.vertices # C = C-np.array([np.mean(R[1:,0]),np.mean(R[1:,1])]) # fig = plt.figure() # plt.triplot(xy[:,0], xy[:,1], Dtri.simplices.copy()) # plt.xlim(-10,10) # plt.ylim(-10, 10) # plt.show() # translate btri --> bond list BL = le.Tri2BL(btri) # remove bonds on the sides and through the hexagons print('Removing extraneous bonds from triangulation...') # calc vecs from C bonds BL = np.array(list(BL)+list(BL2)) BL = le.unique_rows(BL) BL = blf.latticevec_filter(BL, xy, C, CBL) NL, KL = le.BL2NLandKL(BL,NN=10) UC = C lattice_exten = 'overcoordinated1_square' return xy, NL, KL, BL, SBL, LV, UC, LVUC, lattice_exten
def generate_triangular_lattice(shape, NH, NV, periodicBC=False, eta=0., theta=0., check=False): """Generate a triangular lattice NH wide and NV tall, with sites randomized by eta and rotated by theta. Parameters ---------- shape : dictionary with string key key is overall shape of the mesh ('square' 'rectangle2x1' 'rectangle1x2' 'circle' 'hexagon'), value is radius, hexagon, sidelength, or array of closed points NH : int Number of pts along horizontal before boundary is cut NV : int Number of pts along vertical before boundary is cut periodicBC : bool make the network periodic eta : float randomization of the mesh, in units of lattice spacing theta : float overall rotation of the mesh lattice vectors in radians check : bool whether to view results at each step Returns ---------- xy : array of dimension nx3 Equilibrium positions of all the points for the lattice NL : array of dimension n x (max number of neighbors) Each row corresponds to a point. The entries tell the indices of the neighbors. KL : array of dimension n x (max number of neighbors) Correponds to NL matrix. 1 corresponds to a true connection while 0 signifies that there is not a connection BL : array of dimension #bonds x 2 Each row is a bond and contains indices of connected points LVUC : NP x 4 array For each particle, gives (lattice vector, unit cell vector) coordinate position of that particle: LV1, LV2, UC For instance, xy[0,:] = LV[0]*LVUC[0,0] + LV[1]*LVUC[0,1] + UC[LVUC[0,2]] LV : 3 x 2 float array Lattice vectors for the kagome lattice with input twist angle UC : 6 x 2 float array (extended) unit cell vectors lattice_type : string label, lattice type. For making output directory """ # If shape is a string, turn it into the appropriate dict if isinstance(shape, str): # Since shape is a string, give key as str and vals to form polygon mask print 'Since shape is a string, give key as str and vals to form polygon mask...' vals = [NH, NV] shape_string = shape NH *= 3 NV *= 3 shape = {shape_string: vals} # Establish triangular lattice, rotated by theta if abs(theta) < 1e-6: latticevecs = [[1, 0], [0.5, np.sqrt(3)*0.5]] else: latticevecs = [[np.cos(theta), np.sin(theta)], [0.5 * np.cos(theta) - np.sqrt(3) * 0.5 * np.sin(theta), np.sqrt(3) * 0.5 * np.cos(theta) + 0.5 * np.sin(theta)]] xypts_tmp, LVUC = blf.generate_lattice_LVUC([NH, NV], latticevecs) # CHECK if check: plt.plot(xypts_tmp[:, 0], xypts_tmp[:, 1], 'b.') for i in range(len(xypts_tmp)): plt.text(xypts_tmp[i, 0], xypts_tmp[i, 1], str(LVUC[i, 0]) + ', ' + str(LVUC[i, 1])) plt.title('Pre-cropped lattice') plt.show() if theta == 0: add_exten = '' else: add_exten = '_theta' + '{0:.3f}'.format(theta / np.pi).replace('.', 'p') + 'pi' # ROTATE BY THETA print 'Rotating by theta= ', theta, '...' xys = copy.deepcopy(xypts_tmp) xypts_tmp = np.array([[x*np.cos(theta) - y*np.sin(theta), y*np.cos(theta)+x*np.sin(theta)] for x, y in xys]) # mask to rectangle if 'circle' in shape: '''add masking to shape here''' tmp2 = xypts_tmp NH, NV = shape['circle'] # Modify below to allow ovals R = NH*0.5 keep = np.logical_and(np.abs(tmp2[:, 0]) < R*1.000000001, np.abs(tmp2[:, 1]) < (2*R*1.0000001)) xy = tmp2[keep, :] LVUC = LVUC[keep, :] shape = 'circle' elif 'hexagon' in shape: print 'cropping to: ', shape tmp2 = xypts_tmp NH, NV = shape['hexagon'] # Modify below to allow different values of NH and NV on the horiz and vertical sides of the hexagon a = NH + 0.5 polygon = np.array([[-a*0.5, -np.sqrt(a**2 - (0.5*a)**2)], [a*0.5, -np.sqrt(a**2 - (0.5*a)**2)], [a, 0.], [a*0.5, np.sqrt(a**2 - (0.5*a)**2)], [-a*0.5, np.sqrt(a**2 - (0.5*a)**2)], [-a, 0.], [-a*0.5, -np.sqrt(a**2 - (0.5*a)**2)]]) bpath = mplpath.Path(polygon) keep = bpath.contains_points(tmp2) xy = tmp2[keep, :] LVUC = LVUC[keep, :] shape = 'hexagon' # Check' if check: codes = [mplpath.Path.MOVETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.CLOSEPOLY, ] path = mplpath.Path(polygon, codes) ax = plt.gca() patch = mpatches.PathPatch(path, facecolor='orange', lw=2) ax.add_patch(patch) ax.plot(polygon[:, 0], polygon[:, 1], 'bo') ax.plot(xy[:, 0], xy[:, 1], 'r.') plt.show() elif 'square' in shape: tmp2 = xypts_tmp NH,NV = shape['square'] if periodicBC: keep = np.logical_and(np.abs(tmp2[:, 0]) < NH * .5 + 0.51, np.abs(tmp2[:, 1]) < (NV * .5 / np.sin(np.pi / 3.) - 0.1)) else: keep = np.logical_and(np.abs(tmp2[:, 0]) < NH*.5 + 0.1, np.abs(tmp2[:, 1]) < (NV*.5/np.sin(np.pi/3.)+0.1)) xy = tmp2[keep, :] LVUC = LVUC[keep, :] shape = 'square' pass elif 'polygon' in shape: bpath = mplpath.Path(shape['polygon']) keep = bpath.contains_points(xypts_tmp) xy = xypts_tmp[keep, :] LVUC = LVUC[keep, :] shape = 'polygon' else: raise RuntimeError('Polygon dictionary not specified in generate_triangular_lattice().') print('Triangulating points...\n') tri = Delaunay(xy) TRItmp = tri.vertices print('Computing bond list...\n') BL = le.Tri2BL(TRItmp) # bL = le.bond_length_list(xy,BL) thres = 1.1 # cut off everything longer than a diagonal print('thres = ' + str(thres)) print('Trimming bond list...\n') BLtrim = le.cut_bonds(BL, xy, thres) print('Trimmed ' + str(len(BL) - len(BLtrim)) + ' bonds.') # print 'BLtrim =', BLtrim print('Recomputing TRI...\n') TRI = le.BL2TRI(BLtrim, xy) # Randomize if eta >0 specified if eta == 0: xypts = xy eta_exten = '' else: print 'Randomizing lattice by eta=', eta jitter = eta*np.random.rand(np.shape(xy)[0], np.shape(xy)[1]) xypts = np.dstack((xy[:, 0] + jitter[:, 0], xy[:, 1] + jitter[:, 1]))[0] eta_exten = '_eta{0:.3f}'.format(eta).replace('.', 'p') # Naming exten = '_' + shape + add_exten + eta_exten # BL = latticevec_filter(BL,xy, C, CBL) NL, KL = le.BL2NLandKL(BLtrim, NN=6) lattice_exten = 'triangular' + exten print 'lattice_exten = ', lattice_exten LV = np.array(latticevecs) UC = np.array([0., 0.]) return xypts, NL, KL, BLtrim, LVUC, LV, UC, lattice_exten
def build_hexannulus_filled_defects(lp): """Build a U(1) symmetric honeycomb lattice within an annulus. The inner radius is given by alpha At some cutoff radius, decrease the number of particles in each new row. Also, place a particle at the center. Instead of lp['alph'] determining the inner radius cutoff as a fraction of the system size, lp['alph'] as the cutoff radius for when to decrease the number of particles in each row. Remove lp['Ndefects'] at each row within a radius of lp['alph'] * system_size. Parameters ---------- lp : dict """ N = lp['NH'] shape = 'circle' theta = np.linspace(0, 2. * np.pi, N + 1) theta = theta[:-1] # The radius, given the length of a side is: # radius = s/(2 * sin(2 pi/ n)), where n is number of sides, s is length of each side # We set the length of a side to be 1 (the rest length of each bond) Rout = 1. / (2. * np.sin(np.pi / float(N))) if lp['alph'] < 1e-5 or lp['alph'] > 1: raise RuntimeError('lp param alph must be > 0 and less than 1') Rinner = lp['alph'] * Rout # Make the first row xtmp = Rout * np.cos(theta) ytmp = Rout * np.sin(theta) xy = np.dstack([xtmp, ytmp])[0] if lp['check']: plt.plot(xy[:, 0], xy[:, 1], 'b.') for ii in range(len(xy)): plt.text(xy[ii, 0] + 0.2 * np.random.rand(1)[0], xy[ii, 1] + 0.2 * np.random.rand(1)[0], str(ii)) plt.title('First row') plt.show() # rotate by delta(theta)/2 and shrink xy so that outer bond lengths are all equal to unity # Here we have all bond lengths of the outer particles == 1, so that the inner radius is determined by # # o z1 # / | # / | # z2 o | |z2 - z0| = |z2 - z1| --> if z2 = r2 e^{i theta/2}, and z1 = r1 e^{i theta}, and z0 = r1, # \ | then r2 = r1 cos[theta/2] - sqrt[s**2 - r1**2 + r1**2 cos[theta/2]**2] # \ | or r2 = r1 cos[theta/2] + sqrt[s**2 - r1**2 + r1**2 cos[theta/2]**2] # o z0 Choose the smaller radius (the first one). # s is the sidelength, initially == 1 # iterate sidelength: s = R*2*sin(2pi/N) # --> see for ex, http://www.mathopenref.com/polygonradius.html dt = np.diff(theta) if (dt - dt[0] < 1e-12).all(): dt = dt[0] else: print 'dt = ', dt raise RuntimeError('Not all thetas are evenly spaced') RR = Rout ss = 1. Rnext = RR * np.cos(dt * 0.5) - np.sqrt(ss**2 - RR**2 + RR**2 * np.cos(dt * 0.5)**2) rlist = [RR] # Continue adding more rows kk = 0 while Rnext > Rinner: print 'Adding Rnext = ', Rnext print 'with bond length connecting to last row = ', ss # Add to xy if np.mod(kk, 2) == 0: xtmp = Rnext * np.cos(theta + dt * 0.5) ytmp = Rnext * np.sin(theta + dt * 0.5) else: xtmp = Rnext * np.cos(theta) ytmp = Rnext * np.sin(theta) xyadd = np.dstack([xtmp, ytmp])[0] xy = np.vstack((xy, xyadd)) rlist.append(Rnext) if lp['check']: plt.plot(xy[:, 0], xy[:, 1], 'b.') for ii in range(len(xy)): plt.text(xy[ii, 0] + 0.2 * np.random.rand(1)[0], xy[ii, 1] + 0.2 * np.random.rand(1)[0], str(ii)) plt.title('next row') plt.show() RR = Rnext ss = RR * np.sin(2. * np.pi / N) print 'next sidelength = ', ss Rnext = RR * np.cos(dt * 0.5) - np.sqrt(ss**2 - RR**2 + RR**2 * np.cos(dt * 0.5)**2) kk += 1 Rfinal = RR # Get NV from the number of rows laid down. NVtri = len(rlist) lp['NV'] = NVtri - 2 print('Triangulating points...\n') tri = Delaunay(xy) TRItmp = tri.vertices print('Computing bond list...\n') BL = le.Tri2BL(TRItmp) # bL = le.bond_length_list(xy,BL) thres = 1.1 # cut off everything longer than a diagonal print('thres = ' + str(thres)) print('Trimming bond list...\n') BLtrim = le.cut_bonds(BL, xy, thres) print('Trimmed ' + str(len(BL) - len(BLtrim)) + ' bonds.') xy, NL, KL, BL = le.voronoi_lattice_from_pts(xy, NN=3, kill_outliers=True) # Remove any bonds that cross the inner circle tmpt = np.linspace(0, 2. * np.pi, 2000) innercircle = Rinner * np.dstack((np.cos(tmpt), np.sin(tmpt)))[0] # cycle the inner circle by one ic_roll = np.dstack((np.roll(innercircle[:, 0], -1), np.roll(innercircle[:, 1], -1)))[0] ic = np.hstack((innercircle, ic_roll)) bondsegs = np.hstack((xy[BL[:, 0]], xy[BL[:, 1]])) does_intersect = linsegs.linesegs_intersect_linesegs(bondsegs, ic, thres=1e-6) keep = np.ones(len(BL[:, 0]), dtype=bool) keep[does_intersect] = False BL = BL[keep] # Remove any points that ended up inside the inner radius (this should not be necessary) inpoly = le.inds_in_polygon(xy, innercircle) keep = np.setdiff1d(np.arange(len(xy)), inpoly) print 'keep = ', keep print 'len(xy) = ', len(xy) xy, NL, KL, BL = le.remove_pts(keep, xy, BL, NN='min', check=lp['check']) # Randomize if eta > 0 specified eta = lp['eta'] if eta == 0: xypts = xy eta_exten = '' else: print 'Randomizing lattice by eta=', eta jitter = eta * np.random.rand(np.shape(xy)[0], np.shape(xy)[1]) xypts = np.dstack( (xy[:, 0] + jitter[:, 0], xy[:, 1] + jitter[:, 1]))[0] eta_exten = '_eta{0:.3f}'.format(eta).replace('.', 'p') # Naming exten = '_circle_delta0p667_phi0p000_alph{0:0.2f}'.format( lp['alph']).replace('.', 'p') + eta_exten lattice_exten = 'hexannulus' + exten print 'lattice_exten = ', lattice_exten if lp['check']: le.display_lattice_2D(xy, BL, NL=NL, KL=KL, title='output from build_hexannulus()', close=False) for ii in range(len(xy)): plt.text(xy[ii, 0] + 0.2 * np.random.rand(1)[0], xy[ii, 1] + 0.2 * np.random.rand(1)[0], str(ii)) plt.show() # Scale up xy BM = le.BL2BM(xy, NL, BL, KL=KL, PVx=None, PVy=None) bL = le.BM2bL(NL, BM, BL) scale = 1. / np.median(bL) xy *= scale return xy, NL, KL, BL, lattice_exten, lp
def generate_square_lattice(shape, NH, NV, eta=0., theta=0., check=False): """Create a square lattice NH wide and NV tall, with sites randomized by eta and rotated by theta. Parameters ---------- shape : string overall shape of the mesh: 'circle' 'hexagon' 'square' NH : int Number of pts along horizontal before boundary is cut NV : int Number of pts along vertical before boundary is cut eta : float randomization or jitter in the positions of the particles theta : float orientation of the lattice vectors (rotation) in units of radians check : bool Whether to view intermediate results Results ---------- """ # Establish square lattice, rotated by theta if abs(theta) < 1e-6: latticevecs = [[1., 0.], [0., 1.]] # todo: SHOULD MODIFY TO INCLUDE LVUC # xypts_tmp, LVUC = generate_lattice_LVUC([NH,NV], latticevecs) xypts_tmp = blf.generate_lattice([NH, NV], latticevecs) else: latticevecs = [[np.cos(theta), np.sin(theta)], [np.sin(theta), np.cos(theta)]] xypts_tmp, LVUC = blf.generate_lattice([2 * NH, 2 * NV], latticevecs) if NH < 3 and NV < 3: if NH == NV == 2: xypts_tmp = np.array( [[0., 0.], np.array(latticevecs[0]), np.array(latticevecs[1]), np.array(latticevecs[0]) + np.array(latticevecs[1])], dtype=float) xypts_tmp -= np.mean(xypts_tmp) elif NH == 1 and NV == 1: '''making single point''' xypts_tmp = np.array([[0., 0.]]) print 'xypts_tmp =', xypts_tmp if eta == 0. or eta == '': etastr = '' else: etastr = '_eta{0:.3f}'.format(eta).replace('.', 'p') if theta == 0. or theta == '': thetastr = '' else: thetastr = '_theta{0:.3f}'.format(theta / np.pi).replace('.', 'p') + 'pi' if shape == 'square': tmp2 = xypts_tmp # shorten name for clarity xy = tmp2 # [np.logical_and(tmp2[:,0]<(NH) , tmp2[:,1]<NV) ,:] elif shape == 'circle': print 'assuming NH == NV since cutting out a circle...' tmp2 = xypts_tmp # shorten name for clarity xy = tmp2[tmp2[:, 0]**2 + tmp2[:, 1]**2 < NH**2, :] elif shape == 'hexagon': tmp2 = xypts_tmp # shorten name for clarity # xy = tmp2[tmp2[:,0]**2+tmp2[:,1]**2 < (NH)**2 ,:] print 'cropping to: ', shape # NH, NV = shape['hexagon'] # Modify below to allow different values of NH and NV on the horiz and vertical sides of the hexagon a = NH + 0.5 polygon = np.array([[-a * 0.5, -np.sqrt(a**2 - (0.5 * a)**2)], [a * 0.5, -np.sqrt(a**2 - (0.5 * a)**2)], [a, 0.], [a * 0.5, np.sqrt(a**2 - (0.5 * a)**2)], [-a * 0.5, np.sqrt(a**2 - (0.5 * a)**2)], [-a, 0.], [-a * 0.5, -np.sqrt(a**2 - (0.5 * a)**2)]]) bpath = mplpath.Path(polygon) keep = bpath.contains_points(tmp2) xy = tmp2[keep] # Check' if check: codes = [ mplpath.Path.MOVETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.CLOSEPOLY, ] path = mplpath.Path(polygon, codes) ax = plt.gca() patch = mpatches.PathPatch(path, facecolor='orange', lw=2) ax.add_patch(patch) ax.plot(polygon[:, 0], polygon[:, 1], 'bo') ax.plot(tmp2[:, 0], tmp2[:, 1], 'r.') plt.show() else: xy = xypts_tmp print('Triangulating points...\n') print 'xy =', xy tri = Delaunay(xy) TRItmp = tri.vertices print('Computing bond list to remove cross braces...\n') BL = le.Tri2BL(TRItmp) thres = np.sqrt(2.0) * .99 # cut off everything as long as a diagonal print('thres = ' + str(thres)) print('Trimming bond list...\n') orig_numBL = len(BL) BL = le.cut_bonds(BL, xy, thres) print('Trimmed ' + str(orig_numBL - len(BL)) + ' bonds.') # print('Recomputing TRI...\n') # TRI = le.BL2TRI(BL, xy) # Randomize by eta if eta == 0: xypts = xy else: print 'Randomizing lattice by eta=', eta jitter = eta * np.random.rand(np.shape(xy)[0], np.shape(xy)[1]) xypts = np.dstack( (xy[:, 0] + jitter[:, 0], xy[:, 1] + jitter[:, 1]))[0] # Naming exten = '_' + shape + etastr + thetastr # BL = latticevec_filter(BL,xy, C, CBL) NL, KL = le.BL2NLandKL(BL, NN=4) lattice_exten = 'square' + exten print 'lattice_exten = ', lattice_exten return xypts, NL, KL, BL, lattice_exten