Пример #1
0
def arc12_pt3(xyz1, xyz2, xyz3):
    '''
    Three points should be on same circle.
    '''

    vec1 = x1, y1, z1 = xyz1
    vec2 = x2, y2, z2 = xyz2
    vec3 = x3, y3, z3 = xyz3

    unit_nvec = normal_vector(vec1, vec2, normalize=True)
    cp1 = np.dot(unit_nvec, np.cross(vec1, vec3))
    cp2 = np.dot(unit_nvec, np.cross(vec2, vec3))

    if feq(cp1,0):
        if feq(cp2,0):
            raise ValueError("cp1 and cp2 are both zero")
        elif flt(cp2,0):
            return 'pt1'
        elif fgt(cp2,0):
            return 'out'

    elif flt(cp1,0):
        return 'out'

    elif fgt(cp1,0):
        if feq(cp2,0):
            return 'pt2'
        elif flt(cp2,0):
            return 'between'
        elif fgt(cp2,0):
            return 'out'
Пример #2
0
def xyz2latlon(x, y, z, R=1):
    '''
    if feq(z,R):
        lat, lon = pi/2, 0
    elif feq(z,-R):
        lat, lon = -pi/2, 0
    '''

    if feq(sqrt(x*x + y*y),0):
        if z > 0:
            lat, lon = pi/2, 0
        elif z < 0:
            lat, lon = -pi/2, 0

    else:
        lat = arctan(z/sqrt(x*x + y*y))

        if feq(x,0):
            if fgt(y,0): lon = pi/2
            else: lon = 3*pi/2

        elif fgt(x,0):
            if fgt(y,0): lon = arctan(y/x)
            else: lon = arctan(y/x) + 2*pi

        else:
            lon = arctan(y/x) + pi

    return lat, lon
Пример #3
0
def duplicate_idxs(xyzs, digit=15):
    size = len(xyzs)
    dup_idxs = list()

    for i in range(size):
        for j in range(i+1,size):
            x1, y1, z1 = xyzs[i]
            x2, y2, z2 = xyzs[j]

            if feq(x1,x2,digit) and feq(y1,y2,digit) and feq(z1,z2,digit):
                dup_idxs.append(j)
    
    return dup_idxs
Пример #4
0
def intersect_two_greatcircles(abc1, abc2):
    '''
    Two intersection points of two planes and a sphere
    Input are plane parameters.
    '''

    a1, b1, c1 = abc1
    a2, b2, c2 = abc2

    if feq(a1,a2) and feq(b1,b2) and feq(c1,c2):
        return None, None

    elif feq(a1,0) and feq(a2,0):
        s1, s2 = [(1,0,0), (-1,0,0)]

    elif feq(b1,0) and feq(b2,0):
        s1, s2 = [(0,1,0), (0,-1,0)]

    elif feq(c1,0) and feq(c2,0):
        s1, s2 = [(0,0,1), (0,0,-1)]

    elif feq(c2*b1, c1*b2):
        A = a2*c1-a1*c2
        B = a2*b1-a1*b2
        denom = A*A + B*B

        #if feq(denom,0):
        if denom == 0:
            return None, None
        else:
            Z = 1/np.sqrt(denom)
            s1 = (0, A*Z, -B*Z)
            s2 = (0, -A*Z, B*Z)

    else:
        A = b2*c1-b1*c2
        B = c2*a1-c1*a2
        C = b2*a1-b1*a2
        denom = A*A + B*B + C*C

        #if feq(denom,0):
        if denom == 0:
            return None, None
        else:
            Z = 1/np.sqrt(denom)
            s1 = (A*Z, B*Z, -C*Z)
            s2 = (-A*Z, -B*Z, C*Z)

    return s1, s2
Пример #5
0
    def get_xyz3(self):
        angle = self.max_angle
        x1, y1, z1 = self.xyz1
        x2, y2, z2 = self.xyz2
        
        c_angle, s_angle = np.cos(angle), np.sin(angle)
        if feq(s_angle,0):
            x3, y3, z3 = x2, y2, z2
        else:
            x3 = (x2 - x1*c_angle)/s_angle
            y3 = (y2 - y1*c_angle)/s_angle
            z3 = (z2 - z1*c_angle)/s_angle

        return (x3,y3,z3)
Пример #6
0
def test_avg_sequential_3_4_1():
    '''
    CubeMPI for AVG: Exact squential values (ne=3, ngq=4, nproc=1)
    '''
    ne, ngq = 3, 4

    nproc, myrank = 1, 0
    cubegrid = CubeGridMPI(ne, ngq, nproc, myrank, cs_grid_dpath)
    cubempi = CubeMPI(cubegrid, 'AVG', spmat_dpath)

    a_equal(cubegrid.local_gids, np.arange(6*ne*ne*ngq*ngq))
    a_equal(cubempi.recv_schedule.shape, (0,3))
    a_equal(cubempi.send_schedule.shape, (0,3))
    a_equal(cubempi.recv_buf_size, 6*ne*ne*12)
    a_equal(cubempi.send_buf_size, 0)


    #-----------------------------------------------------
    # Generate a sequential field on the cubed-sphere
    #-----------------------------------------------------
    f = np.arange(cubegrid.local_ep_size, dtype='f8')


    #-----------------------------------------------------
    # Average the element boundary for the spectral element method
    #-----------------------------------------------------
    recv_buf = np.zeros(cubempi.recv_buf_size, 'f8')
    send_buf = np.zeros(cubempi.send_buf_size, 'f8')

    pre_send(cubempi, f, recv_buf, send_buf)
    post_recv(cubempi, f, recv_buf)


    #-----------------------------------------------------
    # Check if mvps have same values
    #-----------------------------------------------------
    fs = [f]
    ranks, lids = cubegrid.ranks, cubegrid.lids

    cs_fpath = os.path.join(cs_grid_dpath, "cs_grid_ne{:03d}np{}.nc".format(ne, ngq))
    cs_ncf = nc.Dataset(cs_fpath, 'r', format='NETCDF4')
    mvps = cs_ncf.variables['mvps'][:]
    for seq, mvp in enumerate(mvps):
        eff_mvp = [k for k in mvp if k != -1]

        for gid in eff_mvp:
            rank, lid = ranks[gid], lids[gid]
            ok_( feq(fs[rank][lid], np.mean(eff_mvp), 15) )
Пример #7
0
def plane12_pt3(xyz1, xyz2, xyz3):
    '''
    plane generated by xyz1 and xyz2
    left if xyz3 is in normal vector direction
    '''

    plane = plane_origin(xyz1, xyz2)
    #nvec = normal_vector(xyz1, xyz2)
    #print np.dot(plane,nvec)       # > 0 

    val = np.dot(plane, xyz3)

    if feq(val,0):
        return 'straight'
    elif flt(val,0):
        return 'right'
    elif fgt(val,0):
        return 'left'
Пример #8
0
def xyz2xyp(X, Y, Z, R=1):
    assert feq(sqrt(X*X + Y*Y + Z*Z),R), 'The (x,y,z) (%s,%s,%s) is not on the sphere.'%(X,Y,Z)

    a = R/sqrt(3)
    at1, at2 = a*tan(-pi/4), a*tan(pi/4)

    xyp_dict = dict()


    if fgt(X,0):
        x, y = a*(Y/X), a*(Z/X)
        if flge(at1,x,at2) and flge(at1,y,at2):
            xyp_dict[1] = (x,y)

    elif flt(X,0):
        x, y = a*(Y/X), -a*(Z/X)
        if flge(at1,x,at2) and flge(at1,y,at2):
            xyp_dict[3] = (x,y)


    if fgt(Y,0):
        x, y = -a*(X/Y), a*(Z/Y)
        if flge(at1,x,at2) and flge(at1,y,at2):
            xyp_dict[2] = (x,y)

    elif flt(Y,0):
        x, y = -a*(X/Y), -a*(Z/Y)
        if flge(at1,x,at2) and flge(at1,y,at2):
            xyp_dict[4] = (x,y)


    if flt(Z,0):
        x, y = -a*(Y/Z), -a*(X/Z)
        if flge(at1,x,at2) and flge(at1,y,at2):
            xyp_dict[5] = (x,y)

    elif fgt(Z,0):
        x, y = a*(Y/Z), -a*(X/Z)
        if flge(at1,x,at2) and flge(at1,y,at2):
            xyp_dict[6] = (x,y)


    return xyp_dict
Пример #9
0
def check_avg_sequential_mpi(ne, ngq, comm):
    '''
    CubeMPI for AVG
    '''
    myrank = comm.Get_rank()
    nproc = comm.Get_size()

    cubegrid = CubeGridMPI(ne, ngq, nproc, myrank, cs_grid_dpath)
    cubempi = CubeMPI(cubegrid, 'AVG', spmat_dpath, comm=None)


    # Generate a sequential field on the cubed-sphere
    f = cubegrid.local_gids.astype('f8')

    # Average the element boundary for the spectral element method
    send_buf = np.zeros(cubempi.send_buf_size, 'f8')
    recv_buf = np.zeros(cubempi.recv_buf_size, 'f8')

    # Send/Recv
    pre_send(cubempi, f, recv_buf, send_buf)

    req_send_list = list()
    req_recv_list = list()

    for dest, start, size in cubempi.send_schedule:
        req = comm.Isend(send_buf[start:start+size], dest, 0)
        req_send_list.append(req)

    for dest, start, size in cubempi.recv_schedule:
        req = comm.Irecv(recv_buf[start:start+size], dest, 0)
        req_recv_list.append(req)

    MPI.Request.Waitall(req_send_list)
    MPI.Request.Waitall(req_recv_list)

    # After receive
    post_recv(cubempi, f, recv_buf)


    #-----------------------------------------------------
    # Check if mvps have same values
    #-----------------------------------------------------
    if myrank == 0:
        fs = [f]
        for src in range(1,nproc):
            size = cubegrid.local_ep_size
            fs.append( np.zeros(size, 'f8') )
            comm.Recv(fs[-1], src, 10)

        cs_fpath = cs_grid_dpath + "cs_grid_ne{:03d}np{}.nc".format(ne, ngq)
        cs_ncf = nc.Dataset(cs_fpath, 'r', format='NETCDF4')
        mvps = cs_ncf.variables['mvps'][:]
        ranks, lids = cubegrid.ranks, cubegrid.lids
        for seq, mvp in enumerate(mvps):
            eff_mvp = [k for k in mvp if k != -1]

            for gid in eff_mvp:
                rank, lid = ranks[gid], lids[gid]
                ok_( feq(fs[rank][lid], np.mean(eff_mvp), 15) )

    else:
        comm.Send(f, 0, 10)
Пример #10
0
def test_avg_sequential_3_4_3():
    '''
    CubeMPI for AVG: Exact squential values (ne=3, ngq=4, nproc=3)
    '''
    ne, ngq = 3, 4

    nproc = 3
    cubegrid0 = CubeGridMPI(ne, ngq, nproc, 0, cs_grid_dpath)
    cubempi0 = CubeMPI(cubegrid0, 'AVG', spmat_dpath)

    cubegrid1 = CubeGridMPI(ne, ngq, nproc, 1, cs_grid_dpath)
    cubempi1 = CubeMPI(cubegrid1, 'AVG', spmat_dpath)
    
    cubegrid2 = CubeGridMPI(ne, ngq, nproc, 2, cs_grid_dpath)
    cubempi2 = CubeMPI(cubegrid2, 'AVG', spmat_dpath)

    # Check send/recv pair in send_group and recv_group
    a_equal(list(cubempi0.send_group[1].keys()), cubempi1.recv_group[0])
    a_equal(list(cubempi0.send_group[2].keys()), cubempi2.recv_group[0])
    a_equal(list(cubempi1.send_group[0].keys()), cubempi0.recv_group[1])
    a_equal(list(cubempi1.send_group[2].keys()), cubempi2.recv_group[1])
    a_equal(list(cubempi2.send_group[0].keys()), cubempi0.recv_group[2])
    a_equal(list(cubempi2.send_group[1].keys()), cubempi1.recv_group[2])

    # Check send/recv pair in send_buf and recv_buf
    rank0, i0, n0 = cubempi0.send_schedule[0]   # send 0->1
    rank1, i1, n1 = cubempi1.recv_schedule[0]   # recv 
    a_equal(cubempi0.send_buf[i0:i0+n0], cubempi1.recv_buf[i1:i1+n1])

    rank0, i0, n0 = cubempi1.send_schedule[0]   # send 1->0
    rank1, i1, n1 = cubempi0.recv_schedule[0]   # recv
    a_equal(cubempi1.send_buf[i0:i0+n0], cubempi0.recv_buf[i1:i1+n1])

    rank0, i0, n0 = cubempi0.send_schedule[1]   # send 0->2
    rank1, i1, n1 = cubempi2.recv_schedule[0]   # recv
    a_equal(cubempi0.send_buf[i0:i0+n0], cubempi2.recv_buf[i1:i1+n1])

    rank0, i0, n0 = cubempi2.send_schedule[0]   # send 2->0
    rank1, i1, n1 = cubempi0.recv_schedule[1]   # recv
    a_equal(cubempi2.send_buf[i0:i0+n0], cubempi0.recv_buf[i1:i1+n1])

    rank0, i0, n0 = cubempi1.recv_schedule[1]   # send 1->2 
    rank1, i1, n1 = cubempi2.send_schedule[1]   # recv
    a_equal(cubempi1.recv_buf[i0:i0+n0], cubempi2.send_buf[i1:i1+n1])

    rank0, i0, n0 = cubempi2.recv_schedule[1]   # send 2->1 
    rank1, i1, n1 = cubempi1.send_schedule[1]   # recv
    a_equal(cubempi2.recv_buf[i0:i0+n0], cubempi1.send_buf[i1:i1+n1])


    #-----------------------------------------------------
    # Generate a sequential field on the cubed-sphere
    #-----------------------------------------------------
    f0 = cubegrid0.local_gids.astype('f8')
    f1 = cubegrid1.local_gids.astype('f8')
    f2 = cubegrid2.local_gids.astype('f8')


    #-----------------------------------------------------
    # Average the element boundary for the spectral element method
    #-----------------------------------------------------
    recv_buf0 = np.zeros(cubempi0.recv_buf_size, 'f8')
    send_buf0 = np.zeros(cubempi0.send_buf_size, 'f8')
    recv_buf1 = np.zeros(cubempi1.recv_buf_size, 'f8')
    send_buf1 = np.zeros(cubempi1.send_buf_size, 'f8')
    recv_buf2 = np.zeros(cubempi2.recv_buf_size, 'f8')
    send_buf2 = np.zeros(cubempi2.send_buf_size, 'f8')

    # Prepare to send
    pre_send(cubempi0, f0, recv_buf0, send_buf0)
    pre_send(cubempi1, f1, recv_buf1, send_buf1)
    pre_send(cubempi2, f2, recv_buf2, send_buf2)

    # Send/Recv
    rank0, i0, n0 = cubempi0.send_schedule[0]    # send 0->1
    rank1, i1, n1 = cubempi1.recv_schedule[0]
    recv_buf1[i1:i1+n1] = send_buf0[i0:i0+n0]

    rank1, i1, n1 = cubempi1.send_schedule[0]    # send 1->0
    rank0, i0, n0 = cubempi0.recv_schedule[0]
    recv_buf0[i0:i0+n0] = send_buf1[i1:i1+n1]

    rank1, i1, n1 = cubempi0.send_schedule[1]    # send 0->2
    rank0, i0, n0 = cubempi2.recv_schedule[0]
    recv_buf2[i0:i0+n0] = send_buf0[i1:i1+n1]

    rank1, i1, n1 = cubempi2.send_schedule[0]    # send 2->0
    rank0, i0, n0 = cubempi0.recv_schedule[1]
    recv_buf0[i0:i0+n0] = send_buf2[i1:i1+n1]

    rank1, i1, n1 = cubempi1.send_schedule[1]    # send 1->2
    rank0, i0, n0 = cubempi2.recv_schedule[1]
    recv_buf2[i0:i0+n0] = send_buf1[i1:i1+n1]

    rank1, i1, n1 = cubempi2.send_schedule[1]    # send 2->1
    rank0, i0, n0 = cubempi1.recv_schedule[1]
    recv_buf1[i0:i0+n0] = send_buf2[i1:i1+n1]

    # After receive
    post_recv(cubempi0, f0, recv_buf0)
    post_recv(cubempi1, f1, recv_buf1)
    post_recv(cubempi2, f2, recv_buf2)


    #-----------------------------------------------------
    # Check if mvps have same values
    #-----------------------------------------------------
    fs = [f0, f1, f2]
    ranks, lids = cubegrid0.ranks, cubegrid0.lids

    cs_fpath = cs_grid_dpath + "cs_grid_ne{:03d}np{}.nc".format(ne, ngq)
    cs_ncf = nc.Dataset(cs_fpath, 'r', format='NETCDF4')
    mvps = cs_ncf.variables['mvps'][:]
    for seq, mvp in enumerate(mvps):
        eff_mvp = [k for k in mvp if k != -1]

        for gid in eff_mvp:
            rank, lid = ranks[gid], lids[gid]
            ok_( feq(fs[rank][lid], np.mean(eff_mvp), 15) )