Exemple #1
0
def insert_em(grid, conf, ffunc):

    Lx = conf.Nx * conf.NxMesh  #XXX scaled length
    for i in range(grid.get_Nx()):
        for j in range(grid.get_Ny()):
            for k in range(grid.get_Nz()):
                c = grid.get_tile(i, j, k)
                yee = c.get_yee()

                for l in range(conf.NxMesh):
                    for m in range(conf.NyMesh):
                        for n in range(conf.NzMesh):

                            # get x_i,j,k
                            xloc0 = pytools.ind2loc((i, j, k), (l, m, n), conf)

                            #get x_i+1/2, x_j+1/2, x_k+1/2
                            xloc1 = pytools.ind2loc((i, j, k), (l + 1, m, n),
                                                    conf)
                            yloc1 = pytools.ind2loc((i, j, k), (l, m + 1, n),
                                                    conf)
                            zloc1 = pytools.ind2loc((i, j, k), (l, m, n + 1),
                                                    conf)

                            # values in Yee lattice corners
                            xcor = xloc0[0]
                            ycor = xloc0[1]
                            zcor = xloc0[2]

                            # values in Yee lattice mids
                            xmid = 0.5 * (xloc0[0] + xloc1[0])
                            ymid = 0.5 * (xloc0[1] + yloc1[1])
                            zmid = 0.5 * (xloc0[2] + zloc1[2])

                            #val = ffunc(xmid, ymid, zmid)

                            # enforce Yee lattice structure
                            yee.ex[l, m, n] = ffunc(xmid, ycor, zcor)
                            yee.ey[l, m, n] = ffunc(xcor, ymid, zcor) + 1.0
                            #yee.ez[l,m,n] = ffunc(xcor, ycor, zmid)+2.0
                            yee.ez[l, m,
                                   n] = ffunc(xcor, ycor, zcor) + 2.0  #2D hack

                            #yee.bx[l,m,n] = ffunc(xcor, ymid, zmid)+3.0
                            yee.bx[l, m,
                                   n] = ffunc(xcor, ymid, zcor) + 3.0  #2D hack
                            #yee.by[l,m,n] = ffunc(xmid, ycor, zmid)+4.0 #2D hack
                            yee.by[l, m, n] = ffunc(xmid, ycor, zcor) + 4.0
                            yee.bz[l, m, n] = ffunc(xmid, ymid, zcor) + 5.0

                            yee.jx[l, m, n] = ffunc(xmid, ymid, zmid)
                            yee.jy[l, m, n] = ffunc(xmid, ymid, zmid)
                            yee.jz[l, m, n] = ffunc(xmid, ymid, zmid)
Exemple #2
0
def insert_em_fields(grid, conf):

    # into radians
    btheta = conf.btheta / 180.0 * np.pi
    bphi = conf.bphi / 180.0 * np.pi
    beta = conf.beta

    for tile in pytools.tiles_all(grid):
        yee = tile.get_yee(0)

        ii, jj, kk = tile.index if conf.threeD else (*tile.index, 0)

        # insert values into Yee lattices; includes halos from -3 to n+3
        for n in range(-3, conf.NzMesh + 3):
            for m in range(-3, conf.NyMesh + 3):
                for l in range(-3, conf.NxMesh + 3):
                    # get global coordinates
                    iglob, jglob, kglob = pytools.ind2loc((ii, jj, kk),
                                                          (l, m, n), conf)
                    r = np.sqrt(iglob**2 + jglob**2 + kglob**2)

                    yee.bx[l, m, n] = conf.binit * np.cos(bphi)
                    yee.by[l, m,
                           n] = conf.binit * np.sin(bphi) * np.sin(btheta)
                    yee.bz[l, m,
                           n] = conf.binit * np.sin(bphi) * np.cos(btheta)

                    yee.ex[l, m, n] = 0.0
                    yee.ey[l, m, n] = -beta * yee.bz[l, m, n]
                    yee.ez[l, m, n] = beta * yee.by[l, m, n]
    return
Exemple #3
0
def insert_em_fields(grid, conf):

    # into radians
    #btheta = conf.btheta / 180.0 * np.pi
    #bphi = conf.bphi / 180.0 * np.pi
    #beta = conf.beta

    # setup global perturbations for electric field
    np.random.seed(1)  # global simulation seed
    rnd_phases = np.random.rand(conf.n_modes)

    Lx = conf.Nx * conf.NxMesh
    kx = 2.0 * np.pi / Lx
    modes = np.arange(1, conf.n_modes + 1)
    ampl = conf.mode_ampl  #/np.sqrt(conf.n_modes)

    for tile in pytools.tiles_all(grid):
        yee = tile.get_yee(0)

        ii, jj, kk = tile.index if conf.threeD else (*tile.index, 0)

        # insert values into Yee lattices; includes halos from -3 to n+3
        for n in range(-3, conf.NzMesh + 3):
            for m in range(-3, conf.NyMesh + 3):
                for l in range(-3, conf.NxMesh + 3):
                    # get global coordinates
                    iglob, jglob, kglob = pytools.ind2loc((ii, jj, kk),
                                                          (l, m, n), conf)
                    #r = np.sqrt(iglob ** 2 + jglob ** 2 + kglob ** 2)
                    yee.bx[l, m, n] = 0.0  #conf.binit * np.cos(bphi)
                    yee.by[
                        l, m,
                        n] = 0.0  #conf.binit * np.sin(bphi) * np.sin(btheta)
                    yee.bz[
                        l, m,
                        n] = 0.0  #conf.binit * np.sin(bphi) * np.cos(btheta)
                    yee.ey[l, m, n] = 0.0  #-beta * yee.bz[l, m, n]
                    yee.ez[l, m, n] = 0.0  #+beta * yee.by[l, m, n]

                    # harmonic perturbations
                    yee.ex[l, m, n] = ampl * np.sum(
                        np.sin(kx * iglob * modes + rnd_phases))

    return
Exemple #4
0
def insert_em_fields(grid, conf):
    from numpy import arctan2, sin, cos, sqrt, pi

    Lx = conf.Nx*conf.NxMesh
    Ly = conf.Ny*conf.NyMesh
    Lz = conf.Nz*conf.NzMesh

    b0 = conf.binit   # equilibrium magnetic field
    zeta = conf.zeta  # perturbation amplitude

    # maximum perpendicular and parallel wavenumbers
    kperp = 1.0*pi/Lx #half of the sine only
    kpar  = 2.0*pi/Lz

    #phase shift
    om0 = 0.0 

    #amplitude; 
    A = b0*zeta/2.0

    # position of the centers as Stagger objects
    pkg_loc1 = conf.pkg_loc1
    pkg_loc2 = conf.pkg_loc2 

    #-------------------------------------------------- 
    #ell = Lx/2. #maximum size
    ell = conf.ell

    for cid in grid.get_tile_ids():
        tile = grid.get_tile(cid)
        yee = tile.get_yee(0)

        if conf.twoD:
            ii, jj = tile.index
            kk = 0
        elif conf.threeD:
            ii, jj, kk = tile.index

        # insert values into Yee lattices
        for n in range(conf.NzMesh):
            for m in range(conf.NyMesh):
                for l in range(conf.NxMesh):

                    # get global coordinates
                    iglob, jglob, kglob = pytools.ind2loc((ii, jj, kk), (l, m, n), conf)
                    loc = pytools.Stagger(iglob, jglob, kglob)

                    # distance from the center of the packets
                    d1 = pkg_loc1 - loc
                    d2 = pkg_loc2 - loc

                    x = iglob
                    y = jglob
                    z = kglob 

                    # add stationary guide field
                    yee.bz[l, m, n] = b0

                    bpkg1 = {}
                    bpkg2 = {}

                    # build exact initial amplitude for different staggered grid locations
                    for st in [ "rh", "bx", "by", "bz", "ex", "ey", "ez",]:

                        # spherical distance
                        r1 = np.sqrt( d1.at(st).x ** 2 + d1.at(st).y ** 2 + d1.at(st).z ** 2 )
                        r2 = np.sqrt( d2.at(st).x ** 2 + d2.at(st).y ** 2 + d2.at(st).z ** 2 )

                        envelope1 = np.cos(pi*r1/ell/2.0)
                        envelope2 = np.cos(pi*r2/ell/2.0)

                        # cut after r > ell
                        if r1 > 1.10*ell or envelope1 < 0.0:
                            envelope1 = 0.0
                        if r2 > 1.10*ell or envelope2 < 0.0:
                            envelope2 = 0.0

                        # volume normalized amplitdue
                        #bpkg1[st] = b0*(pi * ell) * envelope
                        #bpkg2[st] = b0*(pi * ell) * envelope

                        # peak normalized amplitdue
                        bpkg1[st] = 2.0*b0*zeta*envelope1/ell
                        bpkg2[st] = 2.0*b0*zeta*envelope2/ell


                    #first pkg
                    yee.bx[l, m, n] += -bpkg1["bx"] * d1.at("bx").y
                    yee.by[l, m, n] += +bpkg1["by"] * d1.at("by").x

                    wdir = +1.0*conf.beta #direction of wave
                    yee.ex[l, m, n] += wdir*bpkg1["ex"] * d1.at("ex").x
                    yee.ey[l, m, n] += wdir*bpkg1["ey"] * d1.at("ey").y

                    #second pkg
                    if conf.two_wave:
                        if conf.two_wave_reversed:
                            rdir = -1.0 #direction of twist; antialigned
                        else:
                            rdir = +1.0 #direction of twist; aligned

                        yee.bx[l, m, n] += -rdir*bpkg2["bx"] * d2.at("bx").y
                        yee.by[l, m, n] += +rdir*bpkg2["by"] * d2.at("by").x

                        wdir = -1.0*conf.beta #direction of wave
                        yee.ex[l, m, n] += wdir*rdir*bpkg2["ex"] * d2.at("ex").x
                        yee.ey[l, m, n] += wdir*rdir*bpkg2["ey"] * d2.at("ey").y

    return
Exemple #5
0
def insert_em_harris_sheet(grid, conf):
    from numpy import pi, tanh, sin, cos, sinh, cosh, sqrt

    delta = conf.sheet_thickness / (2.0 * pi)  # sheet thickness incl. 2pi
    pinch_delta = conf.pinch_width / (2.0 * pi)  # pinch thickness incl. 2pi
    eta = conf.sheet_density
    beta = 0.0  # conf.beta #sheet bulk flow; NOTE: for force-free setup no flow
    sigma = conf.sigma  # magnetization

    # field angles
    btheta = 1.0
    bphi = pi / 2.0  # conf.bphi/180. * pi

    # note: if periodicx then mxhalf is actually Lx/4 else Lx/2
    mxhalf = conf.mxhalf
    myhalf = conf.myhalf
    mzhalf = conf.mzhalf
    Lx = conf.lstripe

    # binit = conf.binit  # initial B_0
    binit = 0.1

    for tile in pytools.tiles_all(grid):
        ii, jj, kk = tile.index if conf.threeD else (*tile.index, 0)
        yee = tile.get_yee(0)

        # insert values into Yee lattices; includes halos from -3 to n+3
        for n in range(conf.NzMesh):
            for m in range(conf.NyMesh):
                for l in range(conf.NxMesh):

                    # get global coordinates
                    iglob, jglob, kglob = pytools.ind2loc((ii, jj, kk),
                                                          (l, m, n), conf)

                    # trigger field modulation in z coordinate
                    if conf.threeD:
                        triggerz = cosh((kglob - mzhalf) / pinch_delta)  # 3D
                    else:
                        triggerz = 1.0

                    # inifnitely small thickness
                    if conf.sheet_thickness == 0.0:
                        if iglob <= mxhalf:
                            stripetanh = -1.0
                        elif mxhalf < iglob <= 3.0 * mxhalf:
                            stripetanh = +1.0
                        elif 3.0 * mxhalf < iglob:
                            stripetanh = -1.0

                        # one cell flip of zero
                        # if iglob == mxhalf or iglob == 3.*mxhalf:
                        #    stripetanh = 0.0

                    # flipping harris sheet stripe
                    else:
                        if not (conf.periodicx):
                            stripetanh = tanh((iglob - mxhalf) / delta)
                        else:
                            stripetanh = tanh(Lx * sin(2.0 * pi *
                                                       (iglob - mxhalf) / Lx) /
                                              delta / 2.0 / pi)

                    if conf.trigger:

                        # plasma bulk velocity modulation factor;
                        # NOTE: true velocity v/c= velstripe*beta

                        # velstripe = tanh((iglob-mxhalf)/pinch_delta)/cosh((iglob-mxhalf)/pinch_delta)
                        velstripe = tanh((iglob - mxhalf) / pinch_delta)
                        # velstripe = tanh((iglob - mxhalf) / pinch_delta) / (
                        #    cosh((jglob - myhalf) / pinch_delta)
                        #    * cosh((iglob - mxhalf) / pinch_delta)
                        # )

                        if conf.sheet_thickness == 0.0:
                            pinch_corr = cosh(
                                (jglob - myhalf) / pinch_delta) * triggerz
                            if iglob != mxhalf + 1:  # or iglob == 3.0 * mxhalf + 1:
                                pinch_corr = 1.0

                        else:
                            pinch_corr = (cosh(
                                (jglob - myhalf) / pinch_delta) * cosh(
                                    (iglob - mxhalf) / delta) * triggerz)

                        # by
                        yee.by[l, m, n] = binit * sin(bphi) * stripetanh
                        yee.by[l, m,
                               n] += (binit * cos(bphi) * btheta * cos(bphi) *
                                      (1.0 - 1.0 / pinch_corr))

                        # bz
                        yee.bz[l, m, n] = binit * cos(bphi) * stripetanh
                        yee.bz[l, m, n] += (binit * sin(bphi) * btheta *
                                            (1.0 - 1.0 / pinch_corr))

                        # ey
                        yee.ey[l, m, n] = (-beta) * velstripe * yee.bz[l, m, n]

                        # ez
                        yee.ez[l, m, n] = (+beta) * velstripe * yee.by[l, m, n]

                        # drive to trigger reconnection in the middle of the box;
                        # the coefficient should be the desired ExB speed
                        yee.ez[l, m, n] += (conf.trigger_field *
                                            yee.by[l, m, n] / pinch_corr)

                        # trigger point
                        if conf.sheet_thickness == 0.0:
                            if jglob == myhalf:
                                if iglob == mxhalf + 1 or iglob == 3.0 * mxhalf + 1:
                                    yee.ez[l, m, n] += conf.trigger_field

                    else:
                        yee.by[l, m, n] = binit * sin(bphi) * stripetanh
                        yee.by[l, m, n] += binit * cos(bphi) * btheta

                        yee.bz[l, m, n] = binit * cos(bphi) * stripetanh
                        yee.bz[l, m, n] += binit * sin(bphi) * btheta

                        yee.ey[l, m, n] = (-beta) * yee.bz[l, m, n]
                        yee.ez[l, m, n] = (+beta) * yee.by[l, m, n]

                    yee.ex[l, m, n] = 0.0

                    # add external non-evolving guide field
                    yee.bz[l, m, n] += binit * sqrt(conf.sigma_ext)

                    # one zell thin current sheet to balance the flip
                    # if iglob == mxhalf or iglob == 3.*mxhalf:
                    #    yee.ez[l, m, n] +=  binit
                    # if iglob == mxhalf+1 or iglob == 3.*mxhalf+1:
                    #    yee.ez[l, m, n] +=  binit

                    if False:
                        # hot current sheet
                        # beta_drift = sqrt(sigma)
                        beta_drift = 0.5
                        if not (conf.periodicx):
                            num_plasma = 1.0 / (cosh(
                                (iglob - mxhalf) / delta))**2.0
                        else:
                            # num_plasma = 1.0/(cosh(dstripe*lstripe*sin(2.*pi*(iglob-mxhalf)/lstripe)))**2.*stripecosh
                            num_plasma = (
                                1.0 / cosh(Lx * sin(2.0 * pi *
                                                    (iglob - mxhalf) / Lx) /
                                           delta / 2.0 / pi)**2.0)

                        gamma_drift = sqrt(1.0 / (1.0 - beta_drift**2.0))
                        if conf.periodicx:
                            gamma_drift = gamma_drift * np.sign(
                                cos(2.0 * pi * (iglob - mxhalf) / Lx))
                            beta_drift = sqrt(1.0 - 1.0 / gamma_drift**2
                                              ) * np.sign(gamma_drift)

                        yee.ez[l, m, n] += beta_drift * num_plasma * binit

            # copy values to boundary cells
            # FIXME
            # try:
            #    for n in range(conf.NzMesh):
            #        for m in range(conf.NyMesh):
            #            for l in range(conf.NxMesh):
            #                c.ex_ref[l,m,n] = yee.ex[l,m,n]
            #                c.ey_ref[l,m,n] = yee.ey[l,m,n]
            #                c.ez_ref[l,m,n] = yee.ez[l,m,n]

            #                c.bx_ref[l,m,n] = yee.bx[l,m,n]
            #                c.by_ref[l,m,n] = yee.by[l,m,n]
            #                c.bz_ref[l,m,n] = yee.bz[l,m,n]
            # except:
            #    #print("cell ({},{}) is not boundary cell".format(ii,jj))
            #    pass
    return
Exemple #6
0
def insert_em_3D_wave_packet(grid, conf):
    from numpy import arctan2, sin, cos, sqrt

    b0 = 1.0

    # bperp = 1.0
    # Lx = conf.NxMesh*conf.Nx
    # beta = 0.1
    # modes = 1.
    # kx = 2.0*np.pi*modes/Lx

    # middle of the box
    x0 = conf.Nx * conf.NxMesh * 0.5
    y0 = conf.Ny * conf.NyMesh * 0.5

    z1 = 0.0  # conf.Ny*conf.NyMesh*0.25
    z2 = conf.Ny * conf.NyMesh * 0.75

    print("x0 {} {} {}".format(x0, y0, z1))

    # position of the centers as Stagger objects
    pkg_loc1 = pytools.Stagger(x0, y0, z1)
    pkg_loc2 = pytools.Stagger(x0, y0, z2)

    zeta = 1.0  # perturbation amplitude
    ell = 10.0  # perturbation length

    for cid in grid.get_tile_ids():
        tile = grid.get_tile(cid)
        yee = tile.get_yee(0)

        if conf.twoD:
            ii, jj = tile.index
            kk = 0
        elif conf.threeD:
            ii, jj, kk = tile.index

        # insert values into Yee lattices; includes halos from -3 to n+3
        for n in range(conf.NzMesh):
            for m in range(conf.NyMesh):
                for l in range(conf.NxMesh):
                    # get global coordinates
                    iglob, jglob, kglob = pytools.ind2loc((ii, jj, kk),
                                                          (l, m, n), conf)
                    loc = pytools.Stagger(iglob, jglob, kglob)

                    # distance from the center of the packets
                    d1 = pkg_loc1 - loc
                    d2 = pkg_loc2 - loc

                    # add stationary guide field
                    yee.bz[l, m, n] = b0

                    # amplitude for the perturbations
                    #
                    # gauss = zeta * ell * np.exp(-r1 / ell ** 2)
                    # bphi = (2.0 * b0 * w / ell ** 2) * gauss

                    # bphi = {}
                    # theta = {}

                    bpkg1 = {}
                    bpkg2 = {}

                    # build exact initial amplitude for different staggered grid locations
                    for st in [
                            "rh",
                            "bx",
                            "by",
                            "bz",
                            "ex",
                            "ey",
                            "ez",
                            #'jx', 'jy', 'jz',
                    ]:

                        # spherical distance
                        r1 = d1.at(st).x**2 + d1.at(st).y**2 + d1.at(st).z**2
                        r2 = d2.at(st).x**2 + d2.at(st).y**2 + d2.at(st).z**2

                        gauss_profile1 = zeta * ell * np.exp(-r1 / ell**2)
                        gauss_profile2 = zeta * ell * np.exp(-r2 / ell**2)

                        bpkg1[st] = (2 * b0 / ell**2) * gauss_profile1
                        bpkg2[st] = (2 * b0 / ell**2) * gauss_profile2

                    # add fields (staggered)
                    yee.bx[l, m, n] = -bpkg1["bx"] * d1.at("bx").y
                    yee.by[l, m, n] = +bpkg1["by"] * d1.at("by").x

                    yee.ex[l, m, n] = -bpkg1["ex"] * d1.at("ex").x
                    yee.ey[l, m, n] = -bpkg1["ey"] * d1.at("ey").y

                    # non staggered
                    #st = 'rh'
                    #yee.bx[l, m, n] = -bpkg1[st] * d1.at(st).y
                    #yee.by[l, m, n] = +bpkg1[st] * d1.at(st).x

                    #yee.ex[l, m, n] = -bpkg1[st] * d1.at(st).x
                    #yee.ey[l, m, n] = -bpkg1[st] * d1.at(st).y
    return
Exemple #7
0
def insert_em_waves(grid, conf):

    # into radians
    # btheta = conf.btheta / 180.0 * np.pi
    # bphi = conf.bphi / 180.0 * np.pi
    # beta = conf.beta
    # beta = 0.1

    bpar = 1.0
    bperp = 1.0
    Lx = conf.NxMesh * conf.Nx
    beta = 0.1

    modes = 1.0
    kx = 2.0 * np.pi * modes / Lx

    for cid in grid.get_tile_ids():
        tile = grid.get_tile(cid)
        yee = tile.get_yee(0)

        if conf.twoD:
            ii, jj = tile.index
            kk = 0
        elif conf.threeD:
            ii, jj, kk = tile.index

        # insert values into Yee lattices; includes halos from -3 to n+3
        for n in range(conf.NzMesh):
            for m in range(conf.NyMesh):
                for l in range(conf.NxMesh):
                    # get global coordinates
                    iglob, jglob, kglob = pytools.ind2loc((ii, jj, kk),
                                                          (l, m, n), conf)
                    # r = np.sqrt(iglob ** 2 + jglob ** 2 + kglob ** 2)

                    if True:
                        # 1D Alfven wave packet
                        yee.bx[l, m, n] = 0.0  # bpar
                        if 0 <= iglob <= 0.5 * Lx:
                            # yee.bz[l, m, n] = bperp*np.sin(kx*iglob)
                            # yee.ey[l, m, n] = bperp*np.sin(kx*iglob)

                            yee.by[l, m, n] = bperp * np.sin(kx * iglob)
                            yee.ez[l, m, n] = bperp * np.sin(kx * iglob)

                    # fast mode wave packet
                    if False:
                        if 0 <= iglob <= 0.5 * Lx:
                            yee.by[l, m, n] = bperp * np.sin(kx * iglob)
                            # yee.ez[l, m, n] = bperp*np.sin(kx*iglob)

                    if False:
                        # 1D Alfven wave packet collisions
                        yee.bx[l, m, n] = bpar
                        if 0 <= iglob < 0.5 * Lx:
                            yee.bz[l, m, n] = bperp * np.sin(kx * iglob)
                            yee.ey[l, m, n] = bperp * np.sin(kx * iglob)

                        if 0.5 * Lx <= iglob < Lx:
                            yee.bz[l, m, n] = bperp * np.sin(kx * iglob)
                            yee.ey[l, m, n] = -bperp * np.sin(kx * iglob)

    return