简体   繁体   中英

Interpolate 3D Vector Field with Python

The task

I would like to interpolate a 3D vector field using python.

intial grid -> asociated u,v,w => new grid --> compute associated u,v,w

What I have done so far:

Code to create a sample vector field:

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import RegularGridInterpolator

# REDUCED EXAMPLE
Nx = 8
Ny = 8
Nz = 3
grid = np.meshgrid(np.linspace(-1, 1, Nx),
                   np.linspace(-1, 1, Ny),
                   np.linspace(-1, 1, Nz))

x,y,z = grid

# CONSTRUCT u,v,w 
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
     np.sin(np.pi * z))

fig = plt.figure(dpi=300)
ax = fig.gca(projection='3d')
ax.quiver(x, y, z, u, v, w, length=0.2)
plt.title("Reduced")
plt.show()

在此处输入图像描述

... I tried to create an interpolation function:

def interpolate_field(old_points,u,v,w,new_points):
    # old points zip(x,y,z) where x,y,z linspace -> regular grid
    # u,v,w each of shape (NX, NY, NZ)
    # mew points np.array(list(zip(xx,yy,zz))) where xx,yy,zz np.meshgrid
    
    x, y, z = old_points

    u_int_f = RegularGridInterpolator((x, y, z), u)
    v_int_f = RegularGridInterpolator((x, y, z), v)
    w_int_f = RegularGridInterpolator((x, y, z), w)
    

    u_int = u_int_f(new_points)
    v_int = v_int_f(new_points)
    w_int = w_int_f(new_points)
    
    return u_int, v_int, w_int

..but when I try to apply it:+

# New grid
NNx = 20
NNy = 20
NNz = 3
grid = np.meshgrid(np.linspace(-1, 1, NNx),
                   np.linspace(-1, 1, NNy),
                   np.linspace(-1, 1, NNz))
    
# Reshape for interpolation function
u_reshape = np.reshape(u, (Nx, Ny, Nz))
v_reshape = np.reshape(v, (Nx, Ny, Nz))
w_reshape = np.reshape(w, (Nx, Ny, Nz))


old_points = (x,y,z)
new_points = np.vstack(list(map(np.ravel, grid))).T

u_int, v_int, w_int = interpolate_field(old_points,
                  u_reshape,
                  v_reshape,
                  w_reshape,
                  new_points)

I get the error:

ValueError: The points in dimension 0 must be strictly ascending

RegularGridInterpolator requires a tuple of points before the meshgrid was applied

Parameters points

tuple of ndarray of float, with shapes (m1, ), …, (mn, ) The points defining the regular grid in n dimensions

So you can either pass in the grid beforehand:

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import RegularGridInterpolator

def interpolate_field(old_points,u,v,w,new_points):
    # old points zip(x,y,z) where x,y,z linspace -> regular grid
    # u,v,w each of shape (NX, NY, NZ)
    # mew points np.array(list(zip(xx,yy,zz))) where xx,yy,zz np.meshgrid
    
    x, y, z = old_points


    u_int_f = RegularGridInterpolator((x, y, z), u)
    v_int_f = RegularGridInterpolator((x, y, z), v)
    w_int_f = RegularGridInterpolator((x, y, z), w)
    

    u_int = u_int_f(new_points)
    v_int = v_int_f(new_points)
    w_int = w_int_f(new_points)
    
    return u_int, v_int, w_int

# New grid
Nx = 20
Ny = 20
Nz = 3

x = np.linspace(-1, 1, Nx)
y = np.linspace(-1, 1, Ny)
z = np.linspace(-1, 1, Nz)

grid = np.meshgrid(x, y, z)

XX, YY, ZZ = grid

# CONSTRUCT u,v,w 
u = np.sin(np.pi * XX) * np.cos(np.pi * YY) * np.cos(np.pi * ZZ)
v = -np.cos(np.pi * XX) * np.sin(np.pi * YY) * np.cos(np.pi * ZZ)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * XX) * np.cos(np.pi * YY) *
     np.sin(np.pi * ZZ))


# Reshape for interpolation function
u_reshape = np.reshape(u, (Nx, Ny, Nz))
v_reshape = np.reshape(v, (Nx, Ny, Nz))
w_reshape = np.reshape(w, (Nx, Ny, Nz))


old_points = (x,y,z)
new_points = np.vstack(list(map(np.ravel, grid))).T

u_int, v_int, w_int = interpolate_field(old_points,
                  u_reshape,
                  v_reshape,
                  w_reshape,
                  new_points)

Or you can try and inverse the meshgrid from within the interpolate_field function

EDIT:

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import RegularGridInterpolator

def interpolate_field(old_points,u,v,w,new_points):
    # old points zip(x,y,z) where x,y,z linspace -> regular grid
    # u,v,w each of shape (NX, NY, NZ)
    # mew points np.array(list(zip(xx,yy,zz))) where xx,yy,zz np.meshgrid
    
    x, y, z = old_points
    x = x[0, :, 0]
    y = y[:, 0, 0]
    z = z[0, 0, :]

    u_int_f = RegularGridInterpolator((x, y, z), u)
    v_int_f = RegularGridInterpolator((x, y, z), v)
    w_int_f = RegularGridInterpolator((x, y, z), w)
    

    u_int = u_int_f(new_points)
    v_int = v_int_f(new_points)
    w_int = w_int_f(new_points)
    
    return u_int, v_int, w_int

# New grid
NNx = 20
NNy = 20
NNz = 3

x = np.linspace(-1, 1, NNx)
y = np.linspace(-1, 1, NNy)
z = np.linspace(-1, 1, NNz)

grid = np.meshgrid(np.linspace(-1, 1, NNx),
                   np.linspace(-1, 1, NNy),
                   np.linspace(-1, 1, NNz))

x,y,z = grid

# CONSTRUCT u,v,w 
u = np.sin(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x) * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.cos(np.pi * y) *
     np.sin(np.pi * z))


# Reshape for interpolation function
u_reshape = np.reshape(u, (NNx, NNy, NNz))
v_reshape = np.reshape(v, (NNx, NNy, NNz))
w_reshape = np.reshape(w, (NNx, NNy, NNz))


old_points = (x,y,z)
new_points = np.vstack(list(map(np.ravel, grid))).T

u_int, v_int, w_int = interpolate_field(old_points,
                  u_reshape,
                  v_reshape,
                  w_reshape,
                    new_points)

u_int = np.reshape(u_int, (NNx,NNy,NNz))
v_int = np.reshape(v_int, (NNx,NNy,NNz))
w_int = np.reshape(w_int, (NNx,NNy,NNz))
fig = plt.figure(dpi=300)
ax = fig.gca(projection='3d')
ax.quiver(x, y, z, u_int, v_int, w_int, length=0.2)
plt.title("Reduced")
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM