如何将笛卡尔问题转换为圆柱问题?
How to convert a cartesian problem in a cylindrical problem?
我使用 Pyvista 在笛卡尔系统中显示陀螺仪结构 (TPMS)。我现在尝试以柱坐标显示结构。 Pyvista 确实显示了一些圆柱形的东西,但似乎晶胞长度不均匀(虽然没有理由改变这个我的参数“a”是稳定的。这种变化似乎特别沿着 z 出现,但我不明白为什么(见图片).
我有这个:
这是我的代码的一部分。
感谢您的帮助。
import pyvista as pv
import numpy as np
from numpy import cos, sin, pi
from random import uniform
lattice_par = 1.0 # Unit cell length
a = (2*pi)/lattice_par
res = 200j
r, theta, z = np.mgrid[0:2:res, 0:2*pi:res, 0:4:res]
# consider using non-equidistant r for uniformity
def GyroidCyl(r, theta, z, b=0.8):
return (sin(a*(r*cos(theta) - 1))*cos(a*(r*sin(theta) - 1))
+ sin(a*(r*sin(theta) - 1))*cos(a*(z - 1))
+ sin(a*(z - 1))*cos(a*(r*cos(theta) - 1))
- b)
vol3 = GyroidCyl(r, theta, z)
# compute Cartesian coordinates for grid points
x = r * cos(theta)
y = r * sin(theta)
grid = pv.StructuredGrid(x, y, z)
grid["vol3"] = vol3.flatten()
contours3 = grid.contour([0]) # Isosurface = 0
pv.set_plot_theme('document')
p = pv.Plotter()
p.add_mesh(contours3, scalars=contours3.points[:, 2], show_scalar_bar=False, interpolate_before_map=True,
show_edges=False, smooth_shading=False, render=True)
p.show_axes_all()
p.add_floor()
p.show_grid()
p.add_title('Gyroid in cylindrical coordinates')
p.add_text('Volume Fraction Parameter = ' + str(b))
p.show(window_size=[2040, 1500])
所以您在评论中注意到您正在尝试复制某些东西,例如 this paper. What they do is take a regular gyroid unit cell, and then transform it to build a cylindrical shell. If igloos 中解释的策略是圆柱形的,然后陀螺仪单元将是一块雪砖。将它们并排放置并堆叠成一列,您将得到一个圆柱体。
由于我不能使用论文中的数字,我们必须自己重新创建一些。因此,您必须从隐式函数
定义的常规 gyroid 开始
cos(x) sin(y) + cos(y) sin(z) + cos(z) sin(x) = 0
(或其某些变体)。这是单个晶胞的外观:
import pyvista as pv
import numpy as np
res = 100j
a = 2*np.pi
x, y, z = np.mgrid[0:a:res, 0:a:res, 0:a:res]
def Gyroid(x, y, z):
return np.cos(x)*np.sin(y) + np.cos(y)*np.sin(z) + np.cos(z)*np.sin(x)
# compute implicit function
fun_values = Gyroid(x, y, z)
# create grid for contouring
grid = pv.StructuredGrid(x, y, z)
grid["vol3"] = fun_values.ravel('F')
contours3 = grid.contour([0]) # isosurface for 0
# plot the contour, i.e. the gyroid
pv.set_plot_theme('document')
plotter = pv.Plotter()
plotter.add_mesh(contours3, scalars=contours3.points[:, -1],
show_scalar_bar=False)
plotter.add_bounding_box()
plotter.enable_terrain_style()
plotter.show_axes()
plotter.show()
使用“晶胞”一词意味着存在一个潜在的无限晶格,可以通过将这些 (rectangular) 晶胞整齐地并排堆叠来构建。通过一些想象,我们可以说服自己这是真的。或者我们可以查看公式并注意,由于三角函数,该函数在 x
、y
和 z
中具有周期性,周期为 2*pi
。这也告诉我们,我们可以通过引入晶格参数 a
、b
和 c
:
将晶胞转换为具有任意 rectangular 维度
cos(kx x) sin(ky y) + cos(ky y) sin(kz z) + cos(kz z) sin(kx x) = 0, where
kx = 2 pi/a
ky = 2 pi/b
kz = 2 pi/c
(这些kx
、ky
和kz
量在固体物理学中称为波矢。)
对应的变化只影响header:
res = 100j
a, b, c = lattice_params = 1, 2, 3
kx, ky, kz = [2*np.pi/lattice_param for lattice_param in lattice_params]
x, y, z = np.mgrid[0:a:res, 0:b:res, 0:c:res]
def Gyroid(x, y, z):
return ( np.cos(kx*x)*np.sin(ky*y)
+ np.cos(ky*y)*np.sin(kz*z)
+ np.cos(kz*z)*np.sin(kx*x))
这就是我们的起点。我们要做的是拿这个单元格,将它弯曲,使其对应圆柱体上的 30 度圆弧,然后使用这个单元堆叠圆柱体。根据该论文,他们使用 12 个晶胞在平面上创建一个圆(因此有 30 度幻数),并将三个这样的圆带堆叠在一起以构建圆柱体。
实际的映射在论文中也有相当清楚的解释。而函数的原始 x
、y
和 z
参数基本上分别插值在 [0, a]
、[0, b]
和 [0, c]
之间,在新的setup x
在半径范围 [r1, r2]
内插值,y
在 angular 范围内插值 [0, pi/6]
而 z
就是 z
。 (在论文中 x
和 y
似乎与此约定相反,但这应该无关紧要。如果重要,那将作为 reader 的练习。)
所以我们需要做的是或多或少保留当前的格点,但是将对应的x
、y
和z
格点进行变换,使它们位于一个汽缸代替。这是一个镜头:
import pyvista as pv
import numpy as np
res = 100j
a, b, c = lattice_params = 1, 1, 1
kx, ky, kz = [2*np.pi/lattice_param for lattice_param in lattice_params]
r_aux, phi, z = np.mgrid[0:a:res, 0:b:res, 0:3*c:res]
# convert r_aux range to actual radii
r1, r2 = 1.5, 2
r = r2/a*r_aux + r1/a*(1 - r_aux)
def Gyroid(x, y, z):
return ( np.cos(kx*x)*np.sin(ky*y)
+ np.cos(ky*y)*np.sin(kz*z)
+ np.cos(kz*z)*np.sin(kx*x))
# compute data for cylindrical gyroid
# r_aux is x, phi / 12 is y and z is z
fun_values = Gyroid(r_aux, phi * 12, z)
# compute Cartesian coordinates for grid points
x = r * np.cos(phi*ky)
y = r * np.sin(phi*ky)
grid = pv.StructuredGrid(x, y, z)
grid["vol3"] = fun_values.ravel('F')
contours3 = grid.contour([0])
# plot cylindrical gyroid
pv.set_plot_theme('document')
plotter = pv.Plotter()
plotter.add_mesh(contours3, scalars=contours3.points[:, -1],
show_scalar_bar=False)
plotter.add_bounding_box()
plotter.show_axes()
plotter.enable_terrain_style()
plotter.show()
如果您想查看圆柱形设置中的单个变换晶胞,请对函数使用 phi
和 z
的单个定义域,并且仅转换为 1/12 个完整的圆对于网格点:
fun_values = Gyroid(r_aux, phi, z/3)
# compute Cartesian coordinates for grid points
x = r * np.cos(phi*ky/12)
y = r * np.sin(phi*ky/12)
grid = pv.StructuredGrid(x, y, z/3)
但是在(不再是)晶胞中看到曲率并不容易:
我使用 Pyvista 在笛卡尔系统中显示陀螺仪结构 (TPMS)。我现在尝试以柱坐标显示结构。 Pyvista 确实显示了一些圆柱形的东西,但似乎晶胞长度不均匀(虽然没有理由改变这个我的参数“a”是稳定的。这种变化似乎特别沿着 z 出现,但我不明白为什么(见图片).
我有这个:
感谢您的帮助。
import pyvista as pv
import numpy as np
from numpy import cos, sin, pi
from random import uniform
lattice_par = 1.0 # Unit cell length
a = (2*pi)/lattice_par
res = 200j
r, theta, z = np.mgrid[0:2:res, 0:2*pi:res, 0:4:res]
# consider using non-equidistant r for uniformity
def GyroidCyl(r, theta, z, b=0.8):
return (sin(a*(r*cos(theta) - 1))*cos(a*(r*sin(theta) - 1))
+ sin(a*(r*sin(theta) - 1))*cos(a*(z - 1))
+ sin(a*(z - 1))*cos(a*(r*cos(theta) - 1))
- b)
vol3 = GyroidCyl(r, theta, z)
# compute Cartesian coordinates for grid points
x = r * cos(theta)
y = r * sin(theta)
grid = pv.StructuredGrid(x, y, z)
grid["vol3"] = vol3.flatten()
contours3 = grid.contour([0]) # Isosurface = 0
pv.set_plot_theme('document')
p = pv.Plotter()
p.add_mesh(contours3, scalars=contours3.points[:, 2], show_scalar_bar=False, interpolate_before_map=True,
show_edges=False, smooth_shading=False, render=True)
p.show_axes_all()
p.add_floor()
p.show_grid()
p.add_title('Gyroid in cylindrical coordinates')
p.add_text('Volume Fraction Parameter = ' + str(b))
p.show(window_size=[2040, 1500])
所以您在评论中注意到您正在尝试复制某些东西,例如 this paper. What they do is take a regular gyroid unit cell, and then transform it to build a cylindrical shell. If igloos 中解释的策略是圆柱形的,然后陀螺仪单元将是一块雪砖。将它们并排放置并堆叠成一列,您将得到一个圆柱体。
由于我不能使用论文中的数字,我们必须自己重新创建一些。因此,您必须从隐式函数
定义的常规 gyroid 开始cos(x) sin(y) + cos(y) sin(z) + cos(z) sin(x) = 0
(或其某些变体)。这是单个晶胞的外观:
import pyvista as pv
import numpy as np
res = 100j
a = 2*np.pi
x, y, z = np.mgrid[0:a:res, 0:a:res, 0:a:res]
def Gyroid(x, y, z):
return np.cos(x)*np.sin(y) + np.cos(y)*np.sin(z) + np.cos(z)*np.sin(x)
# compute implicit function
fun_values = Gyroid(x, y, z)
# create grid for contouring
grid = pv.StructuredGrid(x, y, z)
grid["vol3"] = fun_values.ravel('F')
contours3 = grid.contour([0]) # isosurface for 0
# plot the contour, i.e. the gyroid
pv.set_plot_theme('document')
plotter = pv.Plotter()
plotter.add_mesh(contours3, scalars=contours3.points[:, -1],
show_scalar_bar=False)
plotter.add_bounding_box()
plotter.enable_terrain_style()
plotter.show_axes()
plotter.show()
使用“晶胞”一词意味着存在一个潜在的无限晶格,可以通过将这些 (rectangular) 晶胞整齐地并排堆叠来构建。通过一些想象,我们可以说服自己这是真的。或者我们可以查看公式并注意,由于三角函数,该函数在 x
、y
和 z
中具有周期性,周期为 2*pi
。这也告诉我们,我们可以通过引入晶格参数 a
、b
和 c
:
cos(kx x) sin(ky y) + cos(ky y) sin(kz z) + cos(kz z) sin(kx x) = 0, where
kx = 2 pi/a
ky = 2 pi/b
kz = 2 pi/c
(这些kx
、ky
和kz
量在固体物理学中称为波矢。)
对应的变化只影响header:
res = 100j
a, b, c = lattice_params = 1, 2, 3
kx, ky, kz = [2*np.pi/lattice_param for lattice_param in lattice_params]
x, y, z = np.mgrid[0:a:res, 0:b:res, 0:c:res]
def Gyroid(x, y, z):
return ( np.cos(kx*x)*np.sin(ky*y)
+ np.cos(ky*y)*np.sin(kz*z)
+ np.cos(kz*z)*np.sin(kx*x))
这就是我们的起点。我们要做的是拿这个单元格,将它弯曲,使其对应圆柱体上的 30 度圆弧,然后使用这个单元堆叠圆柱体。根据该论文,他们使用 12 个晶胞在平面上创建一个圆(因此有 30 度幻数),并将三个这样的圆带堆叠在一起以构建圆柱体。
实际的映射在论文中也有相当清楚的解释。而函数的原始 x
、y
和 z
参数基本上分别插值在 [0, a]
、[0, b]
和 [0, c]
之间,在新的setup x
在半径范围 [r1, r2]
内插值,y
在 angular 范围内插值 [0, pi/6]
而 z
就是 z
。 (在论文中 x
和 y
似乎与此约定相反,但这应该无关紧要。如果重要,那将作为 reader 的练习。)
所以我们需要做的是或多或少保留当前的格点,但是将对应的x
、y
和z
格点进行变换,使它们位于一个汽缸代替。这是一个镜头:
import pyvista as pv
import numpy as np
res = 100j
a, b, c = lattice_params = 1, 1, 1
kx, ky, kz = [2*np.pi/lattice_param for lattice_param in lattice_params]
r_aux, phi, z = np.mgrid[0:a:res, 0:b:res, 0:3*c:res]
# convert r_aux range to actual radii
r1, r2 = 1.5, 2
r = r2/a*r_aux + r1/a*(1 - r_aux)
def Gyroid(x, y, z):
return ( np.cos(kx*x)*np.sin(ky*y)
+ np.cos(ky*y)*np.sin(kz*z)
+ np.cos(kz*z)*np.sin(kx*x))
# compute data for cylindrical gyroid
# r_aux is x, phi / 12 is y and z is z
fun_values = Gyroid(r_aux, phi * 12, z)
# compute Cartesian coordinates for grid points
x = r * np.cos(phi*ky)
y = r * np.sin(phi*ky)
grid = pv.StructuredGrid(x, y, z)
grid["vol3"] = fun_values.ravel('F')
contours3 = grid.contour([0])
# plot cylindrical gyroid
pv.set_plot_theme('document')
plotter = pv.Plotter()
plotter.add_mesh(contours3, scalars=contours3.points[:, -1],
show_scalar_bar=False)
plotter.add_bounding_box()
plotter.show_axes()
plotter.enable_terrain_style()
plotter.show()
如果您想查看圆柱形设置中的单个变换晶胞,请对函数使用 phi
和 z
的单个定义域,并且仅转换为 1/12 个完整的圆对于网格点:
fun_values = Gyroid(r_aux, phi, z/3)
# compute Cartesian coordinates for grid points
x = r * np.cos(phi*ky/12)
y = r * np.sin(phi*ky/12)
grid = pv.StructuredGrid(x, y, z/3)
但是在(不再是)晶胞中看到曲率并不容易: