Esempio n. 1
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
Esempio n. 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

    # 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
Esempio n. 3
0
def insert_em_fields(grid, conf):

    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
                    yee.by[l, m, n] = 0.0
                    yee.bz[l, m, n] = conf.binit

                    yee.ex[l, m, n] = 0.0
                    yee.ey[l, m, n] = 0.0
                    yee.ez[l, m, n] = 0.0
    return
Esempio n. 4
0
    # timer.verbose = 1  # 0 normal; 1 - debug mode

    # --------------------------------------------------
    # sync e and b fields

    # mpi e
    grid.send_data(1)
    grid.recv_data(1)
    grid.wait_data(1)

    # mpi b
    grid.send_data(2)
    grid.recv_data(2)
    grid.wait_data(2)

    for tile in pytools.tiles_all(grid):
        tile.update_boundaries(grid)

    ##################################################
    # simulation time step loop

    sys.stdout.flush()

    # simulation loop
    time = lap * (conf.cfl / conf.c_omp)
    for lap in range(lap, conf.Nt + 1):

        # --------------------------------------------------
        # push B half
        t1 = timer.start_comp("push_half_b1")
        for tile in pytools.tiles_all(grid):
Esempio n. 5
0
    def test_problematic_prtcls(self):

        # test pic loop behavior when particle is located in wrong container

        conf = Conf()
        conf.twoD = False
        conf.threeD = True
        conf.Nx = 2
        conf.Ny = 2
        conf.Nz = 2

        conf.NxMesh = 3
        conf.NyMesh = 3
        conf.NzMesh = 3

        conf.Nt = 3
        conf.update_bbox()

        grid = pycorgi.threeD.Grid(conf.Nx, conf.Ny, conf.Nz)
        grid.set_grid_lims(conf.xmin, conf.xmax, conf.ymin, conf.ymax,
                           conf.zmin, conf.zmax)

        pytools.pic.load_tiles(grid, conf)
        insert_em(grid, conf, zero_field)

        print("============================================================")

        #--------------------------------------------------
        cid = grid.id(0, 0, 0)
        c = grid.get_tile(cid)  #get cell ptr

        container = c.get_container(0)  #ispcs
        container.set_keygen_state(0, 0)  #number, rank

        u0 = [0.0, 0.0, 0.0]

        # problematic prtcl set 1 (at minimum boundary)
        #x0 = [0.0, 1.0, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 0.0, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 1.0, 0.0]
        #container.add_particle(x0, u0, 1.0)

        # problematic prtcl set 2 (at maximum boundary)
        #x0 = [3.0, 1.0, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 3.0, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 1.0, 3.0]
        #container.add_particle(x0, u0, 1.0)

        # problematic prtcl set 3 (completely outside)
        #x0 = [3.1, 1.0, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 3.1, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 1.0, 3.1]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [-0.1, 1.0, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, -0.1, 1.0]
        #container.add_particle(x0, u0, 1.0)

        #x0 = [1.0, 1.0, -0.1]
        #container.add_particle(x0, u0, 1.0)

        # last tile
        cid = grid.id(1, 1, 1)
        c = grid.get_tile(cid)  #get cell ptr
        container = c.get_container(0)  #ispcs
        container.set_keygen_state(0, 0)  #number, rank

        x0 = [6.0, 5.0, 5.0]
        container.add_particle(x0, u0, 1.0)

        x0 = [0.0, 5.0, 5.0]
        container.add_particle(x0, u0, 1.0)

        #--------------------------------------------------
        pusher = pyrunko.pic.threeD.BorisPusher()
        fldprop = pyrunko.fields.threeD.FDTD2()
        fintp = pyrunko.pic.threeD.LinearInterpolator()
        currint = pyrunko.pic.threeD.ZigZag()
        flt = pyrunko.fields.threeD.Binomial2(conf.NxMesh, conf.NyMesh,
                                              conf.NzMesh)

        lap = 0
        for lap in range(lap, conf.Nt):

            # --------------------------------------------------
            # push B half
            for tile in pytools.tiles_all(grid):
                fldprop.push_half_b(tile)

            # --------------------------------------------------
            # comm B
            grid.send_data(2)
            grid.recv_data(2)
            grid.wait_data(2)

            # --------------------------------------------------
            # update boundaries
            for tile in pytools.tiles_all(grid):
                tile.update_boundaries(grid)

            ##################################################
            # move particles (only locals tiles)

            # --------------------------------------------------
            # interpolate fields
            for tile in pytools.tiles_local(grid):
                fintp.solve(tile)
            #print('successful interp')

            # --------------------------------------------------
            # push particles in x and u
            #for tile in pytools.tiles_local(grid):
            #    pusher.solve(tile)

            ##################################################
            # advance B half

            # --------------------------------------------------
            # push B half
            for tile in pytools.tiles_all(grid):
                fldprop.push_half_b(tile)

            # --------------------------------------------------
            # comm B
            grid.send_data(1)
            grid.recv_data(1)
            grid.wait_data(1)

            # --------------------------------------------------
            # update boundaries
            for tile in pytools.tiles_all(grid):
                tile.update_boundaries(grid)

            ##################################################
            # advance E

            # --------------------------------------------------
            # push E
            for tile in pytools.tiles_all(grid):
                fldprop.push_e(tile)

            # --------------------------------------------------
            # current calculation; charge conserving current deposition
            for tile in pytools.tiles_local(grid):
                currint.solve(tile)
            #print('successful currint')

            # --------------------------------------------------
            # clear virtual current arrays for boundary addition after mpi
            for tile in pytools.tiles_virtual(grid):
                tile.clear_current()

            # --------------------------------------------------
            # mpi send currents
            grid.send_data(0)
            grid.recv_data(0)
            grid.wait_data(0)

            # --------------------------------------------------
            # exchange currents
            for tile in pytools.tiles_all(grid):
                tile.exchange_currents(grid)

            ##################################################
            # particle communication (only local/boundary tiles)

            # --------------------------------------------------
            # local particle exchange (independent)
            for tile in pytools.tiles_local(grid):
                tile.check_outgoing_particles()

            # --------------------------------------------------
            # global mpi exchange (independent)
            for tile in pytools.tiles_boundary(grid):
                tile.pack_outgoing_particles()

            # --------------------------------------------------
            # MPI global particle exchange
            # transfer primary and extra data
            grid.send_data(3)
            grid.recv_data(3)
            grid.wait_data(3)

            # orig just after send3
            grid.send_data(4)
            grid.recv_data(4)
            grid.wait_data(4)

            # --------------------------------------------------
            # global unpacking (independent)
            for tile in pytools.tiles_virtual(grid):
                tile.unpack_incoming_particles()
                tile.check_outgoing_particles()

            # --------------------------------------------------
            # transfer local + global
            for tile in pytools.tiles_local(grid):
                tile.get_incoming_particles(grid)

            # --------------------------------------------------
            # delete local transferred particles
            for tile in pytools.tiles_local(grid):
                tile.delete_transferred_particles()

            # --------------------------------------------------
            # delete all virtual particles (because new prtcls will come)
            for tile in pytools.tiles_virtual(grid):
                tile.delete_all_particles()

            # --------------------------------------------------
            # add current to E
            for tile in pytools.tiles_all(grid):
                tile.deposit_current()

            # comm E
            grid.send_data(1)
            grid.recv_data(1)
            grid.wait_data(1)

            # --------------------------------------------------
            # comm B
            grid.send_data(2)
            grid.recv_data(2)
            grid.wait_data(2)

            # --------------------------------------------------
            # update boundaries
            for tile in pytools.tiles_all(grid):
                tile.update_boundaries(grid)

        # --------------------------------------------------
        ip = 0
        prtcls = {}
        for tile in pytools.tiles_all(grid):
            container = tile.get_container(0)  #ispcs

            xp = container.loc(0)
            yp = container.loc(1)
            zp = container.loc(2)

            for i in range(len(xp)):
                prtcls[ip] = (xp[i], yp[i], zp[i], tile.cid)
                ip += 1
Esempio n. 6
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