Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
def generate_overcoordinated1_lattice_trip(NH, NV, ui, si, Co, CBLo):
    """
    Moves the points of the weird lattice around to get bonds that a normal triangulation would miss.
    Parameters
    ----------
    NH : int
        Number of pts along horizontal before boundary is cut
    NV : int

    Returns
    ----------
    BL : array of dimension #bonds x 2
        Each row is a bond and contains indices of connected points
    """
    print('Setting up unit cell...')
    a0 = 2*np.array([[np.cos(n*np.pi/3+np.pi/6), np.sin(n*np.pi/3+np.pi/6), 0] for n in range(6)])

    a = np.array([a0[:,0], a0[:,1]]).T
    A = np.array([0,0])
    C = np.array([np.cos(-10*np.pi/180), np.sin(-10*np.pi/180)])
    B = 0.5*np.array([np.cos(90*np.pi/180), np.sin(90*np.pi/180)])

    An = A+ a
    Bn = B+a
    Cn = C+a

    nA = np.array([B-A, B+a[3]-A, B+a[4]-A, C-A, C+a[2]-A])
    angsA = np.array([np.arctan2(nA[i,1], nA[i,0]) for i in range(len(nA))])

    nB = np.array([A-B, A+a[0]-B, A+a[1]-B, C-B, C+a[1]-B])
    angsB = np.array([np.arctan2(nB[i,1], nB[i,0]) for i in range(len(nB))])

    nC = np.array([A-C, A+a[5]-C, B-C, B+a[4]-C])
    angsC = np.array([np.arctan2(nC[i,1], nC[i,0]) for i in range(len(nC))])

    aa = a.copy()
    a1 = aa[1]
    a2 = aa[2]
    a3 = aa[3]

    # nodes at R
    C = np.array([A,  # 0
               B,     # 1
               B+a[3],  # 2
               B+a[4],  # 3
               C,     # 4
               C+a[2],  # 5

               #A
               A+a[0], #6
               A+a[1], #7
               #C, #4
               C+a[1],#8

               #A
               A+a[5],#9
               #B,#1
               #B+a[4]#3

        ])

    CBL = np.array([[0, 1],
                    [0, 2],
                    [0, 3],
                    [0, 4],
                    [0, 5],
                    [1, 6],
                    [1, 7],
                    [1, 4],
                    [1, 8],
                    [3, 4],
                    [4, 9]])

    # translate by Bravais latt vecs
    print('Translating by Bravais lattice vectors...')
    print('Translating by Bravais lattice vectors...')
    LV = [-a2-a3, a1]
    inds = np.arange(len(C))
    tmp0 = np.zeros(len(C), dtype='int')
    tmp1 = np.ones(len(C), dtype='int')
    for i in np.arange(NV):
        for j in np.arange(NH):
            # bottom row
            if i == 0:
                if j == 0 :
                    R = C
                else:
                    R = np.vstack((R, C + j*LV[0]))
            else:
                # vertical indices to copy over
                vinds = np.array([1, 2, 5, 6, 7, 8])
                R = np.vstack((R, C[vinds] + j*LV[0] + i*LV[1]))

    print('Eliminating repeated points...')
    # ui = le.unique_rows_index(R)

    R = R[si]
    xy = R[ui]
    # Triangulate
    print('Triangulating...')
    Dtri = Delaunay(xy)
    btri = Dtri.vertices

    # translate btri --> bond list
    BL = le.Tri2BL(btri)
    # BL = latticevec_filter(BL,xy, Co, CBLo)

    # fig = plt.figure()
    # plt.triplot(xy[:,0], xy[:,1], Dtri.simplices.copy())
    # plt.xlim(-10,10)
    # plt.ylim(-10,10)
    # plt.show()

    return BL
Ejemplo n.º 4
0
def generate_overcoordinated1_lattice(NH, NV, shape='square', check=False):
    """Generates a lattice with a made-up unit cell that is overcoordinated.

    Parameters
    ----------
    NH : int
        Number of pts along horizontal before boundary is cut
    NV : int

    Returns
    ----------
    xy : array of dimension nx3
        Equilibrium positions of all the points for the lattice
    NL : array of dimension n x (max number of neighbors)
        Each row corresponds to a point.  The entries tell the indices of the neighbors.
    KL : array of dimension n x (max number of neighbors)
        Correponds to NL matrix.  1 corresponds to a true connection while 0 signifies that there is not a connection
    BL : array of dimension #bonds x 2
        Each row is a bond and contains indices of connected points
    SBL : NP x 1 int array
        Sublattice bond list: 0, 1, 2 for each site of the 3-particle unit cell
    lattice_type : string
        label, lattice type.  For making output directory: for ex, 'overcoordinated1_square'

    """
    print('Setting up unit cell...')
    a0 = 2*np.array([[np.cos(n*np.pi/3+np.pi/6), np.sin(n*np.pi/3+np.pi/6), 0] for n in range(6)])

    a = np.array([a0[:, 0], a0[:, 1]]).T
    A = np.array([0, 0])
    C = np.array([np.cos(-10*np.pi/180), np.sin(-10*np.pi/180)])
    B = 1.2*np.array([np.cos(20*np.pi/180), np.sin(20*np.pi/180)])

    An = A+ a
    Bn = B+a
    Cn = C+a

    nA = np.array([B-A, B+a[3]-A, B+a[4]-A, C-A, C+a[2]-A])
    angsA = np.array([np.arctan2(nA[i, 1], nA[i, 0]) for i in range(len(nA))])

    nB = np.array([A-B, A+a[0]-B, A+a[1]-B, C-B, C+a[1]-B])
    angsB = np.array([np.arctan2(nB[i, 1], nB[i, 0]) for i in range(len(nB))])

    nC = np.array([A-C, A+a[5]-C, B-C, B+a[4]-C])
    angsC = np.array([np.arctan2(nC[i,1], nC[i,0]) for i in range(len(nC))])

    aa = a.copy()
    print 'aa = ', aa
    a1 = aa[1]
    a2 = aa[2]
    a3 = aa[3]

    # nodes at R
    C = np.array([A,#0
                  B,  # 1
                  B + a[3],  # 2
                  B + a[4],  # 3
                  C,  # 4
                  C + a[2],  # 5
                  A+a[0],  # 6
                  A+a[1],  # 7
                  C+a[1],  # 8
                  A+a[5],  # 9

        ])
    CU = np.arange(len(C), dtype='int')

    sbl = np.array([0,#0
               1,#1
               1,#2
               1,#3
               2,#4
               2,#5

               #A
               0, #6
               0, #7
               #C, #4
               2,#8

               #A
               0,#9
               #B,#1
               #B+a[4]#3

        ])

    CBL = np.array([
        [0, 1],
        [0, 2],
        [0, 3],
        [0, 4],
        [0, 5],
        [1, 6],
        [1, 7],
        [1, 4],
        [1, 8],
        [3, 4],
        [4, 9]
        ])

    # translate by Bravais latt vecs
    print('Translating by Bravais lattice vectors...')
    LV  = [-a2-a3, a1]
    inds = np.arange(len(C))
    tmp0 = np.zeros(len(C), dtype='int')
    tmp1 = np.ones(len(C), dtype='int')
    print 'sbl = ', sbl
    for i in np.arange(NV):
        for j in np.arange(NH):
            # bottom row
            if i == 0:
                if j == 0 :
                    Bprev = C
                    R = C
                    SBL = sbl.tolist()
                    LVUC = np.dstack((tmp0, tmp0, CU))[0]

                    # # Check
                    # colorvals = np.linspace(0,1,len(R))
                    # #plt.plot(R[:,0],R[:,1], 'k-') #,c=colorvals, cmap='spectral')
                    # le.display_lattice_2D(R,CBL,close=False)
                    # for ii in range(len(R)):
                    #     plt.text(R[ii,0]+0.05,R[ii,1],str(ii))
                    # plt.arrow(0, 0, a1[0], a1[1], head_width=0.05, head_length=0.1, fc='r', ec='r')
                    # plt.arrow(0, 0, a2[0], a2[1], head_width=0.05, head_length=0.1, fc='b', ec='b')
                    # plt.arrow(0, 0, a3[0], a3[1], head_width=0.05, head_length=0.1, fc='g', ec='g')
                    # plt.show()
                else:
                    R = np.vstack((R, C + j*LV[0]))
                    SBL += sbl.tolist() # np.vstack((SBL, sbl))

                    LVUCadd = np.dstack((j*tmp1, tmp0, CU))[0]
                    # print 'LVUCadd = ', LVUCadd
                    LVUC = np.vstack((LVUC, LVUCadd))

                    # # Check
                    # colorvals = np.linspace(0,1,len(R))
                    # plt.scatter(R[:,0],R[:,1],c=colorvals, cmap='spectral')
                    # for ii in range(len(R)):
                    #     plt.text(R[ii,0]+0.05,R[ii,1],str(ii))
                    # plt.arrow(0, 0, a1[0], a1[1], head_width=0.05, head_length=0.1, fc='r', ec='r')
                    # plt.arrow(0, 0, a2[0], a2[1], head_width=0.05, head_length=0.1, fc='b', ec='b')
                    # plt.arrow(0, 0, a3[0], a3[1], head_width=0.05, head_length=0.1, fc='g', ec='g')
                    # plt.pause(1)
            else:
                # vertical indices to copy over
                vinds = np.array([1,2,5,6,7,8])
                R = np.vstack((R, C[vinds] + j*LV[0] + i*LV[1]))
                SBL += sbl[vinds].tolist()
                LVUCadd = np.dstack((j*tmp1[vinds],i*tmp1[vinds],CU[vinds] ))[0]
                # print 'LVUCadd = ', LVUCadd
                LVUC = np.vstack((LVUC,LVUCadd))

                # # Check
                # sizevals = np.arange(len(R))+10
                # colorvals = np.linspace(0,1,len(R))
                # plt.scatter(R[:,0],R[:,1],s=sizevals,c=colorvals, cmap='afmhot')
                # for ii in range(len(R)):
                #     plt.text(R[ii,0]+0.05,R[ii,1],str(ii))
                # plt.arrow(0, 0, a1[0], a1[1], head_width=0.05, head_length=0.1, fc='r', ec='r')
                # plt.arrow(0, 0, a2[0], a2[1], head_width=0.05, head_length=0.1, fc='b', ec='b')
                # plt.arrow(0, 0, a3[0], a3[1], head_width=0.05, head_length=0.1, fc='g', ec='g')
                # plt.show()
        # if i%2 ==0:
        #     Bprev = Bprev + a2
        # else:
        #     Bprev = Bprev + a3

    SBL = np.asarray(SBL)
    # get rid of repeated points
    print('Eliminating repeated points...')
    #########
    # check
    if check:
        plt.clf()
        sizevals = np.arange(len(R))+10
        colorvals = np.linspace(0,1,len(R))
        plt.scatter(R[:,0],R[:,1],s=sizevals,c=colorvals, cmap='afmhot', alpha=0.2)
        plt.show()
    #########
    print 'R = ', R
    print 'shape(R) = ', np.shape(R)
    R, si, ui = le.args_unique_rows_threshold(R, 0.01)
    print 'shape(R) = ', np.shape(R)
    #########
    # check
    if check:
        sizevals = np.arange(len(R))+50
        colorvals = np.linspace(0, 1, len(R))
        plt.scatter(R[:, 0], R[:, 1], s=sizevals, c=colorvals, cmap='afmhot', alpha=0.2)
        plt.show()
    #########
    BL2 = generate_overcoordinated1_lattice_trip(NH, NV, ui, si, C, CBL)
    SBL = SBL.flatten()
    SBL = SBL[si]
    SBL = SBL[ui]
    # get rid of first row (0,0)a
    xy = le.unique_rows_threshold(R, 0.05) - np.array([np.mean(R[1:, 0]), np.mean(R[1:, 1])])

    # xy = R[ui]
    # Triangulate
    print('Triangulating...')
    Dtri = Delaunay(xy)
    btri = Dtri.vertices

    # C = C-np.array([np.mean(R[1:,0]),np.mean(R[1:,1])])
    # fig = plt.figure()
    # plt.triplot(xy[:,0], xy[:,1], Dtri.simplices.copy())
    # plt.xlim(-10,10)
    # plt.ylim(-10, 10)
    # plt.show()

    # translate btri --> bond list
    BL = le.Tri2BL(btri)

    # remove bonds on the sides and through the hexagons
    print('Removing extraneous bonds from triangulation...')
    # calc vecs from C bonds

    BL = np.array(list(BL)+list(BL2))
    BL = le.unique_rows(BL)

    BL = blf.latticevec_filter(BL, xy, C, CBL)

    NL, KL = le.BL2NLandKL(BL,NN=10)

    UC = C
    lattice_exten = 'overcoordinated1_square'
    return xy, NL, KL, BL, SBL, LV, UC, LVUC, lattice_exten
Ejemplo n.º 5
0
def generate_triangular_lattice(shape, NH, NV, periodicBC=False, eta=0., theta=0., check=False):
    """Generate a triangular lattice NH wide and NV tall, with sites randomized by eta and rotated by theta.

    Parameters
    ----------
    shape : dictionary with string key
        key is overall shape of the mesh ('square' 'rectangle2x1' 'rectangle1x2' 'circle' 'hexagon'), value is radius,
        hexagon, sidelength, or array of closed points
    NH : int
        Number of pts along horizontal before boundary is cut
    NV : int
        Number of pts along vertical before boundary is cut
    periodicBC : bool
        make the network periodic
    eta : float
        randomization of the mesh, in units of lattice spacing
    theta : float
        overall rotation of the mesh lattice vectors in radians
    check : bool
        whether to view results at each step
    Returns
    ----------
    xy : array of dimension nx3
        Equilibrium positions of all the points for the lattice
    NL : array of dimension n x (max number of neighbors)
        Each row corresponds to a point.  The entries tell the indices of the neighbors.
    KL : array of dimension n x (max number of neighbors)
        Correponds to NL matrix.  1 corresponds to a true connection while 0 signifies that there is not a connection
    BL : array of dimension #bonds x 2
        Each row is a bond and contains indices of connected points
    LVUC : NP x 4 array
        For each particle, gives (lattice vector, unit cell vector) coordinate position of that particle: LV1, LV2, UC
        For instance, xy[0,:] = LV[0]*LVUC[0,0] + LV[1]*LVUC[0,1] + UC[LVUC[0,2]]
    LV : 3 x 2 float array
        Lattice vectors for the kagome lattice with input twist angle
    UC : 6 x 2 float array
        (extended) unit cell vectors
    lattice_type : string
        label, lattice type.  For making output directory
    """
    # If shape is a string, turn it into the appropriate dict
    if isinstance(shape, str):
        # Since shape is a string, give key as str and vals to form polygon mask
        print 'Since shape is a string, give key as str and vals to form polygon mask...'
        vals = [NH, NV]
        shape_string = shape
        NH *= 3
        NV *= 3
        shape = {shape_string: vals}

    # Establish triangular lattice, rotated by theta
    if abs(theta) < 1e-6:
        latticevecs = [[1, 0], [0.5, np.sqrt(3)*0.5]]
    else:
        latticevecs = [[np.cos(theta), np.sin(theta)],
                       [0.5 * np.cos(theta) - np.sqrt(3) * 0.5 * np.sin(theta),
                        np.sqrt(3) * 0.5 * np.cos(theta) + 0.5 * np.sin(theta)]]

    xypts_tmp, LVUC = blf.generate_lattice_LVUC([NH, NV], latticevecs)

    # CHECK
    if check:
        plt.plot(xypts_tmp[:, 0], xypts_tmp[:, 1], 'b.')
        for i in range(len(xypts_tmp)):
            plt.text(xypts_tmp[i, 0], xypts_tmp[i, 1], str(LVUC[i, 0]) + ', ' + str(LVUC[i, 1]))
        plt.title('Pre-cropped lattice')
        plt.show()

    if theta == 0:
        add_exten = ''
    else:
        add_exten = '_theta' + '{0:.3f}'.format(theta / np.pi).replace('.', 'p') + 'pi'
        # ROTATE BY THETA
        print 'Rotating by theta= ', theta, '...'
        xys = copy.deepcopy(xypts_tmp)
        xypts_tmp = np.array([[x*np.cos(theta) - y*np.sin(theta), y*np.cos(theta)+x*np.sin(theta)] for x, y in xys])

    # mask to rectangle
    if 'circle' in shape:
        '''add masking to shape here'''
        tmp2 = xypts_tmp
        NH, NV = shape['circle']
        # Modify below to allow ovals
        R = NH*0.5
        keep = np.logical_and(np.abs(tmp2[:, 0]) < R*1.000000001, np.abs(tmp2[:, 1]) < (2*R*1.0000001))
        xy = tmp2[keep, :]
        LVUC = LVUC[keep, :]
        shape = 'circle'
    elif 'hexagon' in shape:
        print 'cropping to: ', shape
        tmp2 = xypts_tmp
        NH, NV = shape['hexagon']
        # Modify below to allow different values of NH and NV on the horiz and vertical sides of the hexagon
        a = NH + 0.5
        polygon = np.array([[-a*0.5, -np.sqrt(a**2 - (0.5*a)**2)],
            [a*0.5, -np.sqrt(a**2 - (0.5*a)**2)], [a, 0.],
            [a*0.5, np.sqrt(a**2 - (0.5*a)**2)], [-a*0.5, np.sqrt(a**2 - (0.5*a)**2)], [-a, 0.],
            [-a*0.5, -np.sqrt(a**2 - (0.5*a)**2)]])
        bpath = mplpath.Path(polygon)
        keep = bpath.contains_points(tmp2)
        xy = tmp2[keep, :]
        LVUC = LVUC[keep, :]
        shape = 'hexagon'

        # Check'
        if check:
            codes = [mplpath.Path.MOVETO,
                    mplpath.Path.LINETO,
                    mplpath.Path.LINETO,
                    mplpath.Path.LINETO,
                    mplpath.Path.LINETO,
                    mplpath.Path.LINETO,
                    mplpath.Path.CLOSEPOLY,
                    ]
            path = mplpath.Path(polygon, codes)
            ax = plt.gca()
            patch = mpatches.PathPatch(path, facecolor='orange', lw=2)
            ax.add_patch(patch)
            ax.plot(polygon[:, 0], polygon[:, 1], 'bo')
            ax.plot(xy[:, 0], xy[:, 1], 'r.')
            plt.show()
    elif 'square' in shape:
        tmp2 = xypts_tmp
        NH,NV = shape['square']
        if periodicBC:
            keep = np.logical_and(np.abs(tmp2[:, 0]) < NH * .5 + 0.51,
                                  np.abs(tmp2[:, 1]) < (NV * .5 / np.sin(np.pi / 3.) - 0.1))
        else:
            keep = np.logical_and(np.abs(tmp2[:, 0]) < NH*.5 + 0.1, np.abs(tmp2[:, 1]) < (NV*.5/np.sin(np.pi/3.)+0.1))
        xy = tmp2[keep, :]
        LVUC = LVUC[keep, :]
        shape = 'square'
        pass
    elif 'polygon' in shape:
        bpath = mplpath.Path(shape['polygon'])
        keep = bpath.contains_points(xypts_tmp)
        xy = xypts_tmp[keep, :]
        LVUC = LVUC[keep, :]
        shape = 'polygon'
    else:
        raise RuntimeError('Polygon dictionary not specified in generate_triangular_lattice().')

    print('Triangulating points...\n')
    tri = Delaunay(xy)
    TRItmp = tri.vertices

    print('Computing bond list...\n')
    BL = le.Tri2BL(TRItmp)
    # bL = le.bond_length_list(xy,BL)
    thres = 1.1  # cut off everything longer than a diagonal
    print('thres = ' + str(thres))
    print('Trimming bond list...\n')
    BLtrim = le.cut_bonds(BL, xy, thres)
    print('Trimmed ' + str(len(BL) - len(BLtrim)) + ' bonds.')

    # print 'BLtrim =', BLtrim

    print('Recomputing TRI...\n')
    TRI = le.BL2TRI(BLtrim, xy)

    # Randomize if eta >0 specified
    if eta == 0:
        xypts = xy
        eta_exten = ''
    else:
        print 'Randomizing lattice by eta=', eta
        jitter = eta*np.random.rand(np.shape(xy)[0], np.shape(xy)[1])
        xypts = np.dstack((xy[:, 0] + jitter[:, 0], xy[:, 1] + jitter[:, 1]))[0]
        eta_exten = '_eta{0:.3f}'.format(eta).replace('.', 'p')

    # Naming
    exten = '_' + shape + add_exten + eta_exten

    # BL = latticevec_filter(BL,xy, C, CBL)
    NL, KL = le.BL2NLandKL(BLtrim, NN=6)
    lattice_exten = 'triangular' + exten
    print 'lattice_exten = ', lattice_exten
    LV = np.array(latticevecs)
    UC = np.array([0., 0.])
    return xypts, NL, KL, BLtrim, LVUC, LV, UC, lattice_exten
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
def generate_square_lattice(shape, NH, NV, eta=0., theta=0., check=False):
    """Create a square lattice NH wide and NV tall, with sites randomized by eta and rotated by theta.

    Parameters
    ----------
    shape : string
        overall shape of the mesh: 'circle' 'hexagon' 'square'
    NH : int
        Number of pts along horizontal before boundary is cut
    NV : int
        Number of pts along vertical before boundary is cut
    eta : float
        randomization or jitter in the positions of the particles
    theta : float
        orientation of the lattice vectors (rotation) in units of radians
    check : bool
        Whether to view intermediate results

    Results
    ----------
    """
    # Establish square lattice, rotated by theta

    if abs(theta) < 1e-6:
        latticevecs = [[1., 0.], [0., 1.]]
        # todo: SHOULD MODIFY TO INCLUDE LVUC
        # xypts_tmp, LVUC = generate_lattice_LVUC([NH,NV], latticevecs)
        xypts_tmp = blf.generate_lattice([NH, NV], latticevecs)
    else:
        latticevecs = [[np.cos(theta), np.sin(theta)],
                       [np.sin(theta), np.cos(theta)]]
        xypts_tmp, LVUC = blf.generate_lattice([2 * NH, 2 * NV], latticevecs)
    if NH < 3 and NV < 3:
        if NH == NV == 2:
            xypts_tmp = np.array(
                [[0., 0.],
                 np.array(latticevecs[0]),
                 np.array(latticevecs[1]),
                 np.array(latticevecs[0]) + np.array(latticevecs[1])],
                dtype=float)
            xypts_tmp -= np.mean(xypts_tmp)
        elif NH == 1 and NV == 1:
            '''making single point'''
            xypts_tmp = np.array([[0., 0.]])

    print 'xypts_tmp =', xypts_tmp

    if eta == 0. or eta == '':
        etastr = ''
    else:
        etastr = '_eta{0:.3f}'.format(eta).replace('.', 'p')

    if theta == 0. or theta == '':
        thetastr = ''
    else:
        thetastr = '_theta{0:.3f}'.format(theta / np.pi).replace('.',
                                                                 'p') + 'pi'

    if shape == 'square':
        tmp2 = xypts_tmp  # shorten name for clarity
        xy = tmp2  # [np.logical_and(tmp2[:,0]<(NH) , tmp2[:,1]<NV) ,:]
    elif shape == 'circle':
        print 'assuming NH == NV since cutting out a circle...'
        tmp2 = xypts_tmp  # shorten name for clarity
        xy = tmp2[tmp2[:, 0]**2 + tmp2[:, 1]**2 < NH**2, :]
    elif shape == 'hexagon':
        tmp2 = xypts_tmp  # shorten name for clarity
        # xy = tmp2[tmp2[:,0]**2+tmp2[:,1]**2 < (NH)**2 ,:]
        print 'cropping to: ', shape
        # NH, NV = shape['hexagon']
        # Modify below to allow different values of NH and NV on the horiz and vertical sides of the hexagon
        a = NH + 0.5
        polygon = np.array([[-a * 0.5, -np.sqrt(a**2 - (0.5 * a)**2)],
                            [a * 0.5, -np.sqrt(a**2 - (0.5 * a)**2)], [a, 0.],
                            [a * 0.5, np.sqrt(a**2 - (0.5 * a)**2)],
                            [-a * 0.5, np.sqrt(a**2 - (0.5 * a)**2)], [-a, 0.],
                            [-a * 0.5, -np.sqrt(a**2 - (0.5 * a)**2)]])
        bpath = mplpath.Path(polygon)
        keep = bpath.contains_points(tmp2)
        xy = tmp2[keep]

        # Check'
        if check:
            codes = [
                mplpath.Path.MOVETO,
                mplpath.Path.LINETO,
                mplpath.Path.LINETO,
                mplpath.Path.LINETO,
                mplpath.Path.LINETO,
                mplpath.Path.LINETO,
                mplpath.Path.CLOSEPOLY,
            ]
            path = mplpath.Path(polygon, codes)
            ax = plt.gca()
            patch = mpatches.PathPatch(path, facecolor='orange', lw=2)
            ax.add_patch(patch)
            ax.plot(polygon[:, 0], polygon[:, 1], 'bo')
            ax.plot(tmp2[:, 0], tmp2[:, 1], 'r.')
            plt.show()
    else:
        xy = xypts_tmp

    print('Triangulating points...\n')
    print 'xy =', xy

    tri = Delaunay(xy)
    TRItmp = tri.vertices

    print('Computing bond list to remove cross braces...\n')
    BL = le.Tri2BL(TRItmp)
    thres = np.sqrt(2.0) * .99  # cut off everything as long as a diagonal
    print('thres = ' + str(thres))
    print('Trimming bond list...\n')
    orig_numBL = len(BL)
    BL = le.cut_bonds(BL, xy, thres)
    print('Trimmed ' + str(orig_numBL - len(BL)) + ' bonds.')

    # print('Recomputing TRI...\n')
    # TRI = le.BL2TRI(BL, xy)

    # Randomize by eta
    if eta == 0:
        xypts = xy
    else:
        print 'Randomizing lattice by eta=', eta
        jitter = eta * np.random.rand(np.shape(xy)[0], np.shape(xy)[1])
        xypts = np.dstack(
            (xy[:, 0] + jitter[:, 0], xy[:, 1] + jitter[:, 1]))[0]

    # Naming
    exten = '_' + shape + etastr + thetastr

    # BL = latticevec_filter(BL,xy, C, CBL)
    NL, KL = le.BL2NLandKL(BL, NN=4)
    lattice_exten = 'square' + exten
    print 'lattice_exten = ', lattice_exten
    return xypts, NL, KL, BL, lattice_exten