def generate_cairo_tiling(lp): """ Parameters ---------- lp : dict lattice parameters dict with keys: shape, NH, NV, aratio, delta, phi, check Returns ------- """ print 'creating cairo tiling...' lp_tmp = copy.deepcopy(lp) lp_tmp['eta'] = 0. lp_tmp['NH'] += 5 lp_tmp['NV'] += 5 xyA, NLA, KLA, BLA, LVUCA, LVA, UCA, PVxydictA, PVxA, PVyA, lattice_exten = \ generate_flattened_honeycomb_lattice(lp_tmp) xyleft = xyA[xyA[:, 0] < np.min(xyA[:, 0]) + 1e-4] farleft = np.argmin(xyleft[:, 1]) xyA -= xyleft[farleft] if lp['check']: le.display_lattice_2D(xyA, BLA) xyB = np.dstack((xyA[:, 1], xyA[:, 0]))[0] + np.array([3., 1.]) BLB = (np.abs(BLA) + len(xyA)) * (np.minimum(np.sign(BLA[:, 0]), np.sign(BLA[:, 1]))).reshape(len(BLA), 1) LVUC = 'none' LV = LVA UC = 'none' xy = np.vstack((xyA, xyB)) BL = np.vstack((BLA, BLB)) keep = np.logical_and(np.logical_and(xy[:, 0] > 10, xy[:, 1] > 10), np.logical_and(xy[:, 1] < np.max(xyA[:, 1]), xy[:, 0] < np.max(xyB[:, 0]))) xy, NL, KL, BL = le.remove_pts(keep, xy, BL) # Find all crossing line segs, replace with a particle connected to each particle involved # todo: make periodic BCs work (currently aren't realistically used) PVxydict = copy.deepcopy(PVxydictA) for key in PVxydictA: PVxydict[(key[1], key[0])] = np.array([PVxydictA[key][1], PVxydictA[key][0]]) PVxB = copy.deepcopy(PVyA) PVyB = copy.deepcopy(PVxA) PVx = np.vstack((PVxA, PVxB)) PVy = np.vstack((PVyA, PVyB)) lattice_exten = 'cairo_' + lattice_exten[19:] return xy, NL, KL, BL, LVUC, LV, UC, PVxydict, PVx, PVy, lattice_exten
def relax_bondenergy(xy, BL, fixedpts, tol=1e-2, kL=1., bo=1., check=False, checkim_outpath=None): """ Parameters ---------- xy BL fixedpts tol kL bo check Returns ------- """ # Relax lattice, but fix pts with low LV[1] vals # First get ADJACENT pts with low LV[1] values to fix NP = len(xy) if len(fixedpts) == 2: # ensure that indices are in ascending order if fixedpts[0] > fixedpts[1]: pair = [fixedpts[1], fixedpts[0]] else: pair = fixedpts Nzero_pair0 = np.arange(0, pair[0]) Npair0_pair1 = np.arange(pair[0], pair[1]) Npair1_end = np.arange(pair[1], NP) print 'pair = ', pair bounds = [[None, None]] * (2 * (pair[0])) + \ np.c_[xy[pair[0], :].ravel(), xy[pair[0], :].ravel()].tolist() + \ [[None, None]] * (2 * (pair[1] - pair[0] - 1)) + \ np.c_[xy[pair[1], :].ravel(), xy[pair[1], :].ravel()].tolist() + \ [[None, None]] * (2 * (NP - pair[1] - 1)) print 'lepm.build.pointsets.relax_pointset.relax_bondenergy(): len(bounds) = ', len( bounds) print 'lepm.build.pointsets.relax_pointset.relax_bondenergy(): len(xy) = ', len( xy) else: raise RuntimeError( 'Currently cannot handle more than two fixed points -- add that code here -- should be easy' ) # Old way: fix particles 0 and 1 # bounds = np.c_[xy[:2,:].ravel(), xy[:2,:].ravel()].tolist() + \ # [[None, None]] * (2*(NP-2)) # relaxed lattice print 'relaxing lattice...' def flattened_potential_energy(xy): # We convert xy to a 2D array here. xy = xy.reshape((-1, 2)) bL = le.bond_length_list(xy, BL) # print 'bL = ', bL bU = 0.5 * sum(kL * (bL - bo)**2) return bU xyR = opt.minimize(flattened_potential_energy, xy.ravel(), method='L-BFGS-B', bounds=bounds, tol=tol).x.reshape((-1, 2)) xy = xyR bL0 = bo * np.ones_like(BL[:, 0], dtype=float) if check: bs = le.bond_strain_list(xy, BL, bL0) le.display_lattice_2D(xyR, BL, bs=bs, title='Energy-relaxed network', colorz=False, close=False) plt.scatter(xy[pair, 0], xy[pair, 1], s=500, c='r') if checkim_outpath is not None: plt.savefig(checkim_outpath) plt.show() return xy
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 kk_spec_gridlines(lat, lp, gridspacing, maxval, strongbond_val, weakbond_val, check=False): """Build kk (matrix of spring frequencies) with weakened bonds from a supplied lattice. Parameters ---------- lat : lepm.lattice_class.Lattice instance The lattice on which to build kk gridspacing : float The spacing between gridlines for which to weaken bonds maxval : float The extremal value of x or y coordinate in the network, to use for finding bonds to weaken strongbond_val : float The spring frequency for the stronger, unaltered bonds weakbond_val : float The spring frequency for the altered bonds (assumed weaker) check : bool Display the pattern of strong and weak bonds as blue and red before continuing Returns ------- kk : N x max(#NN) float array bond frequencies matching the KL and NL arrays, with bonds weakened along gridlines """ gridright = np.arange(gridspacing, maxval, gridspacing) gridleft = -gridright gridvals = np.hstack((gridleft, 0, gridright)) # Draw grid gridlinesH = np.array([[-maxval, gridv, maxval, gridv] for gridv in gridvals]) gridlinesV = np.array([[gridv, -maxval, gridv, maxval] for gridv in gridvals]) gridsegs = np.vstack((gridlinesH, gridlinesV)) print 'np.shape(gridlines) = ', np.shape(gridsegs) # Make the bond linesegments xy = lat.xy pvx = lat.PVx pvy = lat.PVy NL = lat.NL if lp['periodicBC']: bondsegs = np.array([[xy[b[0], 0], xy[b[0], 1], xy[b[1], 0] + pvx[b[0], np.where(NL[b[0]] == b[1])[0]], xy[b[1], 1] + pvy[b[0], np.where(NL[b[0]] == b[1])[0]]] for b in np.abs(lat.BL)]) else: bondsegs = np.array([[xy[b[0], 0], xy[b[0], 1], xy[b[1], 0], xy[b[1], 1]] for b in np.abs(lat.BL)]) # get crossings # print 'gridsegs = ', gridsegs does_intersect = lsegs.linesegs_intersect_linesegs(bondsegs, gridsegs) if check: kk = 0 xinds = [0, 2] yinds = [1, 3] aBL = np.abs(lat.BL) for bb in bondsegs: if does_intersect[kk]: plt.plot(bb[xinds], bb[yinds], 'r.-') else: plt.plot(bb[xinds], bb[yinds], 'b.-') kk += 1 plt.show() kk = 0 for bb in aBL: if does_intersect[kk]: plt.plot(xy[bb, 0], xy[bb, 1], 'r.-') else: plt.plot(xy[bb, 0], xy[bb, 1], 'b.-') kk += 1 plt.show() # Build kk as it would be constructed without the kkspec specification # In a copy of lp, kill the kk specification to avoid getting stuck in a loop from lepm.gyro_lattice_class import GyroLattice lp_copy = copy.deepcopy(lp) lp_copy['kkspec'] = None lp_copy['kk'] = strongbond_val tmp_glat = GyroLattice(lat, lp_copy) kk = copy.deepcopy(tmp_glat.kk) # Now weaken the gridline bonds. Note that we take the absolute value of BL to allow for periodic networks print 'Altering weak bonds --> ', weakbond_val # print 'lat.BL[does_intersect] = ', lat.BL[does_intersect] for bond in np.abs(lat.BL[does_intersect]): kk[bond[0], np.where(lat.NL[bond[0]] == bond[1])[0]] = weakbond_val kk[bond[1], np.where(lat.NL[bond[1]] == bond[0])[0]] = weakbond_val # check it if check: kkv = le.KL2kL(lat.NL, kk, lat.BL) test = -np.ones(len(lat.BL[:, 0]), dtype=float) test[does_intersect] = weakbond_val print 'test = ', test le.display_lattice_2D(lat.xy, lat.BL, NL=lat.NL, KL=lat.KL, PVxydict=lat.PVxydict, PVx=lat.PVx, PVy=lat.PVy, bs=test, title='', xlimv=None, ylimv=None, climv=0.1, colorz=True, ptcolor=None, ptsize=10, close=True, colorpoly=False, viewmethod=False, labelinds=False, colormap='seismic', bgcolor='#d9d9d9', axis_off=False, fig=None, ax=None, linewidth=0.0, edgecolors=None, check=True) le.display_lattice_2D(lat.xy, lat.BL, NL=lat.NL, KL=lat.KL, PVxydict=lat.PVxydict, PVx=lat.PVx, PVy=lat.PVy, bs=kkv, title='', xlimv=None, ylimv=None, climv=0.1, colorz=True, ptcolor=None, ptsize=10, close=True, colorpoly=False, viewmethod=False, labelinds=False, colormap='seismic', bgcolor='#d9d9d9', axis_off=False, fig=None, ax=None, linewidth=0.0, edgecolors=None, check=True) return kk
def build_kagome_hucent(lp): print('Loading hyperuniform to build lattice...') networkdir = lp['rootdir'] + 'networks/' shape = lp['shape'] NH = lp['NH'] NV = lp['NV'] check = lp['check'] if lp['NP_load'] == 0: points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N400/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) + lp['origin'] addpc = .05 xytmp, trash1, trash2, trash3 = blf.mask_with_polygon(shape, NH + 4, NV + 4, points, [], eps=addpc) polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) xy, NL, KL, BL = blf.kagomecentroid_lattice_from_pts(xytmp, polygon=polygon, trimbound=False, check=check) polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) if check: le.display_lattice_2D( xy, BL, NL=NL, KL=KL, title='Cropped centroid lattice, before dilation') # Form output bounding box and extent measurement LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict = {} PVx = [] PVy = [] BBox = polygon # make string from origin values print 'lp[origin] = ', lp['origin'] print 'type(lp[origin]) = ', type(lp['origin']) if (np.abs(lp['origin']) < 1e-7).all(): originstr = '' else: originstr = '_originX' + '{0:0.2f}'.format(lp['origin'][0]).replace('.', 'p') + \ 'Y' + '{0:0.2f}'.format(lp['origin'][1]).replace('.', 'p') periodicBCstr = '' else: # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) LL = (lp['NP_load'], lp['NP_load']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + \ str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) xy, NL, KL, BL, PVxydict = blf.kagomecentroid_periodic_network_from_pts( points, LL, BBox=BBox, check=lp['check']) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicBCstr = '_periodic' # 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 polygon *= scale BBox *= scale LL = (LL[0] * scale, LL[1] * scale) if lp['periodicBC']: PVx *= scale PVy *= scale PVxydict.update((key, val * scale) for key, val in PVxydict.items()) lattice_exten = 'kagome_hucent_' + shape + periodicBCstr + '_d{0:02d}'.format( int(lp['conf'])) + originstr LV = 'none' LVUC = 'none' UC = 'none' return xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten
def build_jammed(lp): """Use bonds from jammed packing --> already near isostatic, but can't tune above it, only below. Parameters ---------- lp Returns ------- """ # Use bonds from jammed packing --> already near isostatic, but can't tune above it, only below. shape = lp['shape'] nh = lp['NH'] nv = lp['NV'] networkdir = dio.ensure_dir(lp['rootdir']) + 'networks/' print('Loading isostatic file to build jammed lattice...') # Now load use_hexner = (lp['source'] == 'hexner') if use_hexner: print 'lp[periodicBC] = ', lp['periodicBC'] points, BL, LLv, numberstr, sizestr, lp = load_hexner_jammed( lp, BL_load=True) sourcestr = '_hexner' else: # Use Stephan Ulrich's lattices if lp['periodicBC']: RuntimeError('Not sure if Stephan Ulrich lattices are periodic!') zindex = '{0:03d}'.format(int(lp['loadlattice_z'])) number = '{0:03d}'.format(int(lp['conf'])) points = np.loadtxt(networkdir + 'isostatic_source/isostatic_homog_z' + zindex + '_conf' + number + '_nodes.txt') BL = np.loadtxt(networkdir + 'isostatic_source/isostatic_homog_z' + zindex + '_conf' + number + '_bonds.txt', usecols=(0, 1), dtype=int) sourcestr = '_ulrich_homog' print 'BL[100] = ', BL[100] # Loaded BL uses indexing starting at 1, not 0 BL -= 1 print 'BL[100] = ', BL[100] numberstr = number[1:] if check: le.display_lattice_2D(points, np.abs(BL), title='points and bonds loaded, before pruning') xy = points - np.mean(points, axis=0) NL, KL = le.BL2NLandKL(BL, NN='min') # Remove any points with no bonds print 'Removing points without any bonds...' keep = KL.any(axis=1) xy, NL, KL, BL = le.remove_pts(keep, xy, BL, NN='min') print 'len(xy) = ', len(xy) if check: le.display_lattice_2D( xy, np.abs(BL), title='Before tuning z (down) and before fixing PBCs') if lp['cutz_method'] == 'random': NL, KL, BL = le.cut_bonds_z_random(xy, NL, KL, BL, lp['target_z'], bulk_determination='Endpts') elif lp['cutz_method'] == 'highest': NL, KL, BL = le.cut_bonds_z_highest(xy, NL, KL, BL, lp['target_z'], check=check) elif lp['cutz_method'] == 'none': pass if lp['periodicBC'] or lp['NP_load'] > 0: print 'Building periodicBC PVs...' lp['periodicBC'] = True LL = (LLv, LLv) polygon = 0.5 * np.array([[-LLv, -LLv], [LLv, -LLv], [LLv, LLv], [-LLv, LLv]]) BBox = polygon PV = np.array([[LLv, 0.0], [LLv, LLv], [LLv, -LLv], [0.0, 0.0], [0.0, LLv], [0.0, -LLv], [-LLv, 0.0], [-LLv, LLv], [-LLv, -LLv]]) PVxydict = le.BL2PVxydict(BL, xy, PV) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) if lp['check']: le.display_lattice_2D(xy, BL, NL=NL, KL=KL, PVx=PVx, PVy=PVy, title='Checking periodic BCs', close=False, colorz=False) for ii in range(len(xy)): plt.text(xy[ii, 0] + 0.1, xy[ii, 1], str(ii)) plt.plot(xy[:, 0], xy[:, 1], 'go') plt.show() else: polygon = blf.auto_polygon(shape, nh, nv, eps=0.00) BBox = polygon print('Trimming lattice to be NH x NV...') keep = np.logical_and( abs(xy[:, 0]) < nh * 0.5, abs(xy[:, 1]) < nv * 0.5) print "Check that if lp['NP_load'] !=0 then len(keep) == len(xy):", len( keep) == len(xy) xy, NL, KL, BL = le.remove_pts(keep, xy, BL, NN='min') LL = (nh, nv) PVx = [] PVy = [] PVxydict = {} z = le.compute_bulk_z(xy, NL, KL, BL) print 'FOUND z = ', z if lp['periodicBC']: periodicBCstr = '_periodicBC' else: periodicBCstr = '' print('Defining lattice_exten...') lattice_exten = 'jammed_' + shape + sourcestr + periodicBCstr + '_z' + '{0:0.03f}'.format(z) + '_conf' + \ numberstr + '_zmethod' + lp['cutz_method'] LV = 'none' UC = 'none' LVUC = 'none' return xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp
def build_kagome_huvor(lp): """Construct a kagomized network from hyperuniform point set and voronoize it with Wigner-Seitz Parameters ---------- lp : dict Lattice parameters dictionary, with keys: rootdir, conf, origin, shape, NH, NV, check, NP_load (if periodic) """ if lp['NP_load'] == 0: points = np.loadtxt( dio.prepdir(lp['rootdir']) + 'networks/hyperuniform_source/hyperuniform_N400/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) + lp['origin'] addpc = .05 xytmp, trash1, trash2, trash3 = \ blf.mask_with_polygon(lp['shape'], lp['NH'] + 7, lp['NV'] + 7, points, [], eps=addpc) polygon = blf.auto_polygon(lp['shape'], lp['NH'], lp['NV'], eps=0.00) xy, NL, KL, BL = blf.kagomevoronoi_network_from_pts(xytmp, polygon=polygon, kill_outliers=True, check=lp['check']) LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict, PVx, PVy = {}, [], [] BBox = polygon if lp['check']: le.display_lattice_2D( xy, BL, NL=NL, KL=KL, title='Cropped centroid lattice, before dilation') # make string from origin values print 'lp[origin] = ', lp['origin'] print 'type(lp[origin]) = ', type(lp['origin']) if (np.abs(lp['origin']) < 1e-7).all(): originstr = '' else: originstr = '_originX' + '{0:0.2f}'.format(lp['origin'][0]).replace('.', 'p') + \ 'Y' + '{0:0.2f}'.format(lp['origin'][1]).replace('.', 'p') periodicBCstr = '' else: # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) LL = (lp['NP_load'], lp['NP_load']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) points = np.loadtxt( dio.prepdir(lp['rootdir']) + 'networks/hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) xy, NL, KL, BL, PVxydict = blf.kagomevoronoi_periodic_network_from_pts( points, LL, BBox=BBox, check=lp['check']) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicBCstr = '_periodic' # 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 polygon *= scale BBox *= scale LL = (LL[0] * scale, LL[1] * scale) if lp['periodicBC']: PVx *= scale PVy *= scale PVxydict.update((key, val * scale) for key, val in PVxydict.items()) lattice_exten = 'kagome_huvor_' + lp[ 'shape'] + periodicBCstr + '_d{0:02d}'.format(int( lp['conf'])) + originstr return xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten
def generate_penrose_rhombic_tiling(Num_sub, check=False): """Generates penrose rhomus tiling (P3) with given number of subdivisions (scaling method) http://preshing.com/20110831/penrose-tiling-explained/ """ # ------ Configuration -------- NUM_SUBDIVISIONS = Num_sub # ----------------------------- goldenRatio = (1.0 + math.sqrt(5.0)) / 2.0 def subdivide(triangles): result = [] for color, A, B, C in triangles: if color == 0: # Subdivide red triangle P = A + (B - A) / goldenRatio result += [(0, C, P, B), (1, P, C, A)] else: # Subdivide blue triangle Q = B + (A - B) / goldenRatio R = B + (C - B) / goldenRatio result += [(1, R, C, A), (1, Q, R, B), (0, R, Q, A)] return result # Create wheel of red triangles around the origin triangles = [] for i in xrange(10): B = cmath.rect(1, (2*i - 1) * math.pi / 10) C = cmath.rect(1, (2*i + 1) * math.pi / 10) if i % 2 == 0: B, C = C, B # Make sure to mirror every second triangle triangles.append((0, B, 0j, C)) def plot_quasicrystal(triangles): ax = plt.gca() for color, A, B, C in triangles: if color == 0: codes = [mplpath.Path.MOVETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.CLOSEPOLY, ] polygon = np.array([[A.real, A.imag], [B.real, B.imag], [C.real, C.imag], [A.real, A.imag]]) path = mplpath.Path(polygon, codes) patch = mpatches.PathPatch(path, facecolor='orange', lw=2) ax.add_patch(patch) if color == 1: codes = [mplpath.Path.MOVETO, mplpath.Path.LINETO, mplpath.Path.LINETO, mplpath.Path.CLOSEPOLY, ] polygon = np.array([[A.real, A.imag], [B.real, B.imag], [C.real, C.imag], [A.real, A.imag]]) path = mplpath.Path(polygon, codes) patch = mpatches.PathPatch(path, facecolor='blue', lw=2) ax.add_patch(patch) return ax # Create wheel of red triangles around the origin triangles = [] for i in xrange(10): B = cmath.rect(1, (2*i - 1) * math.pi / 10) C = cmath.rect(1, (2*i + 1) * math.pi / 10) if i % 2 == 0: B, C = C, B # Make sure to mirror every second triangle triangles.append((0, 0j, B, C)) # Perform subdivisions for i in xrange(NUM_SUBDIVISIONS): triangles = subdivide(triangles) # Prepare cairo surface # surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, IMAGE_SIZE[0], IMAGE_SIZE[1]) # cr = cairo.Context(surface) # cr.translate(IMAGE_SIZE[0] / 2.0, IMAGE_SIZE[1] / 2.0) # wheelRadius = 1.2 * math.sqrt((IMAGE_SIZE[0] / 2.0) ** 2 + (IMAGE_SIZE[1] / 2.0) ** 2) # cr.scale(wheelRadius, wheelRadius) # Draw red triangles if check: plot_quasicrystal(triangles) plt.show() # Scale points tri = np.array(triangles) mindist = np.min(abs(tri[:, 1] - tri[:, 0])) print 'mindist = ', mindist scale = 1./mindist tri = tri[:, 1:4] * scale if check: plot_quasicrystal(triangles) # Convert points to numbered points # Create dict of locations to indices indexd = {} xy = np.zeros((len(tri) * 3, 2)) TRI = np.zeros_like(tri, dtype=int) rowIND = 0 dmyi = 0 offs = float(np.ceil(np.max(tri.real).ravel())+1) for AA, BB, CC in tri: # reformat A,B,C A = ('{0:0.2f}'.format(AA.real + offs), '{0:0.2f}'.format(AA.imag + offs)) B = ('{0:0.2f}'.format(BB.real + offs), '{0:0.2f}'.format(BB.imag + offs)) C = ('{0:0.2f}'.format(CC.real + offs), '{0:0.2f}'.format(CC.imag + offs)) # print '\n\n\n' # print 'A = ', A if A not in indexd: indexd[A] = dmyi xy[dmyi] = [AA.real, AA.imag] TRI[rowIND, 0] = dmyi dmyi += 1 # print 'xy[0:dmyi,:] = ', xy[0:dmyi,:] else: index = indexd[A] TRI[rowIND, 0] = index # print 'indexd = ', indexd # print '\nB = ', B if B not in indexd: indexd[B] = dmyi xy[dmyi] = [BB.real, BB.imag] TRI[rowIND, 1] = dmyi dmyi += 1 # print 'xy[0:dmyi,:] = ', xy[0:dmyi,:] else: index = indexd[B] TRI[rowIND, 1] = index # print 'indexd = ', indexd # print '\nC = ', C if C not in indexd: indexd[C] = dmyi xy[dmyi] = [CC.real, CC.imag] TRI[rowIND, 2] = dmyi dmyi += 1 # print 'xy[0:dmyi,:] = ', xy[0:dmyi,:] else: index = indexd[C] TRI[rowIND, 2] = index rowIND += 1 xy = xy[0:dmyi] print 'xy = ', xy if check: # plot_quasicrystal(triangles) plt.plot(xy[:, 0], xy[:, 1], 'b.') plt.triplot(xy[:, 0], xy[:, 1], TRI, 'ro-') plt.show() BL = le.TRI2BL(TRI) NL, KL = le.BL2NLandKL(BL, NP='auto', NN='min') print 'TRI = ', TRI print 'BL = ', BL if check: le.display_lattice_2D(xy, BL, close=False) for ii in range(len(xy)): plt.text(xy[ii, 0], xy[ii, 1], str(ii)) plt.show() lattice_exten = 'penroserhombTri_div_' + str(Num_sub) return xy, NL, KL, BL, TRI, lattice_exten
def build_hyperuniform(lp): """Build a network from a triangulated hyperuniform pointset Parameters ---------- lp Returns ------- """ networkdir = dio.prepdir(lp['rootdir']) + 'networks/' NH = lp['NH'] NV = lp['NV'] shape = lp['shape'] if lp['NP_load'] == 0: points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N400/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) + lp['origin'] # make lattice larger than final cut keep = np.logical_and( abs(points[:, 0]) < NH * 1.5 + 8, abs(points[:, 1]) < NV * 1.5 + 8) xy = points[keep] xytri, NL, KL, BL, BM = le.delaunay_lattice_from_pts( xy, trimbound=False, target_z=lp['target_z']) # Crop lattice down to size polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) BBox = polygon print('Trimming lattice to be NH x NV...') keep = np.logical_and( abs(xy[:, 0]) < NH * 0.5, abs(xy[:, 1]) < NV * 0.5) print "Check that if lp['NP_load'] !=0 then len(keep) == len(xy):", len( keep) == len(xy) xy, NL, KL, BL = le.remove_pts(keep, xytri, BL, NN='min') # make string from origin values print 'lp[origin] = ', lp['origin'] print 'type(lp[origin]) = ', type(lp['origin']) if (np.abs(lp['origin']) < 1e-7).all(): originstr = '' else: originstr = '_originX' + '{0:0.2f}'.format(lp['origin'][0]).replace('.', 'p') + \ 'Y' + '{0:0.2f}'.format(lp['origin'][1]).replace('.', 'p') periodicstr = '' LL = (NH, NV) BBox = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]], dtype=float) PVx = [] PVy = [] PVxydict = {} else: # Unlike in the jammed case, we can't load a periodic bond list! We must make it. lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + \ str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) LL = (lp['NP_load'], lp['NP_load']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon xy, NL, KL, BL, PVxydict = le.delaunay_rect_periodic_network_from_pts( points, LL, BBox='auto', check=lp['check'], zmethod=lp['cutz_method'], target_z=lp['target_z']) print 'Building periodicBC PVs...' PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicstr = '_periodic' if lp['check']: le.display_lattice_2D(xy, BL, NL=NL, KL=KL, PVx=PVx, PVy=PVy, title='Checking periodic BCs', close=False, colorz=False) for ii in range(len(xy)): plt.text(xy[ii, 0] + 0.1, xy[ii, 1], str(ii)) plt.plot(xy[:, 0], xy[:, 1], 'go') plt.show() lattice_exten = 'hyperuniform_' + shape + periodicstr + '_d' + '{0:02d}'.format(int(lp['conf'])) + \ '_z{0:0.3f}'.format(lp['target_z']) + originstr LV = 'none' UC = 'none' LVUC = 'none' return xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten
def build_select_region(lp): """ Parameters ---------- lp Returns ------- """ lpnew = copy.deepcopy(lp) lpnew['LatticeTop'] = lp['LatticeTop'].split('selregion_')[-1] lpnew['check'] = False print 'lpnew[LatticeTop] = ', lpnew['LatticeTop'] lattice = lattice_class.Lattice(lpnew) print '\nBuilding lattice...' lattice.build() # xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten = build_kagome_isocent(lp) xy = lattice.xy NL = lattice.NL KL = lattice.KL BL = lattice.BL PVx = lattice.PVx PVy = lattice.PVy PVxydict = lattice.PVxydict try: LVUC = lattice.lp['LVUC'] LV = lattice.lp['LV'] UC = lattice.lp['UC'] except: LVUC = 'none' LV = 'none' UC = 'none' LL = lattice.lp['LL'] old_lattice_exten = lattice.lp['lattice_exten'] # Display lattice ax = le.display_lattice_2D(xy, BL, NL=NL, KL=KL, PVxydict=PVxydict, PVx=PVx, PVy=PVy, title='Choose roi polygon', xlimv=None, ylimv=None, colorz=True, ptcolor=None, ptsize=10, close=False, colorpoly=False, viewmethod=False, labelinds=False, colormap='BlueBlackRed', bgcolor='#FFFFFF', axis_off=False, linewidth=0.0, edgecolors=None, check=False) # let user draw ROI roi = roipoly(ax=ax, roicolor='r') print 'roi = ', roi print 'x = ', roi.allxpoints print 'y = ', roi.allypoints roi = np.dstack((roi.allxpoints, roi.allypoints))[0] inpoly = dh.inds_in_polygon(xy, roi) print 'inpoly = ', inpoly if lp['check']: plt.plot(xy[inpoly, 0], xy[inpoly, 1], 'b.') plt.show() xy, NL, KL, BL = le.remove_pts(inpoly, xy, BL, check=lp['check']) if lp['periodicBC']: PV = le.PVxydict2PV(PVxydict) PVxydict = le.BL2PVxydict(BL, xy, PV) # If cropping the points has cut off all periodic BCs, update lp to reflect this if len(PVxydict) == 0: lp['periodicBC'] = False if LVUC is not None and LVUC is not 'none': LVUC = LVUC[inpoly] BBox = roi lattice_exten = 'selregion_' + old_lattice_exten + '_NP{0:06d}'.format( len(xy)) xy -= np.mean(xy, axis=0) if lp['check']: ax = le.display_lattice_2D(xy, BL, NL=NL, KL=KL, PVxydict=PVxydict, PVx=PVx, PVy=PVy, title='Cropped network', xlimv=None, ylimv=None, colorz=True, ptcolor=None, ptsize=10, close=False, colorpoly=False, viewmethod=False, labelinds=False, colormap='BlueBlackRed', bgcolor='#FFFFFF', axis_off=False, linewidth=0.0, edgecolors=None, check=False) return xy, NL, KL, BL, PVx, PVy, PVxydict, LVUC, BBox, LL, LV, UC, lattice_exten, lp
def generate_dislocated_hexagonal_lattice(shape, NH, NV, points, Bvecs=[], tol=1e-3, relax_each_step=False, relax_twice=True, check=False): """ Generate a hexagonal lattice with dislocations at specified locations and with given Burgers vectors Parameters ---------- shape : string or dict with keys 'description':string and 'polygon':polygon array Global shape of the mesh, in form 'square', 'hexagon', etc or as a dictionary with keys shape['description'] = the string to name the custom polygon, and shape['polygon'] = 2d numpy array NH : int Number of pts along horizontal. If shape='hexagon', this is the width (in cells) of the bottom side (a) NV : int Number of pts along vertical, or 2x the number of rows of lattice pt : #dislocations x 2 float array or int array of 2D points, locations to place dislocations Bvecs : #dislocations x 1 string array or empty list orientations of Burgers vectors, as 'W' 'SW' 'SE' 'E' 'NE' 'NW' If empty list, orientations are randomized Returns ---------- xy : NP x 2 array Equilibrium lattice positions of honeycomb-like lattice NL : matrix of dimension n x (max number of neighbors) Each row corresponds to a gyroscope. The entries tell the numbers of the neighboring gyroscopes KL : matrix of dimension n x (max number of neighbors) Correponds to Ni matrix. 1 corresponds to a true connection while 0 signifies that there is not a connection BL : #bonds x 2 int array Each row is a bond and contains indices of connected points, of honeycomb-like lattice lattice_exten : string description of the lattice, complete with parameters for properly saving the lattice files """ from lepm.build import build_triangular if isinstance(shape, str): shape_string = shape vals = [NH, NV] if shape in ['hexagon', 'square']: shape = {shape_string: vals} # since shape is dict, make lattice larger than necessary for cropping purposes xy, NL, KL, BL, LVUC, LV, UC, trash = \ build_triangular.generate_triangular_lattice(shape, NH * 3, NV * 3, eta=0., theta=0., check=check) if check: le.display_lattice_2D(xy, BL, title='triangular latt') tri = Delaunay(xy) TRI = tri.vertices BL = le.TRI2BL(TRI) thres = 1.05 # cut off everything longer than normal print('thres = ' + str(thres)) print('Trimming bond list...\n') BL = le.cut_bonds(BL, xy, thres) # Need to multiply bond length by factor to make centroids 1 unit apart. restlen = 1. / np.sqrt((1. / 3. * np.cos(np.pi / 3.) - 2. / 3.) ** 2 + (1. / 3. * np.sin(np.pi / 3.)) ** 2) xy *= restlen NP0 = len(xy) # If pt is an integer, supply random points in the bulk print 'points before check = ', points if isinstance(points, int): print 'Points is integer: ascribe random points in bounding polygon as defect sites...' pt = [] boundary = le.extract_boundary(xy, NL, KL, BL) boundarypoly = np.array(boundary.tolist() + [boundary[0]]) xybp = xy[boundarypoly].tolist() polygon = leg.Polygon(xybp) for ii in range(points): # generate random points point = polygon.random_point() pt += [point.to_list()] points = np.array(pt) lattexten_is_Rand = True else: lattexten_is_Rand = False # Prepare Bvecs (burgers vectors) if Bvecs == [] or Bvecs in ['W', 'West']: BvecList = ['W' for ii in range(len(points))] Bvecstr = 'W' # Order points in increasing y-values for W Bvecs sortIND = np.argsort(points[:, 1]) points = points[sortIND] elif Bvecs in ['random', 'Random', 'rand']: BvecList = [0] * len(points) rands = np.random.rand(len(points)) for ii in range(len(points)): rii = rands[ii] if rii < 1. / 6.: BvecList[ii] = 'W' elif rii < 1. / 3.: BvecList[ii] = 'SW' elif rii < 1. / 2.: BvecList[ii] = 'SE' elif rii < 4. / 6.: BvecList[ii] = 'E' elif rii < 5. / 6.: BvecList[ii] = 'NE' else: BvecList[ii] = 'NW' Bvecstr = 'Random' print 'points = ', points relax_twice_tmp = False tol_tmp = 0.1 for ii in range(len(points)): print 'Adding dislocation #', ii # If this isn't the final point, don't bother relaxing twice or precisely if ii == len(points) - 1: relax_twice_tmp = relax_twice tol_tmp = tol relax_each_step = True pt = points[ii] Bvec = BvecList[ii] print '\n----------\nAdding dislocation at pt = ', pt if Bvec in ['W', 'West']: xy, LVUC, BL = insert_dislocation_triangular_westBurgersvector(pt, xy, LVUC, BL, bo=restlen, check=check, relax_lattice=relax_each_step, relax_twice=relax_twice_tmp, tol=tol_tmp) xy0 = xy # Centroids to get particle positions # print 'BL= ', BL TRI = le.BL2TRI(BL, xy) # print 'TRI = ', TRI if check: le.display_lattice_2D(xy0, BL, title='checking BL2TRI', close=False) for i in range(len(xy0)): plt.text(xy0[i, 0] + 0.01, xy0[i, 1] + 0.01, str(i)) plt.show() xy, NL, KL, BL, BM = le.centroid_lattice_from_TRI(xy0, TRI) #################################### # CHECK if check: # print 'xy0 = ', xy0 le.display_lattice_2D(xy, BL, NL=NL, title='Centroid lattice', close=False) for i in range(len(xy)): plt.text(xy[i, 0] + 0.01, xy[i, 1] + 0.01, str(i)) for i in range(len(xy0)): plt.text(xy0[i, 0] + 0.01, xy0[i, 1] + 0.01, str(i)) plt.triplot(xy0[:, 0], xy0[:, 1], TRI, 'go-') plt.show() #################################### # Cannot relax lattice here because there are too many zero modes and guest modes in the system # --> the result would be a mess exten = '_' + shape_string + '_Ndefects' + str(len(points)) + '_Bvec' + Bvecstr if lattexten_is_Rand: lattice_exten = 'dislocatedRand' + exten else: lattice_exten = 'dislocated' + exten return xy, NL, KL, BL, lattice_exten
def insert_dislocation_triangular_westBurgersvector(pt, xy, LVUC, BL, bo=1., check=False, relax_lattice=True, relax_twice=False, tol=1e-3): """Insert a dislocation with 'right'-pointing Burger's vector near pt, in a triangular lattice. Parameters ---------- pt : 1 x 2 float list or array point near which to insert dislocation xy : NP0 x 2 float array points of the lattice before dislocation insertion LVUC : bo : float or string 'centroid' rest bond length, if auto, then prepares for centroids to have rest length of 1. --> np.sqrt( (1./3.* np.cos(np.pi/3.)-2./3.)**2 + (1./3.* np.sin(np.pi/3.))**2 ) tol : float tolerance for minimization step Returns ---------- """ NP0 = len(xy) # Add two half rows into triangular lattice # First find two nearest points (but near in x only) x = xy[:, 0]; y = xy[:, 1] tree = scipy.spatial.KDTree(zip(x, y)) numfind = 6 print 'pt = ', pt found = tree.query(pt, k=numfind)[1] print 'found = ', found # if not (LVUC[:,1] > LVUC[found,1] ).any(): # # this point is at the top, get a different one gotequal = False # First try to grab leftpoint as the particle nearest pt closest = tree.query(pt, k=1)[1] inds = np.setdiff1d(found, closest) print 'closest= ', closest print 'inds = ', inds getequal = np.where(np.logical_and(LVUC[inds, 1] == LVUC[closest, 1], np.abs(LVUC[inds, 0] - LVUC[closest, 0]) == 1))[0] # print 'getequal = ', getequal if len(getequal) > 0: equalIND = getequal[0] pair = [closest, inds[equalIND]] else: print '\n did not find pair for closest point, so finding pair very nearby' i = 0 while not gotequal: # look at all the other particles (not particle found[i]) inds_noti = np.setdiff1d(np.arange(numfind), np.array([i])) inds = found[inds_noti] # print 'i = ', i # print 'inds_noti = ', inds_noti # print 'inds = ', inds # print 'found[i] = ', found[i] # getequal = np.where(np.logical_and(LVUC[inds, 1] == LVUC[found[i], 1], np.abs(LVUC[inds, 0] - LVUC[found[i], 0]) == 1))[0] # print 'getequal = ', getequal if len(getequal) > 0: gotequal = True equalIND = getequal[0] pair = [found[i], inds[equalIND]] else: i += 1 print 'pair = ', pair # Add rows by using LVUC # First, get LVUC parametrization of the target position if LVUC[pair[0], 0] < LVUC[pair[1], 0]: leftpt = pair[0] rightpt = pair[1] else: leftpt = pair[1] rightpt = pair[0] # leftpt new rightpt # o x o # Grab LVUC coords for left inserted half row LEFTrow = (np.where(np.logical_and(LVUC[:, 1] > LVUC[leftpt, 1], (LVUC[:, 0] + LVUC[:, 1] == LVUC[leftpt, 0] + LVUC[leftpt, 1])))[0]).tolist() LEFTrow.append(leftpt) LEFTrow = np.array(LEFTrow) LVUCnewLrow = LVUC[LEFTrow] # Adjust all points left of the inserted row. # These are points with LVUC[:,1] > LVUC[target,1] and ( LVUC[:,0]+LVUC[:,1] < LVUC[target,0]+LVUC[target,1] ) LEFT = np.where(np.logical_and(LVUC[:, 1] > LVUC[leftpt, 1] - 1, (LVUC[:, 0] + LVUC[:, 1] < LVUC[rightpt, 0] + LVUC[rightpt, 1])))[0] LVUC[LEFT, 0] -= 1 # Insert new point between columns in lattice # First get indices of points just to the right of LEFTrow Lr2 = np.where(np.logical_and(LVUC[:, 1] > LVUC[leftpt, 1] - 1, LVUC[:, 0] + LVUC[:, 1] == LVUC[leftpt, 0] + LVUC[leftpt, 1] + 2))[0] # Sort LEFTrow by increasing LV[1] sortIND_LEFTrow = np.argsort(LVUC[LEFTrow, 1]) LEFTrow = LEFTrow[sortIND_LEFTrow] # Sort LVUCnewLrow by increasing LV[1] sortIND = np.argsort(LVUCnewLrow[:, 1]) LVUCnewLrow = LVUCnewLrow[sortIND] # Sort Lr2 by increasing LV[1] sortIND_Lr2 = np.argsort(LVUC[Lr2, 1]) Lr2 = Lr2[sortIND_Lr2] print 'len(xy) = ', len(xy) print 'len(LVUC) = ', len(LVUC) print 'LVUCnewLrow = ', LVUCnewLrow ################################# # Check if check: plt.plot(xy[:, 0], xy[:, 1], 'bo') plt.scatter(xy[LEFTrow, 0], xy[LEFTrow, 1], s=300, c='r', marker='^') # plt.scatter(xy[RIGHTrow,0], xy[RIGHTrow,1], s=300, c='g', marker='s') for i in range(len(xy[:, 0])): plt.text(xy[i, 0], xy[i, 1], str(LVUC[i, 0]) + ', ' + str(LVUC[i, 1])) plt.title('Identified left row') plt.show() ################################# # Match Lr2 indices with LEFTrow indices, point by point: # LEFTrow new Lr2 # o x o LrINDs = [] for ii in np.arange(len(LEFTrow)): try: tmp = np.where(LVUC[Lr2, 1] == LVUC[LEFTrow[ii], 1]) LrINDs.append(tmp[0][0]) except: pass '''Reached boundary, no match''' # print 'LEFTrow = ', LEFTrow # print 'Lr2 = ', Lr2 # print 'Lr2[LrINDs] = ', Lr2[LrINDs] # extrapt_inds is a subset of Lr2, which is the column of pts to the right of the inserted one # This is automatically sorted extrapt_inds = np.setdiff1d(Lr2, Lr2[LrINDs]) # print 'LrINDs = ', LrINDs # Add the left half row Lr2add = Lr2[LrINDs] xynew = np.mean([xy[LEFTrow, :], xy[Lr2add, :]], axis=0) # print 'xynew = ', xynew # print 'LVUCnewLrow = ', LVUCnewLrow xy = np.vstack((xy, xynew)) LVUC = np.vstack((LVUC, LVUCnewLrow)) # print 'xy = ', xy # print 'LVUC = ', LVUC LaddIND = np.arange(NP0, len(xy)) # new particle with Lowest LV[1] is special lowest_new_pt = NP0 ################################# # Check if check: plt.plot(xy[:, 0], xy[:, 1], 'bo') plt.scatter(xy[LEFTrow, 0], xy[LEFTrow, 1], s=500, c='r', marker='^', zorder=0) # plt.scatter(xy[RIGHTrow,0], xy[RIGHTrow,1], c='g', marker='s') for i in range(len(xy[:, 0])): plt.text(xy[i, 0], xy[i, 1], str(LVUC[i, 0]) + ', ' + str(LVUC[i, 1])) plt.title('After adding one row, but not yet boundary points of row') plt.show() ################################# # print 'len(xy) = ', len(xy) # print 'len(LVUC) = ', len(LVUC) # The added point with the largest LV[1] value is special # (it ends up being second highest in LV1, but call it topnew here.) topnew_tmp = np.where(LVUC[LaddIND, 1] == max(LVUC[LaddIND, 1]))[0][0] topnew = LaddIND[topnew_tmp] # Also need LEFTrow pt with largest LV[1] value topold_tmp = np.where(LVUC[LEFTrow, 1] == max(LVUC[LEFTrow, 1]))[0][0] topold = LEFTrow[topold_tmp] # Add the left half row pts on the boundary using extrapt_inds for pt in extrapt_inds: if LVUC[pt, 1] > LVUC[leftpt, 1] + 1: print 'Pairing extra pt ', pt # Get pair for Lr2 indices not already paired tmp = np.where(np.logical_and(LVUC[:, 1] == LVUC[pt, 1], LVUC[:, 0] == LVUC[pt, 0] + 1))[0][0] xynew = xy[pt, :] - (xy[tmp, :] - xy[pt, :]) xy = np.vstack((xy, xynew)) LVUCnew = LVUC[pt] + np.array([-1, 0, 0]) LVUC = np.vstack((LVUC, LVUCnew)) # Add bonds BL2add = np.array([[pt, len(xy) - 1], [topnew, len(xy) - 1], [topold, len(xy) - 1]]) BL = np.vstack((BL, BL2add)) ################################# # Check if check: plt.plot(xy[:, 0], xy[:, 1], 'bo') plt.scatter(xy[LEFTrow, 0], xy[LEFTrow, 1], c='r', marker='^') # plt.scatter(xy[RIGHTrow,0], xy[RIGHTrow,1], c='g', marker='s') for i in range(len(xy[:, 0])): plt.text(xy[i, 0], xy[i, 1], str(LVUC[i, 0]) + ', ' + str(LVUC[i, 1])) plt.title('After adding one row') plt.show() ################################# # Add the right half row # Rl2 = Rl2[RlINDs] # xynew = np.mean([ xy[RIGHTrow,:], xy[Rl2,:] ], axis=0) # xy = np.vstack((xy,xynew)) # LVUC = np.vstack(( LVUC, LVUCnewRrow )) # CUT BONDS rows2cut = [] for ind in LEFTrow: # Get bonds between LEFTrow and particle +LV[0] or +LV[1] matches = np.where(np.logical_or(np.logical_and(LVUC[Lr2, 0] == LVUC[ind, 0] + 2, LVUC[Lr2, 1] == LVUC[ind, 1]), np.logical_and(LVUC[Lr2, 0] == LVUC[ind, 0] + 1, LVUC[Lr2, 1] == LVUC[ind, 1] + 1) ))[0] matchind = Lr2[matches] # Kill (ind, matches) pairs in BL for match in matchind: try: row2cut_ii = np.where(np.logical_or(np.logical_and(BL[:, 0] == ind, BL[:, 1] == match), np.logical_and(BL[:, 1] == ind, BL[:, 0] == match)))[0][0] print 'row2cut_ii = ', row2cut_ii rows2cut += [row2cut_ii] except: print 'no matching row to cut for index = ', match # Check if check: print 'matches = ', matches print 'matchind = ', matchind le.display_lattice_2D(xy, BL, title='checking bonds to cut (btwn green and red pts)', colorz=False, close=False); plt.plot(xy[:, 0], xy[:, 1], 'b.') plt.plot(xy[matchind, 0], xy[matchind, 1], 'ro') plt.plot(xy[ind, 0], xy[ind, 1], 'g^') plt.show() # # if Bvec == 'SouthWest' or Bvec == 'SW': # print 'Since Bvec is SW, killing one more bond... \n' # # For left point (leftpt), kill northeast bond # matches = np.where( np.logical_and( LVUC[Lr2,0] == LVUC[leftpt,0] , \ # LVUC[Lr2,1] == LVUC[leftpt,1]+1) )[0] # # matchind = Lr2[matches] # row2cut_ii = [np.where(np.logical_or(np.logical_and( BL[:,0] == leftpt, BL[:,1] == match), # np.logical_and(BL[:,1] == leftpt, BL[:,0] == match)))[0][0] for match in matchind] # rows2cut += row2cut_ii # # # Check # if check: # print 'matches = ', matches # print 'matchind = ', matchind # le.display_lattice_2D(xy,BL,colorz=False,close=False); plt.plot(xy[:,0], xy[:,1],'b.'); plt.plot(xy[matchind,0], xy[matchind,1],'ro'); plt.plot(xy[ind,0], xy[ind,1],'g^') # plt.show() keep = np.ones(len(BL), dtype=bool) keep[rows2cut] = False BL = BL[keep, :] # Add new bonds # BL2add = np.zeros((len(LaddIND)*5-1,2), dtype = int) BL2add = [] for ii in range(len(LaddIND)): new = LaddIND[ii] # Add new horizontal bonds # add bond o----x o BL2add.append([LEFTrow[ii], new]) # add bond o x----o BL2add.append([Lr2add[ii], new]) print 'added BL2add entry ', 4 * ii + 1 # Add new vertical bonds # get particle below if new == lowest_new_pt: print 'Attempting to add bond for lowest point ...' try: below = np.where(np.logical_and(LVUC[:, 0] == LVUC[new, 0] + 1, LVUC[:, 1] == LVUC[new, 1] - 1))[0][0] BL2add.append([below, new]) except: print '... Lowest point is on bottom row, no points below to bond with.' else: below = np.where(np.logical_and(LVUC[:, 0] == LVUC[new, 0], LVUC[:, 1] == LVUC[new, 1] - 1))[0][0] BL2add.append([below, new]) # get particle above try: above = np.where(np.logical_and(LVUC[:, 0] == LVUC[new, 0], LVUC[:, 1] == LVUC[new, 1] + 1))[0][0] BL2add.append([above, new]) except: print '... no particle above.' # check if check: le.display_lattice_2D(xy, np.vstack((BL, BL2add)), title='Unrelaxed dislocated lattice', colorz=False, close=False) for i in range(len(xy[:, 0])): plt.text(xy[i, 0], xy[i, 1] + 0.1, '(' + str(LVUC[i, 0]) + ', ' + str(LVUC[i, 1]) + ')') plt.show() ii = 0 for new in LaddIND[0:len(LaddIND) - 1]: # new = LaddIND[ii] print 'adding cconnection between added pts...' BL2add.append([new, new + 1]) ii += 1 # Cut off parts of BL2add that weren't used print 'ii = ', ii print '4*len(LaddIND)+ii+1 = ', 4 * len(LaddIND) + ii + 1 print 'len(LaddIND)*5-1 = ', len(LaddIND) * 5 - 1 # if 4*len(LaddIND)+ii < (len(LaddIND)*5): BL2add = np.array(BL2add) # print 'BL2add = ', BL2add BL = np.vstack((BL, BL2add)) # print 'BL in adding West Bvec= ', BL # Check if check: le.display_lattice_2D(xy, BL, title='Unrelaxed dislocated lattice', colorz=False, close=False) # for i in range(len(xy)): # plt.text(xy[i,0]+0.05, xy[i,1]+0.05, str(LVUC[i])) plt.show() # bU = potential_energy(xy,BL,bo=1.,kL=1.) NP = len(xy) kL = 1. if bo == 'centroid': bo = 1. / (np.sqrt((1. / 3. * np.cos(np.pi / 3.) - 2. / 3.) ** 2 + (1. / 3. * np.sin(np.pi / 3.)) ** 2)) else: bo = bo def flattened_potential_energy(xy): # We convert xy to a 2D array here. xy = xy.reshape((-1, 2)) bL = le.bond_length_list(xy, BL) bU = 0.5 * sum(kL * (bL - bo) ** 2) return bU if relax_lattice: # Relax lattice, but fix pts with low LV[1] vals # First get ADJACENT pts with low LV[1] values to fix fix_candidates = np.where(LVUC[:, 1] == np.min(LVUC[:, 1]))[0] # Grab particle with min abs(x) value from fix_candidates fix0_ind = np.argmin(xy[fix_candidates, 0]) fix0 = fix_candidates[fix0_ind] print 'fix0 = ', fix0 # look at all the other particles (not particle fix_candidates[i]) inds_noti = np.setdiff1d(np.arange(len(fix_candidates)), np.array([fix0_ind])) inds = fix_candidates[inds_noti] # Get index of a particle next to fix0 that is one bond away getequal = np.where(np.logical_and(LVUC[inds, 1] == LVUC[fix0, 1], np.abs(LVUC[inds, 0] - LVUC[fix0, 0]) == 1))[0] print 'getequal = ', getequal if len(getequal) > 1: print '\n there is more than one...' getequal2 = np.argmin(xy[getequal, 0])[0] print 'getequal = ', getequal equalIND = getequal[getequal2] print 'equalIND = ', equalIND else: equalIND = getequal[0] print 'inds = ', inds if fix0 < inds[equalIND]: pair = [fix0, inds[equalIND]] else: pair = [inds[equalIND], fix0] Nzero_pair0 = np.arange(0, pair[0]) Npair0_pair1 = np.arange(pair[0], pair[1]) Npair1_end = np.arange(pair[1], NP) print 'pair = ', pair bounds = [[None, None]] * (2 * (pair[0])) + \ np.c_[xy[pair[0], :].ravel(), xy[pair[0], :].ravel()].tolist() + \ [[None, None]] * (2 * (pair[1] - pair[0] - 1)) + \ np.c_[xy[pair[1], :].ravel(), xy[pair[1], :].ravel()].tolist() + \ [[None, None]] * (2 * (NP - pair[1] - 1)) # Old way: fix particles 0 and 1 # bounds = np.c_[xy[:2,:].ravel(), xy[:2,:].ravel()].tolist() + \ # [[None, None]] * (2*(NP-2)) # relaxed lattice print 'relaxing lattice...' xyR = opt.minimize(flattened_potential_energy, xy.ravel(), method='L-BFGS-B', bounds=bounds, tol=tol).x.reshape((-1, 2)) xy = xyR bL0 = bo * np.ones_like(BL[:, 0], dtype=float) if check: bs = le.bond_strain_list(xy, BL, bL0) le.display_lattice_2D(xyR, BL, bs=bs, title='Relaxed dislocated lattice', colorz=False, close=False) plt.scatter(xy[pair, 0], xy[pair, 1], s=500, c='r') plt.show() if relax_twice: # Kick lattice, relax again, fixing pts far from 0 and 1 # Fix pair of particles near top of sample # first grab lowest particle fix0 = np.argmax(xy[:, 1]) found = tree.query(xy[fix0], k=2)[1] print 'found =', found print 'tree.query(xy[fix0], k=2) = ', tree.query(xy[fix0], k=2) print 'found partners for second relaxing => fix0 =', fix0, ' and ', found[1] pair = [fix0, found[1]] # If for some reason found[1] == fix0, choose a different particle in found if fix0 == found[1]: print 'found[0] = ', found[0] pair = [fix0, found[0]] Nzero_pair0 = np.arange(0, pair[0]) Npair0_pair1 = np.arange(pair[0], pair[1]) Npair1_end = np.arange(pair[1], NP) print 'pair = ', pair bounds = [[None, None]] * (2 * (pair[0])) + \ np.c_[xy[pair[0], :].ravel(), xy[pair[0], :].ravel()].tolist() + \ [[None, None]] * (2 * (pair[1] - pair[0] - 1)) + \ np.c_[xy[pair[1], :].ravel(), xy[pair[1], :].ravel()].tolist() + \ [[None, None]] * (2 * (NP - pair[1] - 1)) # Kick particles that are not fixed during relaxation kick = 0.0001 * np.random.rand(NP, 2) kick[fix0] = [0., 0.] kick[found] = [0., 0.] xy += kick print 'relaxing lattice again...' xyR = opt.minimize(flattened_potential_energy, xy.ravel(), method='L-BFGS-B', bounds=bounds, tol=tol * 0.1).x.reshape((-1, 2)) xy = xyR if check: bs = le.bond_strain_list(xy, BL, bL0) le.display_lattice_2D(xyR, BL, bs=bs, title='Twice Relaxed dislocated lattice', colorz=False, close=False) plt.scatter(xy[NP - 2:NP, 0], xy[NP - 2:NP, 1], s=500, c='r') plt.show() return xy, LVUC, BL
def build_accordionkag_hucent(lp): """Create an accordion-bonded kagomized amorphous network from a loaded hyperuniform point set. Parameters ---------- lp Returns ------- """ print('Loading hyperuniform to build lattice...') networkdir = lp['rootdir'] + 'networks/' shape = lp['shape'] NH = lp['NH'] NV = lp['NV'] check = lp['check'] if lp['NP_load'] == 0: points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N400/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) + lp['origin'] addpc = .05 xytmp, trash1, trash2, trash3 = blf.mask_with_polygon(shape, NH + 4, NV + 4, points, [], eps=addpc) polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) xy, NL, KL, BL = le.delaunay_centroid_lattice_from_pts( xytmp, polygon=polygon, trimbound=False) # check=check) ################################################################# # nzag controlled by lp['intparam'] below xyacc, BLacc, LVUC, UC, xyvertices, lattice_exten_add = \ blf.accordionize_network(xy, BL, lp, PVxydict=None, PVx=None, PVy=None, PV=None) print 'BL = ', BL # need indices of xy that correspond to xyvertices # note that xyvertices gives the positions of the vertices, not their indices inRx = np.in1d(xyacc[:, 0], xyvertices[:, 0]) inRy = np.in1d(xyacc[:, 1], xyvertices[:, 1]) vxind = np.where(np.logical_and(inRx, inRy))[0] print 'vxind = ', vxind # Note: beware, do not provide NL and KL to decorate_bondneighbors_elements() since NL,KL need # to be recalculated xy, BL = blf.decorate_bondneighbors_elements(xyacc, BLacc, vxind, PVxydict=None, viewmethod=False, check=lp['check']) NL, KL = le.BL2NLandKL(BL, NP=len(xy)) ################################################################# polygon = blf.auto_polygon(shape, NH, NV, eps=0.00) if check: le.display_lattice_2D( xy, BL, NL=NL, KL=KL, title='Cropped centroid lattice, before dilation') # Form output bounding box and extent measurement LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict = {} PVx = [] PVy = [] BBox = polygon # make string from origin values print 'lp[origin] = ', lp['origin'] print 'type(lp[origin]) = ', type(lp['origin']) if (np.abs(lp['origin']) < 1e-7).all(): originstr = '' else: originstr = '_originX' + '{0:0.2f}'.format(lp['origin'][0]).replace('.', 'p') + \ 'Y' + '{0:0.2f}'.format(lp['origin'][1]).replace('.', 'p') periodicBCstr = '' else: # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) LL = (lp['NP_load'], lp['NP_load']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + \ str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) xy, NL, KL, BL, PVxydict = blf.kagomecentroid_periodic_network_from_pts( points, LL, BBox=BBox, check=lp['check']) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicBCstr = '_periodic' # 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 polygon *= scale BBox *= scale LL = (LL[0] * scale, LL[1] * scale) if lp['periodicBC']: PVx *= scale PVy *= scale PVxydict.update((key, val * scale) for key, val in PVxydict.items()) lattice_exten = 'accordionkag_hucent_' + shape + periodicBCstr + '_d{0:02d}'.format(int(lp['conf'])) + originstr + \ lattice_exten_add LV = 'none' LVUC = 'none' UC = 'none' return xy, NL, KL, BL, PVxydict, PVx, PVy, LL, LVUC, LV, UC, BBox, lattice_exten
'polygon2': polygon2, 'polygon3': polygon3, # 'reg1_xy': reg1_xy, 'reg2_xy': reg2_xy, 'reg3_xy': reg3_xy } fn = dataNdir + 'params_regs_ksize{0:0.3f}'.format(ksize_frac) + '.txt' header = 'Region 1 indices for lattice division, ksize=(' + \ '{0:0.5f}'.format(ksize_frac * NH.astype(float)) + ', ' + \ '{0:0.5f}'.format(ksize_frac * NV.astype(float)) + ') ' + shape le.save_dict(regions, fn, header=header) if save_ims: plt.clf() ax = le.display_lattice_2D(xy, BL, bs='none', close=False, colorz=False, colormap='BlueBlackRed', bgcolor='#FFFFFF', axis_off=True) ax.scatter(xy[reg1, 0], xy[reg1, 1], c='r', s=80, marker='o', alpha=0.3, label='reg1', zorder=100) ax.scatter(xy[reg2, 0], xy[reg2, 1], c='g', s=80,
def build_huvoronoi(lp): if lp['NP_load'] == 0: points = np.loadtxt( lp['rootdir'] + 'networks/hyperuniform_source/hyperuniform_N400/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) + lp['origin'] keep = np.logical_and( abs(points[:, 0]) < (8 + lp['NH'] * 0.5), abs(points[:, 1]) < (8 + lp['NV'] * 0.5)) xytmp = points[keep] if lp['check']: plt.plot(points[:, 0], points[:, 1], 'b.') plt.title('Point set before initial cutting') plt.show() polygon = blf.auto_polygon(lp['shape'], lp['NH'], lp['NV'], eps=0.00) xy, NL, KL, BL = le.voronoi_lattice_from_pts(xytmp, polygon=polygon, NN=3, kill_outliers=True, check=lp['check']) if lp['check']: le.display_lattice_2D( xy, BL, NL=NL, KL=KL, title='Cropped centroid lattice, before dilation') # Form output bounding box and extent measurement LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict = {} PVx = [] PVy = [] BBox = polygon # make string from origin values print 'lp[origin] = ', lp['origin'] print 'type(lp[origin]) = ', type(lp['origin']) if (np.abs(lp['origin']) < 1e-7).all(): originstr = '' else: originstr = '_originX' + '{0:0.2f}'.format(lp['origin'][0]).replace('.', 'p') + \ 'Y' + '{0:0.2f}'.format(lp['origin'][1]).replace('.', 'p') periodicstr = '' else: lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) print 'sizestr = ', sizestr points = np.loadtxt(lp['rootdir'] + 'networks/hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + str(int(lp['conf'])) + '_xy.txt') print 'points = ', points points -= np.mean(points, axis=0) # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) LL = (lp['NP_load'], lp['NP_load']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon xy, NL, KL, BL, PVxydict = le.voronoi_rect_periodic_from_pts( points, LL, BBox='auto', check=lp['check']) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicstr = '_periodic' # 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 polygon *= scale BBox *= scale LL = (LL[0] * scale, LL[1] * scale) if lp['NP_load'] != 0: PVx *= scale PVy *= scale PVxydict.update((key, val * scale) for key, val in PVxydict.items()) lattice_exten = 'huvoronoi_' + lp[ 'shape'] + periodicstr + '_d' + '{0:02d}'.format(int( lp['conf'])) + originstr return xy, NL, KL, BL, PVx, PVy, PVxydict, LL, BBox, lattice_exten
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
KL = (KLload).astype(np.intc) NP = np.shape(KL)[0] NN = np.shape(KL)[1] print '\nNP = ', NP BL = le.NL2BL(NL, KL) NLNNN, KLNNN, A = haldane_lattice_functions.haldane_matrix(xy, NL, KL, BL, epsilon=epsilon) BLNNN = le.NL2BL(NLNNN, KLNNN) # print 'KLNNN =', KLNNN # print 'NLNNN =', NLNNN le.display_lattice_2D(xy, BL, BLNNN=BLNNN, NLNNN=NLNNN, KLNNN=KLNNN, labelinds=True) print '\n\n checking A - np.dot(U,np.dot(D,U1)) in plot... ' plt.plot(np.arange(len(A)), A - np.dot(U, np.dot(D, U1))) plt.title('A - np.dot(U,np.dot(D,U1)) --> should be zero') plt.show() # Let M be A with zeros where omega>band1 (or omega<band2) M = copy.deepcopy(D) print 'np.count_nonzero(M) = ', np.count_nonzero(M) plt.plot(np.arange(len(M.ravel())), np.imag(M.ravel()), 'b.', label='imaginary part')
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 build_hucentroid(lp): """Load the proper hyperuniform point set, given the parameters in dict lp Parameters ---------- lp : dict lattice parameters dictionary Returns ------- xy, NL, KL, BL, PVxydict, PVx, PVy, LVUC, BBox, LL, LV, UC, lattice_exten """ check = lp['check'] networkdir = lp['rootdir'] + 'networks/' print('Loading hyperuniform to build lattice...') if lp['NP_load'] == 0: points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N400/out_d' + str(int(lp['conf'])) + '_xy.txt') points -= np.mean(points, axis=0) + lp['origin'] addpc = .05 # Note: below we crop a large region so that if the network has shape==circle, we dont cut off the sides if lp['shape'] == 'circle': keep = np.logical_and( abs(points[:, 0]) < (10 + lp['NH'] * (1 + addpc)), abs(points[:, 1]) < (10 + lp['NV'] * (1 + addpc))) else: # it will speed things up to crop more, so do so if the shape is not a circle keep = np.logical_and( abs(points[:, 0]) < (5 + lp['NH'] * (1 + addpc) * 0.5), abs(points[:, 1]) < (5 + lp['NV'] * (1 + addpc)) * 0.5) xytmp = points[keep] if check: plt.plot(points[:, 0], points[:, 1], 'b.') plt.title('Point set before initial cutting') plt.show() polygon = blf.auto_polygon(lp['shape'], lp['NH'], lp['NV'], eps=0.00) xy, NL, KL, BL = le.delaunay_centroid_lattice_from_pts(xytmp, polygon=polygon, trimbound=False, check=check) if check: le.display_lattice_2D( xy, BL, NL=NL, KL=KL, title='Cropped centroid lattice, before dilation') # Form output bounding box and extent measurement LL = (np.max(xy[:, 0]) - np.min(xy[:, 0]), np.max(xy[:, 1]) - np.min(xy[:, 1])) PVxydict = {} PVx = [] PVy = [] BBox = polygon # make string from origin values print 'lp[origin] = ', lp['origin'] print 'type(lp[origin]) = ', type(lp['origin']) if (np.abs(lp['origin']) < 1e-7).all(): originstr = '' else: originstr = '_originX' + '{0:0.2f}'.format(lp['origin'][0]).replace('.', 'p') + \ 'Y' + '{0:0.2f}'.format(lp['origin'][1]).replace('.', 'p') periodicstr = '' stripstr = '' else: if lp['periodic_strip']: lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) print 'sizestr = ', sizestr points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + str(int(lp['conf'])) + '_xy.txt') print 'points = ', points points -= 0.5 * np.array([lp['NH'], lp['NV']]) # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) if lp['NH'] != lp['NP_load']: raise RuntimeError( 'NP_load should be equal to NH for a periodicstrip geometry!' ) LL = (lp['NH'], lp['NV']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon keep = dh.inds_in_polygon(points, polygon) points = points[keep] xy, NL, KL, BL, PVxydict = le.delaunay_centroid_periodicstrip_from_pts( points, LL, BBox='auto', check=check) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicstr = '_periodicstrip' stripstr = '_NH{0:06d}'.format(lp['NH']) + '_NV{0:06d}'.format( lp['NV']) else: lp['periodicBC'] = True sizestr = '{0:03d}'.format(lp['NP_load']) print 'sizestr = ', sizestr points = np.loadtxt(networkdir + 'hyperuniform_source/hyperuniform_N' + sizestr + '/out_d' + str(int(lp['conf'])) + '_xy.txt') print 'points = ', points points -= np.mean(points, axis=0) # Ensuring that origin param is centered (since using entire lattice) lp['origin'] = np.array([0.0, 0.0]) LL = (lp['NP_load'], lp['NP_load']) polygon = 0.5 * np.array([[-LL[0], -LL[1]], [LL[0], -LL[1]], [LL[0], LL[1]], [-LL[0], LL[1]]]) BBox = polygon xy, NL, KL, BL, PVxydict = le.delaunay_centroid_rect_periodic_network_from_pts( points, LL, BBox='auto', check=check) PVx, PVy = le.PVxydict2PVxPVy(PVxydict, NL) originstr = '' periodicstr = '_periodic' stripstr = '' # 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 polygon *= scale BBox *= scale LL = (LL[0] * scale, LL[1] * scale) if lp['NP_load'] != 0: PVx *= scale PVy *= scale PVxydict.update((key, val * scale) for key, val in PVxydict.items()) lattice_exten = 'hucentroid_' + lp['shape'] + periodicstr + '_d' +\ '{0:02d}'.format(int(lp['conf'])) + stripstr + originstr LVUC = 'none' LV = 'none' UC = 'none' return xy, NL, KL, BL, PVxydict, PVx, PVy, LVUC, BBox, LL, LV, UC, lattice_exten