Exemple #1
0
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
Exemple #2
0
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
Exemple #3
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
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #10
0
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
Exemple #13
0
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
Exemple #14
0
            '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,
Exemple #15
0
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
Exemple #16
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
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')
Exemple #18
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
Exemple #19
0
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