Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算CFD网格中点之间的距离_Python_Numpy - Fatal编程技术网

Python 计算CFD网格中点之间的距离

Python 计算CFD网格中点之间的距离,python,numpy,Python,Numpy,我有一个结构化网格,大约有3e+6个点和 请查看图片: 物理域(欧几里德)中的每个点在计算域中都有一个索引(i、j和k) 我需要迭代计算域索引,并使用相应的点进行计算 例如,给定索引处方向i的长度为(伪代码): 长度=向量长度(点(i+1,j,k)-点(i,j,k)) 此外,找出给定点的长度比也很重要。例如,我将计算方向I附近的两个长度,并在它们之间进行分割 我想出来的东西花了太多时间,而且可能没有充分发挥NumPy的潜力 我制作了一个包含所有网格XYZ坐标的零的数组 block_data =

我有一个结构化网格,大约有3e+6个点和

请查看图片:

物理域(欧几里德)中的每个点在计算域中都有一个索引(i、j和k)

我需要迭代计算域索引,并使用相应的点进行计算

例如,给定索引处方向i的长度为(伪代码): 长度=向量长度(点(i+1,j,k)-点(i,j,k))

此外,找出给定点的长度比也很重要。例如,我将计算方向I附近的两个长度,并在它们之间进行分割

我想出来的东西花了太多时间,而且可能没有充分发挥NumPy的潜力

我制作了一个包含所有网格XYZ坐标的零的数组

block_data =numpy.zeros((i_dim,  j_dim, k_dim, 3), dtype='float')
数字3对应3个元素,x、y和z

因此,如果我想得到I=3,j=7,k=10的z值,它应该是:

Z = block_data[3][7][10][2]
欧几里德空间中的一个点是(1,3)ndarray:

我计算两点之间长度的方法是:

numpy.linalg.norm(point2 - point1)
仅长度计算大约需要1.5毫秒,我想计算所有点和所有方向的距离: 3e+6*3

我认为我构造主块Ndaray(块_数据)的方法存在问题,因为它限制了我一次只在两个点上进行计算,也就是说只有两个小的(1,3)ndarray。 如果我没记错的话,在小阵列上进行计算效率不高


如何解决该问题并加快运行时间?对于这类问题,有没有推荐书?谢谢:-)

要计算这种大小数组中的欧几里德距离,我建议使用矢量化方法:

def euclid_dist(array, direction):
    if direction == 'i':  # make shifted views depending on the direction
        p1 = array[:-1, :, :]
        p2 = array[1:, :, :]
    elif direction == 'j':
        p1 = array[:, :-1, :]
        p2 = array[:, 1:, :]
    elif direction == 'k':
        p1 = array[:, :, :-1]
        p2 = array[:, :, 1:]
    else:
        raise ValueError('direction ' + direction + ' not known.')

    # get euclidean distance for all points in direction:
    euc_dist = (((p1 - p2)*(p1 - p2)).sum(axis=3))**0.5

    return euc_dist
使用具有以下功能的小型测试阵列:

arr = np.random.randint(-20, 20, 5*5*5*3).reshape(5, 5, 5, 3)
eu_i = euclid_dist(arr, 'i')
eu_j = euclid_dist(arr, 'j')
# test some values:
print(eu_i[2, 1, 2] == np.linalg.norm(arr[2, 1, 2] - arr[3, 1, 2]))
# Out 64: True
print(eu_j[1, 1, 1] == np.linalg.norm(arr[1, 1, 1] - arr[1, 2, 1]))
# Out 65: True
具有
8e6
点和
24e6
值的大型阵列的一些计时:

big_arr = np.random.rand(200, 200, 200, 3)
%timeit euclid_dist(big_arr, 'i')
# 644 ms ± 57.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

对于这样大小的数组,这是非常快的。:)如果我正确阅读了您的计时,这大约比您的代码快19000倍。

对于具有矩形网格的三维笛卡尔空间中的一个点,每个点有6个相邻点。所以你想计算到每个相邻点的距离,这意味着每个点有6个距离(不包括边界上的点)?@Scotty1-否。我想在计算域中选择一个特定的方向(对于照片中的2D示例,我可以在I或j之间选择)计算到前面下一个索引点的距离(假设我选择I,我想知道I=5处的长度,所以我将得到I=6处的点,并计算它们之间的范数)事情是我需要计算比率,这更重要,但对于比率,我需要计算两个长度。好的,如果您只需要计算两个长度,而不需要更多,那么您可以坚持使用您的方法。如果你想在一个步骤中计算很多长度,使用矢量化的方法是值得的,但不是两个长度。@Scotty1-例如,如果我需要找出方向I上的最大比率,则需要在整个网格上迭代(当然,需要检查每个j索引。因此对于I*j倍的2D网格)并找到最大值。如果你只需要一个长度,它就可以工作,但是,如我所说,如果你想知道最大比率是多少,那么“length”方法将执行3e+6次减去边界。在ndarray上运行np.linalg.norm()需要1.5e-3。这将花费太多的时间。我添加了一个解决方案,应该会快得多。只是添加了这个到我的代码与一个选项,以找到最大比率,它的工作非常好!不得不说我学到了很多。谢谢:-)
big_arr = np.random.rand(200, 200, 200, 3)
%timeit euclid_dist(big_arr, 'i')
# 644 ms ± 57.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)