有两个嘴的凹六边形的标准网格?
Standard mesh for Concave Hexagons with two Mouths?
我正在计划通过具有两个嘴的凹双对称六边形的流动可视化。
边d1的长度等于边d2的另一个长度的例子:
我最初讨论了关于不规则六边形的命名 here。
有标准的 Mesh 工具,您可以在其中绘制自己的网格,但我想要一些标准库,这样我以后可以更好地与其他人合作进行流动模拟。
我没有在 MathCentral File Exchange here 中找到任何六边形网格库。
是否有针对不规则六边形的标准网格库?
我也对任何其他语言持开放态度,因为我可以阅读代码并将这些标准转换为 Matlab 库。
例如,您可以查看 Alexandra Baumgart 和 Hazuki Okuda 使用 Mathematica 完成的示例。这是通过 Manipulate 实现的,有效地创建了一个基本的 UI.
代码:
Manipulate[
Grid[{{Show[
ParametricPlot3D[{1.25Cos[t], 1.25 Sin[t],s+2-2w},{s,0,.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],2.25-2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],2-2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{1.25Cos[t], 1.25 Sin[t],s-2.25+2w},{s,0,.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],-2.25+2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None],
ParametricPlot3D[{r Cos[t], r Sin[t],-2+2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Max[0,-s+2 ]},{s,Min[2-(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w,1.99],2},{t,0, 2 Pi},PlotStyle->Directive[Opacity[1],Hue[a]],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],Max[0,(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w]},{r,0, .000000000001+w+((2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w)/2},{t,0,2Pi},PlotStyle->Directive[Opacity[1], Hue[a]],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t], Min[0,-(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)]},{r, 0, .00000000001+w+((2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w)/2},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Hue[a]],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Min[0,s -2 ]},{s,w,2},{t,0, 2 Pi},PlotStyle->Directive[Opacity[.2],Gray],Mesh->None, Lighting->"Neutral"],ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Max[0,-s + 2 - w]},{s,w,2},{t,0, 2 Pi},PlotStyle->Directive[Opacity[.2],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Min[0,s-2+ w]},{s,w,Min[2-(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w,2]},{t,0, 2 Pi},Mesh->None, PlotStyle->Directive[Opacity[1],Hue[a]], Lighting->"Neutral"], ParametricPlot3D[{(w/2) Cos[t],(w/2) Sin[t], b},{t,0,2Pi}, {b, -2 + w, 0}, PlotStyle->Directive[Opacity[1], Hue[a]],Mesh->None, Lighting->"Neutral"],PlotRange->All,ImageSize->{300,300}, SphericalRegion-> True]},{Row[{Text["time to empty = "], Text[2Pi (.04)/(3w^2)],Text[" seconds"]}]}}],{start,ControlType->None},{end,ControlType->None},
{{V,.01,"time (seconds)"},0.01,34,.01,ControlType->Animator,AnimationRate->1,AnimationRunning->False,ImageSize->Small},
{{w,.05,"neck width (millimeters)"}, .05, .3,.01,Appearance->"Labeled"},
{{a,0,"color of sand"}, 0, 1,Appearance->"Labeled"}]
如果这是作为纯粹的表示层替代,那么它实际上取决于模拟的输出和您 select 的表示。
例如,如果模拟输出一个变量(例如其中一个隔间的体积),则可以将其直接分配给可视化的属性,例如 "top" 帽的位置一个圆柱体。 "complementary" 圆柱体可以站在前一个圆柱体的顶部,其底盖坐标分配给 (totalVolume-lowerCompartmentVolume)。
在这种情况下,可视化只是一个仪表板,不会反馈到模拟中(例如,模拟通常不会考虑对象碰撞或接近)。
为了概括这一点,我们讨论的是将一组数量分配给一组可视化属性的解决方案。
从这个角度来看,可以使用 VRML(或 X3D)创建一组复杂的对象,它们的属性可以直接绑定到模拟输出,并且每第 n 个模拟时间步触发一次渲染。
要创建 "scene" 或可视化对象,您可以手动使用 blender which can export VRML scenes, or write the VRML 等软件(这确实是一项简单的任务)。
在基础设施方面,MATLAB有VRML toolkit and Python has a really wide selection of modules by which VRML can be handled (please see this and this例如link。
更具体的例子:
给定一些模拟输出 y
和模板 VRML 文件,例如:
#VRML V2.0 utf8
Transform {
translation 0 0 0
children [
Shape { geometry Box {2,2,zSize} }
]
}
你可以这样做:
data = (Read contents of VRML file as string data).
for n in [0..1000]:
y = getSimulationOutput(aParameterVector)
renderData = substitute(data, "zSize", y) #This function could be provided by a template module like jinja for example.
simulationFrame = renderVRML(renderData)
saveImage(simulationFrame)
(请注意:可以找到有关 Jinja 的更多信息 here - 内联评论 link 上面未正确呈现。)
返回文件并将不同的元素绑定到不同的数量(例如,更改可以旋转、缩放、平移框的变换,或通过分配不同的颜色来更改框的外观),您可以为您的模拟创建任何类型的 "dashboard" 输出....包括不规则六边形。
此技术是 Data Driven Documents 的直接应用,但在此处应用于不同的基材(不同于 HTML 或 SVG)。
希望这对您有所帮助。
想建立一个标准的网格库,我想应该从确定自由度开始。
对于有 2 个嘴的凹双对称六边形,它可以是:
- 口斧宽度(W_m)
- 相对顶部宽度 (w_t = W_t / W_m)
- 相对底部宽度(w_b = W_b / W_m)
- 相对顶部高度
- 相对底部高度
Margus 和 A_A 的回答将有助于实现。
如果您的目标是在 matlab 中可视化此类六边形,那么 fill
and fill3
应该可以做到。这是一个示例代码,它假设您的六边形由两个宽度 w1
和 w2
以及 d1
和 d2
参数参数化,它们是边的长度:
function draw_hexagon(w1, w2, d1, d2)
a=(w1-w2)/2;
b1=sqrt(d1^2 - a^2);
b2=sqrt(d2^2 - a^2);
xs=[-w1/2, w1/2, w2/2, w1/2, -w1/2, -w2/2];
ys=[b1, b1, 0, -b2, -b2, 0];
fill(xs, ys, 'b')
axis square
grid on
end
它将为 w1=4, w2=2, d1=2, d2=3
生成以下内容:
对于 3D 也类似:
function draw_hexagon_3d(w1, w2, d1, d2)
a=(w1-w2)/2;
b1=sqrt(d1^2 - a^2);
b2=sqrt(d2^2 - a^2);
xs=[-w1/2, w1/2, w2/2, w1/2, -w1/2, -w2/2];
ys=[0, 0, 0, 0, 0, 0];
zs=[b1, b1, 0, -b2, -b2, 0];
fill3(xs, ys, zs, 'b')
grid on
axis square
end
我们得到:
我和同事讨论过这个问题。
他鼓励创建一个三角形网络,但也指出了非凸多边形的通用算法。
通过自己的算法创建Mesh
- 如问题正文所示,用虚线将六边形分成两个梯形
- 将梯形分成三角形:
assemmbly
并通过inittri
构建三边形结构
- 加载向量
f
由bilin_assembly
构建(因为这以前有效但不一定是最佳选择)
有两个嘴的六边形分成两个梯形
- 取六个节点中索引差为三且距离最小的两个节点。
- 组成两个梯形,一个梯形的数字为 1-4,另一个梯形的数字为 1,6,5,4。
以下语法基于我 2013 年的代码版本,但主要基于 Claes Johnson 着的书有限元法对偏微分方程的数值解一书的描述。
为简单起见,现在考虑的汇编语法是泊松问题(稍后必须在此处细化)
% [S,f]=assemblyGlobal(loadfunction,mesh)
%
% loadfunction = function on the right-hand side of the Poisson equation
% mesh = mesh structure on which the assembly is done
%
% S = stiffness matrix of the Poisson problem
% f = load vector corresponding to loadfunction
我们需要双线性汇编的语法
% function B=bilin_assembly(bilin,mesh)
%
% bilin = function handle to integrand of the bilinear form
% given as bilin(u,v,ux,uy,vx,vy,x,y), where
% u - values of function u
% v - values of function v
% ux - x-derivative of function u
% uy - y-derivative of function u
% vx - x-derivative of function v
% vy - y-derivative of function v
% x - global x-coordinate
% y - global y-coordinate
% mesh = mesh structure on which the matrix will be assembled
%
% B = matrix related to bilinear form bilin
初始化三角网格的语法
% function mesh = inittri(p,t)
%
% p = nodes
% t = triangles
%
% mesh = trimesh structure corresponding to (p,t)
%
% TRIMESH STRUCTURE :
%
% p = nodes in a 2xN-matrix
%
% t = triangles in a 3xN- matrix (nodes of the triangles as indeces to the p- matrix).
%
% edges = a matrix of all edges in the mesh. Each column is an edge :
% [n1 ; n2] where n1 < n2;
%
% t2e = a matrix connecting triangle's and edges's.
% Each column corresponds to a triangle and has
% triangle's edges in the order n1->n2, n2->n3,
% n1->n3.
%
% e2t = inverse of t2e.
由于版权问题,我没有post这里提供完整的源代码,他们会让答案变得相当长。
但是,所有算法都基于第一个来源,因此这里的任何研究人员都可以创建。
我认为这种 FEM 方法是在这里找到最佳网格的唯一方法。
一般非凸多边形的算法
还有一些算法可以为一般的非凸多边形创建网格。
Margus 的 提供的网格可能是由这样的算法生成的。
Ansys
我正在体验有关可视化孔、不同几何形状和不同材料的不同产品。
Ansys 在这里是有前途的解决方案。
来源
- Claes Johnson 的有限元法偏微分方程的数值解。
- Class我大学有限元方法的笔记,2013-2014
我正在计划通过具有两个嘴的凹双对称六边形的流动可视化。
边d1的长度等于边d2的另一个长度的例子:
我最初讨论了关于不规则六边形的命名 here。
有标准的 Mesh 工具,您可以在其中绘制自己的网格,但我想要一些标准库,这样我以后可以更好地与其他人合作进行流动模拟。 我没有在 MathCentral File Exchange here 中找到任何六边形网格库。
是否有针对不规则六边形的标准网格库? 我也对任何其他语言持开放态度,因为我可以阅读代码并将这些标准转换为 Matlab 库。
例如,您可以查看 Alexandra Baumgart 和 Hazuki Okuda 使用 Mathematica 完成的示例。这是通过 Manipulate 实现的,有效地创建了一个基本的 UI.
代码:
Manipulate[
Grid[{{Show[
ParametricPlot3D[{1.25Cos[t], 1.25 Sin[t],s+2-2w},{s,0,.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],2.25-2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],2-2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{1.25Cos[t], 1.25 Sin[t],s-2.25+2w},{s,0,.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],-2.25+2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None],
ParametricPlot3D[{r Cos[t], r Sin[t],-2+2w},{r,0,1.25},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Max[0,-s+2 ]},{s,Min[2-(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w,1.99],2},{t,0, 2 Pi},PlotStyle->Directive[Opacity[1],Hue[a]],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t],Max[0,(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w]},{r,0, .000000000001+w+((2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w)/2},{t,0,2Pi},PlotStyle->Directive[Opacity[1], Hue[a]],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{r Cos[t], r Sin[t], Min[0,-(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)]},{r, 0, .00000000001+w+((2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w)/2},{t,0,2Pi},PlotStyle->Directive[Opacity[1],Hue[a]],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Min[0,s -2 ]},{s,w,2},{t,0, 2 Pi},PlotStyle->Directive[Opacity[.2],Gray],Mesh->None, Lighting->"Neutral"],ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Max[0,-s + 2 - w]},{s,w,2},{t,0, 2 Pi},PlotStyle->Directive[Opacity[.2],Gray],Mesh->None, Lighting->"Neutral"],
ParametricPlot3D[{(1-s/2) Cos[t],(1-s/2) Sin[t],Min[0,s-2+ w]},{s,w,Min[2-(2^(2/3) (2 \[Pi]-Min[2Pi,3 V((w^2)/(.04))])^(1/3))/\[Pi]^(1/3)-w,2]},{t,0, 2 Pi},Mesh->None, PlotStyle->Directive[Opacity[1],Hue[a]], Lighting->"Neutral"], ParametricPlot3D[{(w/2) Cos[t],(w/2) Sin[t], b},{t,0,2Pi}, {b, -2 + w, 0}, PlotStyle->Directive[Opacity[1], Hue[a]],Mesh->None, Lighting->"Neutral"],PlotRange->All,ImageSize->{300,300}, SphericalRegion-> True]},{Row[{Text["time to empty = "], Text[2Pi (.04)/(3w^2)],Text[" seconds"]}]}}],{start,ControlType->None},{end,ControlType->None},
{{V,.01,"time (seconds)"},0.01,34,.01,ControlType->Animator,AnimationRate->1,AnimationRunning->False,ImageSize->Small},
{{w,.05,"neck width (millimeters)"}, .05, .3,.01,Appearance->"Labeled"},
{{a,0,"color of sand"}, 0, 1,Appearance->"Labeled"}]
如果这是作为纯粹的表示层替代,那么它实际上取决于模拟的输出和您 select 的表示。
例如,如果模拟输出一个变量(例如其中一个隔间的体积),则可以将其直接分配给可视化的属性,例如 "top" 帽的位置一个圆柱体。 "complementary" 圆柱体可以站在前一个圆柱体的顶部,其底盖坐标分配给 (totalVolume-lowerCompartmentVolume)。
在这种情况下,可视化只是一个仪表板,不会反馈到模拟中(例如,模拟通常不会考虑对象碰撞或接近)。
为了概括这一点,我们讨论的是将一组数量分配给一组可视化属性的解决方案。
从这个角度来看,可以使用 VRML(或 X3D)创建一组复杂的对象,它们的属性可以直接绑定到模拟输出,并且每第 n 个模拟时间步触发一次渲染。
要创建 "scene" 或可视化对象,您可以手动使用 blender which can export VRML scenes, or write the VRML 等软件(这确实是一项简单的任务)。
在基础设施方面,MATLAB有VRML toolkit and Python has a really wide selection of modules by which VRML can be handled (please see this and this例如link。
更具体的例子:
给定一些模拟输出 y
和模板 VRML 文件,例如:
#VRML V2.0 utf8
Transform {
translation 0 0 0
children [
Shape { geometry Box {2,2,zSize} }
]
}
你可以这样做:
data = (Read contents of VRML file as string data).
for n in [0..1000]:
y = getSimulationOutput(aParameterVector)
renderData = substitute(data, "zSize", y) #This function could be provided by a template module like jinja for example.
simulationFrame = renderVRML(renderData)
saveImage(simulationFrame)
(请注意:可以找到有关 Jinja 的更多信息 here - 内联评论 link 上面未正确呈现。)
返回文件并将不同的元素绑定到不同的数量(例如,更改可以旋转、缩放、平移框的变换,或通过分配不同的颜色来更改框的外观),您可以为您的模拟创建任何类型的 "dashboard" 输出....包括不规则六边形。
此技术是 Data Driven Documents 的直接应用,但在此处应用于不同的基材(不同于 HTML 或 SVG)。
希望这对您有所帮助。
想建立一个标准的网格库,我想应该从确定自由度开始。
对于有 2 个嘴的凹双对称六边形,它可以是:
- 口斧宽度(W_m)
- 相对顶部宽度 (w_t = W_t / W_m)
- 相对底部宽度(w_b = W_b / W_m)
- 相对顶部高度
- 相对底部高度
Margus 和 A_A 的回答将有助于实现。
如果您的目标是在 matlab 中可视化此类六边形,那么 fill
and fill3
应该可以做到。这是一个示例代码,它假设您的六边形由两个宽度 w1
和 w2
以及 d1
和 d2
参数参数化,它们是边的长度:
function draw_hexagon(w1, w2, d1, d2)
a=(w1-w2)/2;
b1=sqrt(d1^2 - a^2);
b2=sqrt(d2^2 - a^2);
xs=[-w1/2, w1/2, w2/2, w1/2, -w1/2, -w2/2];
ys=[b1, b1, 0, -b2, -b2, 0];
fill(xs, ys, 'b')
axis square
grid on
end
它将为 w1=4, w2=2, d1=2, d2=3
生成以下内容:
对于 3D 也类似:
function draw_hexagon_3d(w1, w2, d1, d2)
a=(w1-w2)/2;
b1=sqrt(d1^2 - a^2);
b2=sqrt(d2^2 - a^2);
xs=[-w1/2, w1/2, w2/2, w1/2, -w1/2, -w2/2];
ys=[0, 0, 0, 0, 0, 0];
zs=[b1, b1, 0, -b2, -b2, 0];
fill3(xs, ys, zs, 'b')
grid on
axis square
end
我们得到:
我和同事讨论过这个问题。 他鼓励创建一个三角形网络,但也指出了非凸多边形的通用算法。
通过自己的算法创建Mesh
- 如问题正文所示,用虚线将六边形分成两个梯形
- 将梯形分成三角形:
assemmbly
并通过inittri
构建三边形结构
- 加载向量
f
由bilin_assembly
构建(因为这以前有效但不一定是最佳选择)
有两个嘴的六边形分成两个梯形
- 取六个节点中索引差为三且距离最小的两个节点。
- 组成两个梯形,一个梯形的数字为 1-4,另一个梯形的数字为 1,6,5,4。
以下语法基于我 2013 年的代码版本,但主要基于 Claes Johnson 着的书有限元法对偏微分方程的数值解一书的描述。
为简单起见,现在考虑的汇编语法是泊松问题(稍后必须在此处细化)
% [S,f]=assemblyGlobal(loadfunction,mesh)
%
% loadfunction = function on the right-hand side of the Poisson equation
% mesh = mesh structure on which the assembly is done
%
% S = stiffness matrix of the Poisson problem
% f = load vector corresponding to loadfunction
我们需要双线性汇编的语法
% function B=bilin_assembly(bilin,mesh)
%
% bilin = function handle to integrand of the bilinear form
% given as bilin(u,v,ux,uy,vx,vy,x,y), where
% u - values of function u
% v - values of function v
% ux - x-derivative of function u
% uy - y-derivative of function u
% vx - x-derivative of function v
% vy - y-derivative of function v
% x - global x-coordinate
% y - global y-coordinate
% mesh = mesh structure on which the matrix will be assembled
%
% B = matrix related to bilinear form bilin
初始化三角网格的语法
% function mesh = inittri(p,t)
%
% p = nodes
% t = triangles
%
% mesh = trimesh structure corresponding to (p,t)
%
% TRIMESH STRUCTURE :
%
% p = nodes in a 2xN-matrix
%
% t = triangles in a 3xN- matrix (nodes of the triangles as indeces to the p- matrix).
%
% edges = a matrix of all edges in the mesh. Each column is an edge :
% [n1 ; n2] where n1 < n2;
%
% t2e = a matrix connecting triangle's and edges's.
% Each column corresponds to a triangle and has
% triangle's edges in the order n1->n2, n2->n3,
% n1->n3.
%
% e2t = inverse of t2e.
由于版权问题,我没有post这里提供完整的源代码,他们会让答案变得相当长。 但是,所有算法都基于第一个来源,因此这里的任何研究人员都可以创建。 我认为这种 FEM 方法是在这里找到最佳网格的唯一方法。
一般非凸多边形的算法
还有一些算法可以为一般的非凸多边形创建网格。
Margus 的
Ansys
我正在体验有关可视化孔、不同几何形状和不同材料的不同产品。 Ansys 在这里是有前途的解决方案。
来源
- Claes Johnson 的有限元法偏微分方程的数值解。
- Class我大学有限元方法的笔记,2013-2014