def aspect_ratio():
    D_arr = np.exp(np.linspace(np.log(100e-6), np.log(3000e-6), 100))
    with open("../aggregation/dendrite_grid.dat") as f:
        grid = pickle.load(f)
    rot = rotator.UniformRotator()
    grid_res = 40.0e-6

    def ar(D):
        cry = crystal.Dendrite(D, hex_grid=grid)
        gen = generator.MonodisperseGenerator(cry, rot, grid_res)
        agg = aggregate.Aggregate(gen)

        m = agg.X.mean(0)
        X_c = agg.X - m
        cov = np.dot(X_c.T, X_c)
        (l, v) = np.linalg.eigh(cov)
        size = np.sqrt(l / X_c.shape[0] + (1. /
                                           (2 * np.sqrt(3)) * grid_res)**2)
        width = np.sqrt(0.5 * (size[1]**2 + size[2]**2))
        height = size[0]
        print D, size, width, height
        return height / width

    ratios = np.array([ar(D) for D in D_arr])
    return (D_arr, ratios)
def generate_rosette(D, min_grid_res=40e-6):
    grid_res = min(D / 20, min_grid_res)
    rot = rotator.UniformRotator()
    cry = crystal.Rosette(D)
    gen = generator.MonodisperseGenerator(cry, rot, grid_res)
    agg = aggregate.Aggregate(gen)

    return (agg, grid_res)
示例#3
0
def polydisp_dendrite(N=5, grid=None, align=True):
    #cry = crystal.Column(0.3e-3)

    agg = []
    psd = stats.expon(scale=1.0e-3)
    rot = rotator.UniformRotator()

    for i in xrange(N):
        D = 1e3
        while D > 0.3e-2 or D < 0.2e-3:
            D = psd.rvs()
        print "D: " + str(D)
        cry = crystal.Dendrite(D,
                               alpha=0.705,
                               beta=0.5,
                               gamma=0.0001,
                               num_iter=2500,
                               hex_grid=grid)
        gen = generator.MonodisperseGenerator(cry, rot, 0.02e-3)
        agg.append(aggregate.Aggregate(gen, levels=5))

    aggregate.t_i = 0
    aggregate.t_o = 0

    while len(agg) > 1:
        r = array([((a.extent[0][1] - a.extent[0][0]) +
                    (a.extent[1][1] - a.extent[1][0])) / 4.0 for a in agg])
        m_r = numpy.sqrt(array([a.X.shape[0] for a in agg]) / r)
        r_mat = (numpy.tile(r, (len(agg), 1)).T + r)**2
        mr_mat = abs(numpy.tile(m_r, (len(agg), 1)).T - m_r)
        p_mat = r_mat * mr_mat
        p_max = p_mat.max()
        p_mat /= p_mat.max()
        collision = False
        while not collision:
            i = random.randint(len(agg))
            j = random.randint(len(agg))
            rnd = random.rand()
            if rnd < p_mat[i][j]:
                print i, j
                agg_top = agg[i] if (m_r[i] > m_r[j]) else agg[j]
                agg_btm = agg[i] if (m_r[i] <= m_r[j]) else agg[j]
                collision = agg_top.add_particle(particle=agg_btm.X,
                                                 required=True)
                if collision:
                    if align:
                        agg_top.align()
                    else:
                        agg_top.rotate(rot)
                    agg.pop(i if (m_r[i] <= m_r[j]) else j)

    print aggregate.t_i, aggregate.t_o

    if align:
        agg[0].align()
    agg[0].rotate(rotator.HorizontalRotator())

    return agg[0]
示例#4
0
def monodisp_demo(N=5):
    #cry = crystal.Plate(0.3e-3)
    #cry = crystal.Rosette(0.6e-3)
    cry = crystal.Spheroid(0.6e-3, 0.6)
    rot = rotator.UniformRotator()
    gen = generator.MonodisperseGenerator(cry, rot, 0.01e-3)

    agg = aggregate.Aggregate(gen)

    for i in xrange(N - 1):
        print i
        agg.add_particle(required=True, pen_depth=0.02e-3)
        agg.align()

    return agg
def gen_monomer(psd="monodisperse",
                size=1.0,
                min_size=1e-3,
                max_size=10,
                mono_type="dendrite",
                grid_res=0.02e-3,
                rimed=False):
    def make_cry(D):
        if mono_type == "dendrite":
            grid = pickle.load(file("dendrite_grid.dat"))
            cry = crystal.Dendrite(D, hex_grid=grid)
        elif mono_type == "plate":
            cry = crystal.Plate(D)
        elif mono_type == "needle":
            cry = crystal.Needle(D)
        elif mono_type == "rosette":
            cry = crystal.Rosette(D)
        elif mono_type == "bullet":
            cry = crystal.Bullet(D)
        elif mono_type == "spheroid":
            cry = crystal.Spheroid(D, 0.6)
        return cry

    rot = rotator.UniformRotator()

    def gen():
        if psd == "monodisperse":
            D = size
        elif psd == "exponential":
            psd_f = stats.expon(scale=size)
            D = max_size + 1
            while (D < min_size) or (D > max_size):
                D = psd_f.rvs()

        cry = make_cry(D)

        gen = generator.MonodisperseGenerator(cry, rot, grid_res)
        if rimed:
            agg = aggregate.RimedAggregate(gen)
        else:
            agg = aggregate.Aggregate(gen)
        return agg

    return gen
def generate_aggregate(monomer_generator, N=5, align=True):

    align_rot = rotator.PartialAligningRotator(exp_sig_deg=40)
    uniform_rot = rotator.UniformRotator()

    agg = [monomer_generator() for i in xrange(N)]

    while len(agg) > 1:
        r = array([((a.extent[0][1] - a.extent[0][0]) +
                    (a.extent[1][1] - a.extent[1][0])) / 4.0 for a in agg])
        m_r = np.sqrt(array([a.X.shape[0] for a in agg]) / r)
        r_mat = (np.tile(r, (len(agg), 1)).T + r)**2
        mr_mat = abs(np.tile(m_r, (len(agg), 1)).T - m_r)
        p_mat = r_mat * mr_mat
        p_mat /= p_mat.max()
        collision = False
        while not collision:

            i = random.randint(len(agg))
            j = random.randint(len(agg))
            rnd = random.rand()
            if rnd < p_mat[i][j]:
                print i, j
                agg_top = agg[i] if (m_r[i] > m_r[j]) else agg[j]
                agg_btm = agg[i] if (m_r[i] <= m_r[j]) else agg[j]
                agg_btm.rotate(uniform_rot)
                collision = agg_top.add_particle(particle=agg_btm.X,
                                                 required=True,
                                                 pen_depth=80e-6)
                if collision:
                    if align:
                        agg_top.align()
                        agg_top.rotate(align_rot)
                    else:
                        agg_top.rotate(uniform_rot)
                    agg.pop(i if (m_r[i] <= m_r[j]) else j)

    if align:
        agg[0].align()
        agg[0].rotate(align_rot)
    agg[0].rotate(rotator.HorizontalRotator())

    return agg[0]
示例#7
0
def monodisp_pseudo(N=5, grid=None, sig=1.0):
    cry = crystal.Dendrite(0.5e-3,
                           alpha=0.705,
                           beta=0.5,
                           gamma=0.0001,
                           num_iter=2500,
                           hex_grid=grid)
    rot = rotator.UniformRotator()
    gen = generator.MonodisperseGenerator(cry, rot, 0.02e-3)
    """
   p_agg = aggregate.PseudoAggregate(gen, sig=0.1e-2)
   rho_i = 916.7 #kg/m^3
   N_dip = p_agg.grid().shape[0]
   m = 0.02e-3**3 * N_dip * N * rho_i
   sig = (m/20.3)**(1.0/2.35)
   print N_dip, sig
   """

    p_agg = aggregate.PseudoAggregate(gen, sig=sig)
    aggs = [aggregate.Aggregate(gen, levels=5) for i in xrange(N - 1)]
    for agg in aggs:
        p_agg.add_particle(particle=agg.X, required=False)
    return p_agg
示例#8
0
def monodisp_demo2(N=5):
    #cry = crystal.Column(0.3e-3)
    cry = crystal.Dendrite(0.3e-3, 0.705, 0.5, 0.0001, num_iter=2500)
    rot = rotator.UniformRotator()
    gen = generator.MonodisperseGenerator(cry, rot, 0.01e-3)

    agg = [aggregate.Aggregate(gen) for i in xrange(N)]

    aggregate.t_i = 0
    aggregate.t_o = 0

    while len(agg) > 1:
        r = array([((a.extent[0][1] - a.extent[0][0]) +
                    (a.extent[1][1] - a.extent[1][0])) / 4.0 for a in agg])
        m_r = numpy.sqrt(array([a.X.shape[0] for a in agg]) / r)
        r_mat = (numpy.tile(r, (len(agg), 1)).T + r)**2
        mr_mat = abs(numpy.tile(m_r, (len(agg), 1)).T - m_r)
        p_mat = r_mat * mr_mat
        p_max = p_mat.max()
        p_mat /= p_mat.max()
        collision = False
        while not collision:
            i = random.randint(len(agg))
            j = random.randint(len(agg))
            rnd = random.rand()
            if rnd < p_mat[i][j]:
                print i, j
                agg_top = agg[i] if (m_r[i] > m_r[j]) else agg[j]
                agg_btm = agg[i] if (m_r[i] <= m_r[j]) else agg[j]
                collision = agg_top.add_particle(particle=agg_btm.X,
                                                 required=True)
                agg_top.align()
                agg.pop(i if (m_r[i] <= m_r[j]) else j)

    print aggregate.t_i, aggregate.t_o
    return agg[0]
示例#9
0
def gen_monomer(psd="monodisperse", size=1e-3, min_size=0.1e-3, 
    max_size=20e-3, mono_type="dendrite", grid_res=0.02e-3, 
    rimed=False, debug=False):
    """Make a monomer crystal generator.

    Args:
        psd: "monodisperse" or "exponential".
        size: If psd="monodisperse", this is the diameter of the ice
            crystals. If psd="exponential", this is the inverse of the
            slope parameter (usually denoted as lambda).
        min_size, max_size: Minimum and maximum allowed size for generated
            crystals.
        mono_type: The type of crystals used. The possible values are
            "dendrite", "plate", "needle", "rosette", "bullet", "column",
            "spheroid".
        grid_res: The volume element size.
        rimed: True if a rimed aggregate should be generated, False
            otherwise.
        debug: If True, debug information will be printed.
    """
        
    def make_cry(D):
        if mono_type=="dendrite":
            current_dir = os.path.dirname(os.path.realpath(__file__))
            grid = pickle.load(file(current_dir+"/dendrite_grid.dat"))
            cry = crystal.Dendrite(D, hex_grid=grid)
        elif mono_type=="plate":
            cry = crystal.Plate(D)            
        elif mono_type=="needle":
            cry = crystal.Needle(D)
        elif mono_type=="rosette":
            cry = crystal.Rosette(D)
        elif mono_type=="bullet":
            cry = crystal.Bullet(D)
        elif mono_type=="column":
            cry = crystal.Column(D)
        elif mono_type=="spheroid":
            cry = crystal.Spheroid(D,1.0)
        return cry
                
    rot = rotator.UniformRotator()            
    
    def gen(ident=0):
        if psd=="monodisperse":
            D = size
        elif psd=="exponential":
            psd_f = stats.expon(scale=size)
            D=max_size+1
            while (D<min_size) or (D>max_size):
                D = psd_f.rvs()
        
        cry = make_cry(D)
        if debug:
            print D
        
        gen = generator.MonodisperseGenerator(cry, rot, grid_res)
        if rimed:
            agg = aggregate.RimedAggregate(gen, ident=ident)
        else:
            agg = aggregate.Aggregate(gen, ident=ident)
        return agg
    
    return gen
示例#10
0
def generate_rimed_aggregate_iter(monomer_generator, N=5, align=True,
    riming_lwp=0.0, riming_eff=1.0, riming_mode="simultaneous", 
    rime_pen_depth=120e-6, seed=None, lwp_div=10, compact_dist=0.,
    debug=False):
    """Generate a rimed aggregate particle.

    Refer to the generate_rimed_aggregate function for details.
    """

    random.seed(seed)

    align_rot = rotator.PartialAligningRotator(exp_sig_deg=40, random_flip=True)
    uniform_rot = rotator.UniformRotator()

    agg = [monomer_generator(ident=i) for i in xrange(N)]
    yield agg

    while len(agg) > 1:
        r = np.array([((a.extent[0][1]-a.extent[0][0])+
            (a.extent[1][1]-a.extent[1][0]))/4.0 for a in agg])
        m_r = np.sqrt(np.array([a.X.shape[0] for a in agg])/r)
        r_mat = (np.tile(r,(len(agg),1)).T+r)**2                
        mr_mat = abs(np.tile(m_r,(len(agg),1)).T - m_r)
        p_mat = r_mat * mr_mat
        p_mat /= p_mat.max()
        collision = False
        while not collision:
            
            i = random.randint(len(agg))
            j = i
            while j == i:
                j = random.randint(len(agg))
            rnd = random.rand()
            if rnd < p_mat[i][j]:
                if debug:
                    print i, j
                agg_top = agg[i] if (m_r[i] > m_r[j]) else agg[j]
                agg_btm = agg[i] if (m_r[i] <= m_r[j]) else agg[j]
                agg_btm.rotate(uniform_rot)
                collision = agg_top.add_particle(particle=agg_btm.X,ident=agg_btm.ident,
                    required=True,pen_depth=80e-6)
                if collision:
                    if align:
                        agg_top.align()
                        agg_top.rotate(align_rot)
                    else:
                        agg_top.rotate(uniform_rot)
                    agg.pop(i if (m_r[i] <= m_r[j]) else j)

        if riming_mode == "simultaneous":
            for a in agg:                
                generate_rime(a, align_rot if align else uniform_rot,
                    riming_lwp/float(N-1), riming_eff=riming_eff, 
                    pen_depth=rime_pen_depth, lwp_div=lwp_div,
                    compact_dist=compact_dist)

        if len(agg) > 1:
            yield agg

    if (riming_mode == "subsequent") or (N==1):
        for a in generate_rime(agg[0], align_rot if align else uniform_rot, 
            riming_lwp, riming_eff=riming_eff, pen_depth=rime_pen_depth, 
            lwp_div=lwp_div, iter=True, compact_dist=compact_dist):

            yield [a]

    if align:
        agg[0].align()
        agg[0].rotate(align_rot)
    agg[0].rotate(rotator.HorizontalRotator())

    yield agg