ToElementMesh[r]
領域 r からElementMeshオブジェクトを生成する.
ToElementMesh[r,{{xmin,xmax},…}]
境界ボックス
に制約された領域 r からのElementMeshオブジェクトを生成する.
ToElementMesh[rules]
座標と要素を指定する rules の集合からElementMeshオブジェクトを生成する.
ToElementMesh[emesh]
既存のElementMesh,MeshRegion,BoundaryMeshRegionのいずれかから,新しいElementMeshオブジェクトを生成する.
ToElementMesh
ToElementMesh[r]
領域 r からElementMeshオブジェクトを生成する.
ToElementMesh[r,{{xmin,xmax},…}]
境界ボックス
に制約された領域 r からのElementMeshオブジェクトを生成する.
ToElementMesh[rules]
座標と要素を指定する rules の集合からElementMeshオブジェクトを生成する.
ToElementMesh[emesh]
既存のElementMesh,MeshRegion,BoundaryMeshRegionのいずれかから,新しいElementMeshオブジェクトを生成する.
詳細とオプション
- ToElementMesh[r]は,記号的である可能性のある領域 r を近似するElementMeshオブジェクトを生成する.
- 領域 r の指定には,幾何学領域とImplicitRegionによって説明されるオブジェクトが含まれる.
- 領域 r は,ConstantRegionQがTrueを与える定数領域でなければならない.
- 領域 r の近似を生成するには,ToElementMeshはまずToBoundaryMeshを呼び出す.
- ToElementMesh[rules]では,rules は以下の順序で与えられなければならない.
-
"Coordinates"->{c1,c2,…} 座標が c1,c2,…になるように指定する必要がある "MeshElements"->{e1,…} メッシュの要素が e1,…になるように指定する必要がある "BoundaryElements"->{b1,…} メッシュの境界要素が b1,…になるように指定する(必須ではない) "PointElements"->{p1,…} メッシュの点要素が p1,…になるように指定する(必須ではない) - 1D要素メッシュでは,"MeshElements"はLineElementである."BoundaryElements"と"PointElements"は,指定されると,PointElementである.
- 2D要素メッシュでは,"MeshElements"は,TriangleElementでもQuadElementでもよい."BoundaryElements"は,指定されると,LineElementであり,"PointElements"はPointElementである.
- 3D要素メッシュでは,"MeshElements"は,TetrahedronElementでもHexahedronElementでもよい."BoundaryElements"は,指定されると,TriangleElementとQuadElementであり,"PointElements"は PointElementである.
- ToElementMeshには,ToBoundaryMeshのオプションに,以下を加えたものが使える.
-
"CheckQuality" Automatic 品質評価を計算する "ElementMeshGenerator" Automatic ElementMeshオブジェクトを境界のElementMeshオブジェクトから生成する関数 "ImproveBoundaryPosition" Automatic 境界ノードの位置を改善する "MeshElementBlocks" 1 メッシュ要素のブロックの数 "MeshElementConstraint" Automatic メッシュ要素の追加の制約条件 "MeshElementType" Automatic メッシュの入力に使われるメッシュタイプ "MeshOrder" Automatic 要素メッシュの次数 MeshQualityGoal Automatic メッシュ要素の目標品質を指定する MeshRefinementFunction Automatic 2Dと3Dの要素の調整を制御する "NodeReordering" Automatic ノードを並び替えて,最小のバンド幅の行列を生成する "SteinerPoints" Automatic Steinerの点の挿入を制御する "RegionMarker" None 領域マーカーを指定する "SortElements" Automatic メッシュ内の要素がソートされるかどうかを指定する - ToElementMeshのオプションのいずれかを指定することによって,さまざまな方法で,ToElementMesh[emesh,opts]を使ってElementMeshオブジェクト emesh を修正することができる.
- ToElementMeshがElementMeshを生成できない場合には,$Failedが返される.
- EmptyRegionに対してToElementMeshを呼び出すと,EmptyRegionが返される.
- ToElementMeshに与えられるオプションは,"MeshOptions"を指定することによってNDSolveに与えることができる. »
- NDSolveおよび関連の関数からToElementMeshのオプションを設定することについては,有限要素のためのNDSolveオプションに説明がある.
例題
すべて開く すべて閉じる例 (4)
<<NDSolve`FEM`ToElementMesh[Disk[]]%["Wireframe"]ToElementMesh[RegionUnion[Disk[], Rectangle[{0, 0}, {2, 2}]]]%["Wireframe"]ToElementMesh[FullRegion[2], {{0, 5}, {0, 1}}]%["Wireframe"]ToElementMesh["Coordinates" -> {{1.293, 0.228}, {1., 0.}, {0.94, 0.342}, {1.293, 0.}, {1.215, 0.442}, {2., 0.}, {1.879, 0.684}}, "MeshElements" -> {TriangleElement[{{1, 3, 2}, {1, 2, 4}, {1, 4, 6}, {1, 6, 7}, {1, 7, 5}, {1, 5, 3}}]}]%["Wireframe"]スコープ (29)
ToElementMesh[ImplicitRegion[.2 ≤ x ^ 2 + y ^ 2 ≤ 1, {x, y}]]["Wireframe"]BooleanRegionを使って,2つの円の間の領域にメッシュを生成する:
ToElementMesh[RegionDifference[Disk[], Disk[{0, 0}, Sqrt[0.2]]]]["Wireframe"]ImplicitRegionを明示的な境界ボックスで変換する:
ToElementMesh[ImplicitRegion[x < y ^ 2, {x, y}], {{-1 / 2, 1}, {-1, 1}}]["Wireframe"]RegionDistanceから計算されたImplicitRegionを明示的な境界ボックスで変換する:
ToElementMesh[ImplicitRegion[RegionDistance[Rectangle[{-1, -1}, {1, 1}], {x, y}] ≤ 1 / 3, {{x, -2, 2}, {y, -2, 2}}]]["Wireframe"]GraphicsComplexを要素メッシュに変換する:
ToElementMesh[DiscretizeGraphics[GraphicsComplex[{{0, 0}, {1, 0}, {2, 2}, {0, 1}}, Polygon[{1, 2, 3, 4}]]]]["Wireframe"]TransformedRegionを要素メッシュに変換する:
ToElementMesh[TransformedRegion[Disk[{1, 1}, 4], {Indexed[#, 1] Indexed[#, 2], Indexed[#, 1] + Indexed[#, 2]}&]]["Wireframe"]3DのBallを要素メッシュに変換する:
ToElementMesh[Ball[{0, 0, 0}, 1]]%["Wireframe"]3DのGraphicsComplexを要素メッシュに変換する:
ToElementMesh[DiscretizeGraphics[GraphicsComplex[{{0, 0, 0}, {20, 0, 0}, {20, 2, 0}, {0, 2, 0}, {0, 0, 1}, {20, 0, 1}, {20, 2, 1}, {0, 2, 1}}, Polygon[{{4, 1, 5, 8}, {2, 3, 7, 6}, {1, 2, 3, 4}, {5, 6, 7, 8}, {1, 2, 6, 5}, {3, 4, 8, 7}}]]], MaxCellMeasure -> Infinity]["Wireframe"]3DのImplicitRegionからメッシュを作成する:
r = ImplicitRegion[(x - 100 / 2) ^ 2 + (y - 50 / 2) ^ 2 ≥ (20 / 2) ^ 2, {x, y, z}];ToElementMesh[r, {{0, 100}, {0, 50}, {0, 5}}]%["Wireframe"]3DのBooleanRegionからメッシュを作成する:
r = RegionDifference[Cuboid[{0, 0, 0}, {100, 50, 5}], Cylinder[{{50, 25, -1}, {50, 25, 6}}, 10]]ToElementMesh[r]%["Wireframe"]3DのTransformedRegionを要素メッシュに変換する:
ToElementMesh[TransformedRegion[Cuboid[], ShearingTransform[30Degree, {1, 0, 0}, {0, 1, 1}]]]["Wireframe"]ToElementMesh["Coordinates" -> {{0., 0.}, {1., 0.}, {1., 1.}, {0., 1.}}, "MeshElements" -> {TriangleElement[{{1, 2, 3}, {3, 4, 1}}]}]%["Wireframe"]点集合については,ToElementMeshはドロネー図を返す:
ToElementMesh["Coordinates" -> RandomReal[{-1, 1}, {10, 2}]]["Wireframe"]1Dの線分要素メッシュ (3)
ToElementMesh["Coordinates" -> Partition[Range[0., 1., 1 / 9], 1], "MeshElements" -> {LineElement[{{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}}]}]%["Wireframe"]領域の穴を含む1DのElementMeshをImplicitRegionから作成する:
m = ToElementMesh[ImplicitRegion[(x ≤ -5) || (-1 ≤ x ≤ 1) || (x ≥ 5), {x}], {{-10, 10}}]m["Wireframe"]1DのElementMeshからElementMeshRegionProductを作成する:
m = ToElementMesh[Line[{{0}, {1}}]];
ElementMeshRegionProduct[m, m]["Wireframe"]2Dの三角要素メッシュ (2)
ToElementMesh["Coordinates" -> {{1.293, 0.228}, {1., 0.}, {0.94, 0.342}, {1.293, 0.}, {1.215, 0.442}, {2., 0.}, {1.879, 0.684}}, "MeshElements" -> {TriangleElement[{{1, 3, 2}, {1, 2, 4}, {1, 4, 6}, {1, 6, 7}, {1, 7, 5}, {1, 5, 3}}]}]%["Wireframe"]2DのElementMeshと1DのElementMeshからElementMeshRegionProductを作成する:
m2D = ToElementMesh[Annulus[], MaxCellMeasure -> 1 / 2];
m1D = ToElementMesh[Line[{{0}, {1 / 10}}], MaxCellMeasure -> 1];
ElementMeshRegionProduct[m2D, m1D]["Wireframe"]2Dのクワッド要素メッシュ (2)
nx = ny = 10;
coordinates = Flatten[ Table[{r Cos[θ], r Sin[θ]}, {r, 1., 2., 1 / (ny - 1)}, {θ, 0., 2 Pi / 3., (2 Pi / 3.) / (nx - 1)}], 1];
incidents = Flatten[Table[{j * nx + i, j * nx + i + 1, (j - 1) * nx + i + 1, (j - 1) * nx + i}, {i, 1, nx - 1}, {j, 1, ny - 1}], 1];ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {QuadElement[incidents]}]%["Wireframe"]nx = 6;ny = 3;
{xStart, xStop} = {0, 1};
{yStart, yStop} = {1, 3 / 2};
coordinates = Flatten[ Table[{x, y}, {y, yStart, yStop, (yStop - yStart) / ny}, {x, xStart, xStop, (xStop - xStart) / nx}], 1];
incidents = Flatten[Table[
{(j - 1) * (nx + 1) + i, (j - 1) * (nx + 1) + i + 1, j * (nx + 1) + i + 1, j * (nx + 1) + i}
, {j, 1, ny}, {i, 1, nx}], 1];
m2 = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {QuadElement[incidents]}]Show[
m2["Wireframe"["MeshElement" -> "PointElements", "MeshElementIDStyle" -> Red]], m2["Wireframe"["MeshElement" -> "MeshElements", "MeshElementIDStyle" -> Blue]]]2Dの複合要素タイプのメッシュ (1)
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {2.5, 0.5}, {0., 1.}, {1., 1.}, {2., 1.}, {3., 1.}, {2.5, 1.5}, {0., 2.}, {1., 2.}, {2., 2.}};mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {QuadElement[{{1, 2, 6, 5}, {2, 3, 7, 6}, {5, 6, 11, 10}, {6, 7, 12, 11}}], TriangleElement[{{3, 4, 7}, {4, 8, 7}, {7, 9, 12}, {7, 8, 9}}]}]mesh["Wireframe"]2Dの高次要素メッシュ (1)
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {2.5, 0.5}, {0., 1.}, {1., 1.}, {2., 1.}, {3., 1.}, {2.5, 1.5}, {0., 2.}, {1., 2.}, {2., 2.}, {0., 0.5}, {0., 1.5}, {0.5, 0.}, {0.5, 1.}, {0.5, 2.}, {1., 0.5}, {1., 1.5}, {1.5, 0.}, {1.5, 1.}, {1.5, 2.}, {2., 0.5}, {2., 1.5}, {2.25, 0.25}, {2.25, 0.75}, {2.25, 1.25}, {2.25, 1.75}, {2.5, 1.}, {2.75, 0.75}, {2.75, 1.25}};triIncidents = {{3, 4, 7, 25, 26, 23}, {4, 8, 7, 30, 29, 26}, {7, 9, 12, 27, 28, 24}, {7, 8, 9, 29, 31, 27}};quadIncidents = {{1, 2, 6, 5, 15, 18, 16, 13}, {2, 3, 7, 6, 20, 23, 21, 18}, {5, 6, 11, 10, 16, 19, 17, 14}, {6, 7, 12, 11, 21, 24, 22, 19}};mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {TriangleElement[triIncidents],
QuadElement[quadIncidents]}]Show[mesh["Wireframe"],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementStyle" -> Directive[Red, PointSize[0.02]], "MeshElementIDStyle" -> Blue]]]3Dの四面体要素メッシュ (1)
coordinates = N[Join[{{0, 0, 1}, {0, 0, 0}}, Table[{Sin[i], Cos[i], 0}, {i, 0, 2π - π / 4, π / 4}]]];Graphics3D[MapIndexed[Text[ToString[#2[[1]]], #1]&, coordinates]]mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {
TetrahedronElement[{{1, 2, 3, 4}, {1, 2, 4, 5}, {1, 2, 5, 6}, {1, 2, 6, 7}, {1, 2, 7, 8}, {1, 2, 8, 9}, {1, 2, 9, 10}, {1, 2, 10, 3}}, {1, 1, 1, 1, 2, 2, 2, 2}]
}]mesh["Wireframe"["MeshElement" -> "MeshElements", "MeshElementMarkerStyle" -> Red]]3Dの六面体要素メッシュ (1)
nx = 13;ny = 6;nz = 7;
coordinates = Flatten[ Table[{r Cos[θ], r Sin[θ], h}, {h, -1., 1., 2 / (nz - 1)}, {r, 1., 2., 1 / (ny - 1)}, {θ, 0., 2 Pi / 3., (2 Pi / 3.) / (nx - 1)}], 2];incidents = Flatten[Table[Block[{p1 = (j - 1) * nx + i, p2 = j * nx + i, p3 = p2 + 1, p4 = p1 + 1, p5, p6, p7, p8},
{p5, p6, p7, p8} = {p1, p2, p3, p4} + k * nx * ny;
{p1, p2, p3, p4} += (k - 1) * nx * ny;
{p1, p2, p3, p4, p5, p6, p7, p8}], {i, 1, nx - 1}, {j, 1, ny - 1}, {k, 1, nz - 1}], 2];mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {HexahedronElement[incidents]}]mesh["Wireframe"]画像 (2)
領域マーカー (1)
領域マーカーは,領域内の複数のものを指定するのに便利であり,「要素メッシュの生成」の「マーカー」セクションに詳しく説明されている.
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {2.5, 0.5}, {0., 1.}, {1., 1.}, {2., 1.}, {3., 1.}, {2.5, 1.5}, {0., 2.}, {1., 2.}, {2., 2.}};
incidents = GatherBy[{{1, 2, 6, 5}, {2, 3, 7, 6}, {3, 4, 7}, {4, 8, 7}, {5, 6, 11, 10}, {6, 7, 12, 11}, {7, 9, 12}, {7, 8, 9}}, Length]mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {QuadElement[incidents[[1]], {1, 1, 2, 2}], TriangleElement[incidents[[2]], {1, 1, 2, 2}]}]mesh["Wireframe"["MeshElementMarkerStyle" -> Red]]境界マーカー (1)
境界マーカーは,領域境界上でNeumannValueを指定するのに便利であり,「要素メッシュの生成」の「マーカー」セクションに詳しく説明されている.
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {0., 1.}, {1., 1.}, {2., 1.}, {0., 2.}, {1., 2.}, {2., 2.}};
incidents = {{1, 2, 5, 4}, {2, 3, 6, 5}, {4, 5, 8, 7}, {5, 6, 9, 8}};ele = {QuadElement[incidents]};boundaryIncidents = {{1, 2}, {2, 3}, {3, 6}, {6, 9}, {9, 8}, {8, 7}, {7, 4}, {4, 1}};boundaryMarker = {1, 1, 2, 2, 3, 3, 4, 4}bcEle = {LineElement[boundaryIncidents, boundaryMarker]}mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> ele, "BoundaryElements" -> bcEle]Show[
mesh["Wireframe"["MeshElement" -> "BoundaryElements", "MeshElementMarkerStyle" -> Red]],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementStyle" -> Directive[PointSize[0.02]],
"MeshElementIDStyle" -> Blue
]]]点マーカー (1)
点マーカーは,領域境界上でDirichletConditionを指定するのに便利であり,「要素メッシュの生成」の「マーカー」セクションに詳しく説明されている.
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {0., 1.}, {1., 1.}, {2., 1.}, {0., 2.}, {1., 2.}, {2., 2.}};
incidents = {{1, 2, 5, 4}, {2, 3, 6, 5}, {4, 5, 8, 7}, {5, 6, 9, 8}};ele = {QuadElement[incidents]};boundaryIncidents = {{1, 2}, {2, 3}, {3, 6}, {6, 9}, {9, 8}, {8, 7}, {7, 4}, {4, 1}};
bcEle = {LineElement[boundaryIncidents]};pointIncidents = Partition[Range[Max[incidents]], 1];
pointMarkers = {1, 1, 1, 4, 0, 2, 3, 3, 3};
pEle = {PointElement[pointIncidents, pointMarkers]}mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> ele, "BoundaryElements" -> bcEle, "PointElements" -> pEle];mesh["PointElements"]Show[
mesh["Wireframe"],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementMarkerStyle" -> Red]],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementStyle" -> Directive[PointSize[0.02]],
"MeshElementIDStyle" -> Blue
]]]オプション (42)
"BoundaryMarkerFunction" (2)
境界マーカーは,領域境界上でNeumannValueを指定するのに便利であり,「要素メッシュの生成」の「マーカー」セクションに詳しく説明されている.
boundaryMarkerFunction = Compile[{{boundaryElementCoords, _Real, 3}, {pointMarkres, _Integer, 2}},
Module[{pt1 = #[[1]], pt2 = #[[2]]},
Which[
pt1[[1]] > 0.9 && pt2[[1]] > 0.9, 2,
pt1[[1]] < 0.1 && pt2[[1]] < 0.1, 3,
True, 4 ]]& /@ boundaryElementCoords];mesh = ToElementMesh[FullRegion[2], {{0, 1}, {0, 1}},
"BoundaryMarkerFunction" -> boundaryMarkerFunction,
"MeshElementType" -> TriangleElement,
MaxCellMeasure -> {"Area" -> 0.05, "Length" -> 0.5}]Show[mesh["Wireframe"],
mesh["Wireframe"["MeshElement" -> "BoundaryElements", "MeshElementMarkerStyle" -> Red]]]mesh["BoundaryElements"]"PointElementMarkers"も計算された場合には,それらは,"BoundaryMarkerFunction"に与えられる関数の第2引数としてアクセス可能である.
boundaryMarkerFunction = Compile[{{boundaryElementCoords, _Real, 3}, {boundaryElementPointMarkres, _Integer, 2}},
Module[{pt1 = #[[1]], pt2 = #[[2]]},
Which[
pt1[[1]] > 0.9 && pt2[[1]] > 0.9, 2,
pt1[[1]] < 0.1 && pt2[[1]] < 0.1, 3,
True, 4 ]]& /@ boundaryElementCoords];Μ = ToElementMesh[ImplicitRegion[True, {x, y}], {{0, 1}, {0, 1}},
"BoundaryMarkerFunction" -> boundaryMarkerFunction,
"MaxCellMeasure" -> {"Area" -> 0.05}]Show[Μ["Wireframe"],
Μ["Wireframe"["MeshElement" -> "BoundaryElements", "MeshElementMarkerStyle" -> Red]]]"BoundaryMeshGenerator" (2)
"Continuation"メソッドは,多くの場合にコーナー,尖点,急な変化をかなりうまく処理することができる曲線継続法を使う:
ℛ = ImplicitRegion[-1 + 2 x^2 ≤ y ≤ x^2, {{x, -1, 1}, {y, -1, 1}}];ToElementMesh[ℛ, "BoundaryMeshGenerator" -> "Continuation"]["Wireframe"]"RegionPlot"メソッドは,RegionPlotからの出力を改善することに基づいており,より速い場合もある:
ToElementMesh[ℛ, "BoundaryMeshGenerator" -> "RegionPlot"]["Wireframe"]"BoundaryMeshGenerator"オプションの詳細は,ToBoundaryMeshのページを参照されたい.
"OpenCascade"の境界メッシュ生成器は,Graphics3Dプリミティブからなる3DのBooleanRegion式に使うのに適している.
Ω = RegionDifference[RegionDifference[RegionUnion[Cylinder[{{0, 0, 0}, {0, 0, 10}}, 5], Cylinder[{{0, 0, 5}, {0, -6, 5}}, 3]], Cylinder[{{0, 0, 0}, {0, 0, 10}}, 2]], Cylinder[{{0, 0, 5}, {0, -6, 5}}, 2]];mesh = ToElementMesh[Ω, "BoundaryMeshGenerator" -> {"OpenCascade"}]groups = mesh["BoundaryElementMarkerUnion"];
temp = Most[Range[0, 1, 1 / (Length[groups])]];
colors = ColorData["BrightBands"][#]& /@ tempmesh["Wireframe"["MeshElementStyle" -> FaceForm /@ colors]]"ElementMeshGenerator" (1)
Options[elementMeshGenerator] = {"MyOption" -> Automatic, MaxCellMeasure -> Automatic};
elementMeshGenerator[numericalRegion_, opts : OptionsPattern[]] := Module[{},
Print[numericalRegion];
Print[{opts}];
ToElementMesh[numericalRegion["BoundaryMesh"]]
]mesh = ToElementMesh[FullRegion[2], {{0, 1}, {0, 1}}, "ElementMeshGenerator" -> {elementMeshGenerator, "MyOption" -> "Test"}, MaxCellMeasure -> 0.1]カスタムのメッシュ生成器に与えられた数値領域には"BoundaryMesh"が含まれる.メッシュ生成器のインターフェースが記号表現を使うので外部メッシュ生成器へのインターフェースに境界メッシュ表現が必要ないという場合は,"BoundaryMeshGenerator"->Noneと設定することによって,境界メッシュの生成を行わないようにすることができる.
"ImproveBoundaryPosition" (1)
ImplicitRegionの近似は,一般に厳密ではない."ImproveBoundaryPosition"オプションは,境界ノードの位置を改善することを助ける:
mesh = ToElementMesh[Disk[], "BoundaryMeshGenerator" -> "RegionPlot", "ImproveBoundaryPosition" -> False, "MeshOrder" -> 1, MaxCellMeasure -> {"Length" -> .2}]bcPos = Flatten[ElementIncidents[mesh["BoundaryElements"]]];
bcCoords = mesh["Coordinates"][[bcPos]];境界ノードの平方の総和は,必ずしもすべて値1にあるわけではない:
Total[bcCoords ^ 2, {2}]mesh = ToElementMesh[Disk[], "MeshOrder" -> 1, MaxCellMeasure -> {"Length" -> .2}]bcPos = Flatten[ElementIncidents[mesh["BoundaryElements"]]];
bcCoords = mesh["Coordinates"][[bcPos]];Total[bcCoords ^ 2, {2}]"ImproveBoundaryPosition"オプションがFalseに設定されている場合には,二次要素は領域の曲線部分の境界上の中間ノードを持たない.
"IncludePoints" (3)
Ω = ImplicitRegion[And@@(# ≤ 0& /@ {-y, 1 / 25 - (-3 / 2 + x) ^ 2 - y ^ 2, 1 - x ^ 2 - y ^ 2, -4 + x ^ 2 + y ^ 2, (-x + 2 * y) / Sqrt[5]}), {x, y}];ToElementMesh[Ω, {{0.8, 2.2}, {-0.2, 1.}}]["Wireframe"]additionalPoints = DeleteDuplicates[Table[{1.5 + 0.2Sin[ϕ], 0.4 + 0.2Cos[ϕ]}, {ϕ, 0, 2π, π / 25}]];ToElementMesh[Ω, {{0.8, 2.2}, {-0.2, 1.}}, "IncludePoints" -> additionalPoints]["Wireframe"]"IncludePoints"を使って加えられた点は,DirichletConditionで使える.さらに,DirichletConditionの述部がTrueであれば,境界条件は加えられた点において有効となる.
pts = Transpose[{RandomReal[{0, 5}, {10}], RandomReal[{0, 1}, {10}]}];m = ToElementMesh[FullRegion[2], {{0, 5}, {0, 1}}, "IncludePoints" -> pts, MaxCellMeasure -> .25]m["Wireframe"]"IncludePoints"は,ToBoundaryMeshのオプションであり,ToElementMeshはオプションを渡す.しかしこのことは,ToElementMeshに境界ElementMeshが提示された場合に,その要求を満たすことができないことを意味する:
bmesh = ToBoundaryMesh[Disk[]]mesh = ToElementMesh[bmesh, "IncludePoints" -> {{0, 0}}]Nearest[mesh["Coordinates"], {0, 0}]点{0,0}は含まれていない.この問題を解決する策として,ToBoundaryMeshの呼出し中に"IncludePoints"を指定するか,ToElementMeshを呼び出す際に記号的領域を利用するかの方法がある.
ToBoundaryMeshの呼出し中に"IncludePoints"を使う:
bmesh = ToBoundaryMesh[Disk[], "IncludePoints" -> {{0, 0}}]mesh = ToElementMesh[bmesh]Nearest[mesh["Coordinates"], {0, 0}]あるいは,ToElementMeshの呼出しに記号的領域を使う:
mesh = ToElementMesh[Disk[], "IncludePoints" -> {{0, 0}}]Nearest[mesh["Coordinates"], {0, 0}]"MaxBoundaryCellMeasure" (2)
"MaxCellMeasure" (4)
MaxCellMeasure->m で,セルの大きさが選ばれ,境界セルの大きさが埋込み次元内の高品質セルに適切なものに設定される:
em = ToElementMesh[Disk[], MaxCellMeasure -> .2, AccuracyGoal -> 1];
em["Wireframe"]Max[em["MeshElementMeasure"]]em = ToElementMesh[Disk[], "MeshOrder" -> 1, MaxCellMeasure -> .02];
em["Wireframe"]Max[em["MeshElementMeasure"]]最大セルの大きさは,線形要素に働く.曲線境界のより高次のメッシュの場合には,実際のセルの大きさがより大きくなることがある:
特定の長さは,MaxCellMeasure->{"Length"->len}で指定することができる:
em = ToElementMesh[Disk[], MaxCellMeasure -> {"Length" -> .1}];
em["Wireframe"]特定の長さと範囲がMaxCellMeasure->{"Length"->len,"Area"->area}を使って指定される場合には,より厳しい必要条件が満たされる:
em = ToElementMesh[Disk[], MaxCellMeasure -> {"Length" -> .1, "Area" -> 10}];
em["Wireframe"]Max[em["MeshElementMeasure"]]ToElementMesh[Disk[], MaxCellMeasure -> {"Length" -> .1}, "MaxBoundaryCellMeasure" -> 0.01]["Wireframe"]"MeshElementBlocks" (1)
ToElementMesh[DiscretizeGraphics[GraphicsComplex[{{0, 0}, {1, 0}, {2, 2}, {0, 1}}, Polygon[{1, 2, 3, 4}]]]]ToElementMesh[DiscretizeGraphics[GraphicsComplex[{{0, 0}, {1, 0}, {2, 2}, {0, 1}}, Polygon[{1, 2, 3, 4}]]], "MeshElementBlocks" -> 5]"MeshElementConstraint" (2)
TriangleElementに基づく二次元のメッシュについては,最小の三角角度は,"MeshElementConstraint"オプションを通して指定できる:
gc = DiscretizeGraphics[GraphicsComplex[{{0, 0}, {1, 0}, {2, 2}, {0, 1}}, Polygon[{1, 2, 3, 4}]]];
mesh = ToElementMesh[gc, "MeshElementConstraint" -> 20]Histogram[mesh["Quality"]]mesh["Wireframe"]mesh = ToElementMesh[gc]Histogram[mesh["Quality"]]mesh["Wireframe"]指定された最小角度は,33度より小さくなければならない.理論的には,アルゴリズムは,22.7度より小さい最小角度を確実になくすことになっているが,実際には,33度までの最小角度でも成功することがしばしばある.
三次元のTetrahedronElementメッシュについては,四面体半径の辺の長さに対する最小割合は,"MeshElementConstraint"オプションを使って指定することができる:
gc = DiscretizeGraphics[ExampleData[{"Geometry3D", "SpaceShuttle"}, "GraphicsComplex"]];
mesh = ToElementMesh[gc, "MeshElementConstraint" -> Sqrt[2]]Histogram[mesh["Quality"]]mesh["Wireframe"]mesh = ToElementMesh[gc]Histogram[mesh["Quality"]]mesh["Wireframe"]半径と辺の割合は,
より大きくなければならない.理論的には,アルゴリズムは,半径と辺の割合が2である場合には確実になくすことになっているが,実際には半径と辺の割合が
まで下がる場合にもしばしば成功する.
"MeshElementType" (1)
ToElementMesh[Rectangle[{-1, -1}, {1, 1}]]%["Wireframe"]ToElementMesh[Rectangle[{-1, -1}, {1, 1}], "MeshElementType" -> TriangleElement]%["Wireframe"]"MeshOrder" (1)
mesh = ToElementMesh[Disk[]]%["MeshOrder"]π - NIntegrate[1, {x, y}∈mesh]mesh = ToElementMesh[Disk[], "MeshOrder" -> 1]%["MeshOrder"]π - NIntegrate[1, {x, y}∈mesh]"MeshOrder"オプションの詳細については,要素メッシュの生成と要素メッシュの可視化のチュートリアルを参照されたい.
"MeshQualityGoal" (1)
品質の値
は,正規のメッシュ要素については
,変化したメッシュ要素については
になるように,計算される:
bm = ToBoundaryMesh["Coordinates" -> {{-1, -2}, {1, -2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}}, "BoundaryElements" -> {LineElement[Partition[Range[8], 2, 1, {1, 1}]]}]ToElementMesh[bm, MeshQualityGoal -> 0, MaxCellMeasure -> Infinity]["Wireframe"]ToElementMesh[bm, MeshQualityGoal -> "Maximal", MaxCellMeasure -> Infinity]["Wireframe"]"MeshRefinementFunction" (9)
特定の2D三角要素が細分化されなければならない場合に,Trueを返す関数を作成する:
meshRefine[vertices_, area_] := area > 0.0025mesh = ToElementMesh[Polygon[{{1, 0}, {0, 2}, {-1, 0}}], MeshRefinementFunction -> meshRefine]mesh["Wireframe"]mesh = ToElementMesh[Polygon[{{1, 0}, {0, 2}, {-1, 0}}]]["Wireframe"]特定の2D三角要素が細分化されなければならない場合に,Trueを返すコンパイルされた関数を作成する:
cf = Compile[{{c, _Real, 2}, {a, _Real, 0}},
Block[{com},
com = Total[c] / Length[c];
If[Sin[Times@@com] > 0 && a > 0.001, True, False]]
];m = ToElementMesh[Disk[], MeshRefinementFunction -> cf]m["Wireframe"]ToElementMesh[Disk[], MeshRefinementFunction -> Function[{vertices, area}, area > 0.0005 (0.1 + 10 Norm[Mean[vertices]])]]["Wireframe"]ToElementMesh[Disk[], MeshRefinementFunction -> Function[{vertices, area}, area > 0.0005(21 - 20Norm[Mean[vertices]])]]["Wireframe"]f = Function[{vertices, area}, Block[{x, y}, {x, y} = Mean[vertices];If[x ^ 4 + y ^ 4 ≤ 1, area > 0.003, area > 0.01]]];mr = ToElementMesh[Rectangle[{-1.5, -1.5}, {1.5, 1.5}], MeshRefinementFunction -> f]Show[mr["Wireframe"], ContourPlot[x ^ 4 + y ^ 4 == 1, {x, -1.5, 1.5}, {y, -1.5, 1.5}, ColorFunction -> Hue]]shape = [image];dist = DistanceTransform[Image[1 - ImageData[EdgeDetect[shape]]]];ImageAdjust@distdata = Transpose[Reverse[-ImageData[dist] * (2 * ImageData[shape] - 1)]];
dataRange = Transpose[{{1, 1}, Dimensions[data]}];
if = ListInterpolation[data, dataRange, InterpolationOrder -> 1];cf = Compile[{{c, _Real, 2}, {area, _Real, 0}},
Block[{com, res},
com = Total[c] / Length[c];
res = If[area > Max[Abs[if[com[[1]], com[[2]]]], 2.5], True, False];
res]
];mesh = ToElementMesh[FullRegion[2], dataRange, MeshRefinementFunction -> cf, "MeshElementType" -> "TriangleElement"]mesh["Wireframe"]特定の2Dの三角形要素が細分化されなければならない場合にTrueを返す関数を作成する:
meshRefine[vertices_, area_] := area > 0.0025TrueあるいはFalseを返すコンパイルされた関数を作成する:
cmeshRefine = Compile[{{v, _Real, 2}, {a, _Real, 0}},
meshRefine[v, a], {{_meshRefine, True | False}}]コンパイルされた細分化関数で境界メッシュの完全メッシュを作成する:
mesh = ToElementMesh[Polygon[{{1, 0}, {0, 2}, {-1, 0}}], MeshRefinementFunction -> cmeshRefine]mesh["Wireframe"]特定の3Dの四面体要素が細分化されなければならない場合には,Trueを返すコンパイルされた関数を作成する:
cf = Compile[{{coordinates, _Real, 2}, {vol, _Real, 0}},
If[vol > 1, True, False]
];bmesh = ToBoundaryMesh["Coordinates" -> {{0., 0., 0.}, {2., 0., 0.}, {2., 0., 2.}, {0., 0., 2.}, {0., 12., 0.}, {2., 12., 0.}, {2., 12., 2.}, {0., 12., 2.}}, "BoundaryElements" -> {QuadElement[{{1, 2, 3, 4}, {5, 6, 7, 8}, {1, 5, 6, 2}, {2, 6, 7, 3}, {3, 7, 8, 4}, {4, 8, 5, 1}}]}]mesh = ToElementMesh[bmesh, MaxCellMeasure -> Infinity, MeshRefinementFunction -> cf]mesh["Wireframe"["MeshElement" -> "MeshElements"]]1Dでは,DiscretizeRegionを使って細分化を行う:
ToElementMesh[DiscretizeRegion[Interval[{0, 2}], MeshRefinementFunction -> Function[{vertices, length}, If[Mean[vertices] > 1, length > 0.1, length > 0.01]]]]"NodeReordering" (2)
領域からElementMeshを作成する:
mesh = ToElementMesh[Disk[]]inci = Join@@ElementIncidents[mesh["MeshElements"]];
saPos = Flatten[Map[Outer[List, #, #]&, inci], 2];
MatrixPlot[SparseArray[saPos -> _]]mesh = ToElementMesh[Disk[], "NodeReordering" -> True]inci = Join@@ElementIncidents[mesh["MeshElements"]];
saPos = Flatten[ Map[ Outer[ List, #, #]&, inci], 2];
MatrixPlot[SparseArray[saPos -> _]]mesh = ToElementMesh[Disk[], "NodeReordering" -> Identity]inci = Join@@ElementIncidents[mesh["MeshElements"]];
saPos = Flatten[ Map[ Outer[ List, #, #]&, inci], 2];
MatrixPlot[SparseArray[saPos -> _]]"PointMarkerFunction" (1)
点マーカーは,領域境界上でDirichletConditionを指定するのに便利であり,「要素メッシュの生成」の「マーカー」セクションに詳しく説明されている.
pointMarkerFunction = Compile[{{coords, _Real, 2}, {pMarker, _Integer, 1}},
Which[
#[[1]] == 1., 2,
#[[1]] == 0., 3,
True, 4 ]& /@ coords];mesh = ToElementMesh[ImplicitRegion[0 ≤ x ≤ 1 && 0 ≤ y ≤ 1, {x, y}],
"PointMarkerFunction" -> pointMarkerFunction,
"MaxCellMeasure" -> {"Area" -> 0.1},
"MaxBoundaryCellMeasure" -> 0.25,
"MeshOrder" -> 1
]Show[mesh["Wireframe"],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementMarkerStyle" -> Blue]]]mesh["PointElements"]二次メッシュの中間ノードの点マーカーの値は,境界要素マーカーから導き出される.ここでは何も与えられていないので,値は無作為である:
mesh = ToElementMesh[ImplicitRegion[0 ≤ x ≤ 1 && 0 ≤ y ≤ 1, {x, y}],
"PointMarkerFunction" -> pointMarkerFunction,
"MaxCellMeasure" -> {"Area" -> 0.1},
"MaxBoundaryCellMeasure" -> 0.25]Show[mesh["Wireframe"],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementMarkerStyle" -> Blue]]]"BoundaryMarkerFunction"も計算された場合には,中間ノードは,境界要素マーカーから導き出された値を持つ:
boundaryMarkerFunction = Compile[{{boundaryElementCoords, _Real, 3}, {boundaryElementPointMarkres, _Integer, 2}},
Which[
Union[#] == {2}, 2,
Union[#] == {3}, 3,
True, 4 ]& /@ boundaryElementPointMarkres];mesh = ToElementMesh[ImplicitRegion[0 ≤ x ≤ 1 && 0 ≤ y ≤ 1, {x, y}],
"PointMarkerFunction" -> pointMarkerFunction,
"BoundaryMarkerFunction" -> boundaryMarkerFunction,
"MaxCellMeasure" -> {"Area" -> 0.1},
"MaxBoundaryCellMeasure" -> 0.25]Show[mesh["Wireframe"],
mesh["Wireframe"["MeshElement" -> "PointElements", "MeshElementMarkerStyle" -> Blue]]]"PointMarkers" (1)
点マーカーは,領域境界上でDirichletConditionを指定するのに役立つものである.「要素メッシュの生成」の「マーカー」.セクションに詳しい説明がある.
メッシュに点マーカーを設定する方法はいくつかある.その一つとして,境界マーカーから点マーカーを得る方法がある.
領域にメッシュを掛け,境界マーカーから点マーカーを推測する:
reg = RegionUnion[Cuboid[{1, 2, 0}, {3, 5 / 2, 1}], Cylinder[{{3, 1 / 2, 1 / 2}, {3, 3, 1 / 2}}, 1 / 4]];
(mesh = ToElementMesh[reg, "PointMarkers" -> "BoundaryDeduced"])["Wireframe"]bIDs = mesh["BoundaryElementMarkerUnion"];
Manipulate[Show[
mesh["Wireframe"["MeshElementStyle" ->
Directive[Opacity[0.2], FaceForm[LightBlue], EdgeForm[]]]],
mesh["Edgeframe"],
mesh["Wireframe"[ElementMarker == bIDs[[id]], "MeshElementStyle" -> Directive[FaceForm[LightGray], EdgeForm[]]]]
], {{id, 1, "ElementMarker ID"}, 1, Length[bIDs], 1, Appearance -> "Open"}, SaveDefinitions -> True]position = SelectPointMarkerFromBoundaryMarker[mesh, {6, 8}]Show[
mesh["Wireframe"["MeshElementStyle" -> Directive[Opacity[0.2], FaceForm[LightBlue], EdgeForm[]]]],
mesh["Edgeframe"],
mesh["Wireframe"[position, "MeshElement" -> "PointElements", "MeshElementStyle" -> Directive[Red]]]
]すべての曲面に繋がっている点のみを考慮するような交点を求める.IDが7の境界マーカーは,大きな円柱の曲面である:
position = SelectPointMarkerFromBoundaryMarker[mesh, {6, 8, 7}, Intersection[Union[#1, #2], #3]&]Show[
mesh["Wireframe"["MeshElementStyle" -> Directive[Opacity[0.2], FaceForm[LightBlue], EdgeForm[]]]],
mesh["Edgeframe"],
mesh["Wireframe"[position, "MeshElement" -> "PointElements", "MeshElementStyle" -> Directive[Red]]]
]"RegionHoles" (4)
bmesh = ToBoundaryMesh["Coordinates" -> {{-1, -1}, {1, -1}, {1, 1}, {-1, 1}, {-1 / 2, -1 / 2}, {1 / 2, -1 / 2}, {1 / 2, 1 / 2}, {-1 / 2, 1 / 2}}, "BoundaryElements" -> {LineElement[{{1, 2}, {2, 3}, {3, 4}, {4, 1}}], LineElement[{{5, 6}, {6, 7}, {7, 8}, {8, 5}}]}];
bmesh["Wireframe"]ToElementMesh[bmesh]["Wireframe"]内部を領域の穴として指定して,境界メッシュから完全なメッシュを作成する:
ToElementMesh[bmesh, "RegionHoles" -> {{0, 0}}]["Wireframe"]Ω = ImplicitRegion[x ^ 2 + y ^ 2 ≥ 1, {x, y}];
ToElementMesh[Ω, {{-2, 2}, {-2, 2}}]["Wireframe"]ToElementMesh[Ω, {{-2, 2}, {-2, 2}}, "RegionHoles" -> None]["Wireframe"]穴の領域の座標を明示的に与えないことによって,穴ではない領域にメッシュを掛ける:
ToElementMesh[Ω, {{-2, 2}, {-2, 2}}, "RegionHoles" -> {{0., 0.}}]["Wireframe"]bmesh = ToBoundaryMesh[ImplicitRegion[x ^ 2 + y ^ 2 ≤ 1 && (x - 0.5) ^ 2 + y ^ 2 - 0.05 ≥ 0 && (x + 0.5) ^ 2 + y ^ 2 - 0.05 ≥ 0 && x ^ 2 + (y - 0.5) ^ 2 - 0.05 ≥ 0 && x ^ 2 + (y + 0.5) ^ 2 - 0.05 ≥ 0, {x, y}]];
bmesh["Wireframe"]mesh = ToElementMesh[bmesh]["Wireframe"]mesh = ToElementMesh[bmesh, "RegionHoles" -> {{0.5, 0.}}, "RegionMarker" -> {{{-0.5, 0.}, 0, 0.001}}]mesh["Wireframe"]rh = {0.2, 0.2, 0.2};
bΜ = ToBoundaryMesh["Coordinates" -> {{0, 0, 0}, {2, 0, 0}, {2, 1, 0}, {0, 1, 0}, {0, 0, 1}, {2, 0, 1}, {2, 1, 1}, {0, 1, 1}, {-1, -1, -1}, {3, -1, -1}, {3, 2, -1}, {-1, 2, -1}, {-1, -1, 2}, {3, -1, 2}, {3, 2, 2}, {-1, 2, 2}}, "BoundaryElements" -> {QuadElement[{{1, 2, 3, 4}, {5, 6, 7, 8}, {2, 6, 7, 3}, {3, 7, 8, 4}, {4, 8, 5, 1}, {1, 5, 6, 2}, {9, 10, 11, 12}, {13, 14, 15, 16}, {10, 14, 15, 11}, {11, 15, 16, 12}, {12, 16, 13, 9}, {9, 13, 14, 10}}]}, "RegionHoles" -> {rh}]Show[
bΜ["Wireframe"], Graphics3D[{Red, PointSize[0.025], Point[rh]}]]mesh = ToElementMesh[bΜ, "MaxCellMeasure" -> 0.02]mesh["Wireframe"[
"MeshElement" -> "MeshElements",
"ElementMeshDirective" -> Directive[EdgeForm[Black], FaceForm[LightBlue]], PlotRange -> {{-1, 1 / 2}, All, All}]]"RegionMarker" (2)
bmesh = ToBoundaryMesh["Coordinates" -> {{0., 0.}, {1., 0.}, {1., 1.}, {0., 1.}}, "BoundaryElements" -> {LineElement[{{1, 2}, {2, 3}, {3, 1}, {3, 4}, {4, 1}}]}]bmesh["Wireframe"]{1/2,3/4}を含む境界要素はマーカー1を,{1/2,1/4}を含む領域はマーカー2を使うべきである:
mesh = ToElementMesh[bmesh, "RegionMarker" -> {{{1 / 2, 1 / 4}, 2}, {{1 / 2, 3 / 4}, 1}}, MaxCellMeasure -> 0.1]Show[
mesh["Wireframe"],
mesh["Wireframe"["MeshElementMarkerStyle" -> Blue]]
]さらに,マーカー1の領域の細分化パラメータがマーカーに与えられる:
mesh = ToElementMesh[bmesh, "RegionMarker" -> {{{1 / 2, 1 / 4}, 2}, {{1 / 2, 3 / 4}, 1, 0.015}}, MaxCellMeasure -> 0.1]Show[
mesh["Wireframe"],
mesh["Wireframe"["MeshElementMarkerStyle" -> Blue]]
]bΜ = ToBoundaryMesh["Coordinates" -> {{0, 0, 0}, {2, 0, 0}, {2, 1, 0}, {0, 1, 0}, {0, 0, 1}, {2, 0, 1}, {2, 1, 1}, {0, 1, 1}, {-1, -1, -1}, {3, -1, -1}, {3, 2, -1}, {-1, 2, -1}, {-1, -1, 2}, {3, -1, 2}, {3, 2, 2}, {-1, 2, 2}}, "BoundaryElements" -> {QuadElement[{{1, 2, 3, 4}, {5, 6, 7, 8}, {2, 6, 7, 3}, {3, 7, 8, 4}, {4, 8, 5, 1}, {1, 5, 6, 2}, {9, 10, 11, 12}, {13, 14, 15, 16}, {10, 14, 15, 11}, {11, 15, 16, 12}, {12, 16, 13, 9}, {9, 13, 14, 10}}]}]内側の部分領域が別の細分化に従う,完全な要素メッシュを作成する:
mesh = ToElementMesh[bΜ, MaxCellMeasure -> 1, "RegionMarker" -> {{{0.2, 0.2, 0.2}, 1, 0.001}, {{-0.2, 0.2, 0.2}, 2, 0.2}}]mesh["Wireframe"[
"MeshElement" -> "MeshElements",
"ElementMeshDirective" -> Directive[EdgeForm[Black], FaceForm[LightBlue]], PlotRange -> {{-1, 1 / 2}, All, All}]]"SortElements" (1)
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {2.5, 0.5}, {0., 1.}, {1., 1.}, {2., 1.}, {3., 1.}, {2.5, 1.5}, {0., 2.}, {1., 2.}, {2., 2.}};mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {QuadElement[{{1, 2, 6, 5}, {2, 3, 7, 6}, {5, 6, 11, 10}, {6, 7, 12, 11}}], TriangleElement[{{3, 4, 7}, {4, 8, 7}, {7, 9, 12}, {7, 8, 9}}]}]mesh["Wireframe"["MeshElementIDStyle" -> Red, "ContinuousElementID" -> True]]入力では,QuadElementのインスタンスがTriangleElementの前に指定されたことに注意されたい.要素は性能の理由によりソートされている.自動ソートの機能はオフにすることができる:
mesh = ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {QuadElement[{{1, 2, 6, 5}, {2, 3, 7, 6}, {5, 6, 11, 10}, {6, 7, 12, 11}}], TriangleElement[{{3, 4, 7}, {4, 8, 7}, {7, 9, 12}, {7, 8, 9}}]}, "SortElements" -> False]mesh["Wireframe"["MeshElementIDStyle" -> Red, "ContinuousElementID" -> True]]"SteinerPoints" (1)
2Dの三角メッシュについては,Steiner点の挿入が制御できる.この場合には,境界は境界の大きさを守り,それ以上分割を行わない:
mesh = ToElementMesh[Disk[], "MaxBoundaryCellMeasure" -> .5, "SteinerPoints" -> False, AccuracyGoal -> 1];
mesh["Wireframe"]c = mesh["Coordinates"];
Show[
mesh["Wireframe"],
Graphics[GraphicsComplex[c, {Red, Point[Range[Length[c]]]}]]]mesh = ToElementMesh[Disk[], "MaxBoundaryCellMeasure" -> .5, "SteinerPoints" -> False, "MeshOrder" -> 1, AccuracyGoal -> 1];
c = mesh["Coordinates"];
Show[
mesh["Wireframe"],
Graphics[GraphicsComplex[c, {Red, Point[Range[Length[c]]]}]]]アプリケーション (2)
GeoGraphicsから川のElementMeshを作成する:
gr = GeoGraphics[GeoPosition[{38.194457, -76.439069}], GeoRange -> Quantity[2, "Kilometers"], ImageSize -> 500];
r = Rasterize[gr];
img = RegionBinarize[r, {{227.344, 87.49013689343508}}, 0.1];bmr = ImageMesh[img];
Show[r, ToElementMesh[bmr]["Wireframe"]]
で2つのネストした半環帯の境界メッシュを生成する.それぞれの環帯は異なる部分領域を表す.1つ目の部分領域は内半径が
で外半径が
,2つ目の部分領域は内半径が
,外半径が
である.
まず3つの半円盤を作成し,次に3つの部分領域の和を生成し,最後に2つの環帯を作成するために最初の半円盤を内側の穴とする.
Subscript[r, 1] = 3 / 1000;
Subscript[r, 2] = 10 / 1000;Subscript[r, 3] = 12 / 1000;Circleを使って半円盤を作成する:
c = Circle[{0, 0}, #, {-π / 2, π / 2}]& /@ {Subscript[r, 1], Subscript[r, 2], Subscript[r, 3]};半円盤の和が作成されると,左の境界は自動的に和から削除される.このため,領域をもう一度繋げるために,線分が作成され,半円盤の和に繋げられる.1つ目の半円盤に穴を開けるために,和を
から
まで,および
から
まで
方向に繋げ,1つ目の半円盤を脇にのける.
l = {Line[{{0, Subscript[r, 1]}, {0, Subscript[r, 3]}}], Line[{{0, -Subscript[r, 1]}, {0, -Subscript[r, 3]}}]};ru = RegionUnion[Flatten[{l, c}]];regionMarkers = <|"layer1" -> 1, "layer2" -> 2|>;RegionMarkerを使って,定義された部分領域で要素メッシュを生成し,メッシュを
に限る:
mesh = ToElementMesh[ru, {{-0.01, Subscript[r, 3]}, {-Subscript[r, 3], Subscript[r, 3]}}, "RegionMarker" -> {{{Subscript[r, 2] / 2, 0}, regionMarkers["layer1"]}, {{0.011, 0}, regionMarkers["layer2"]}}]mesh["Wireframe"["MeshElementStyle" -> {Directive[FaceForm[Gray]], Directive[FaceForm[LightBlue]]}]]特性と関係 (5)
ElementMeshは,NDSolveによって返されるInterpolatingFunctionの一部である:
if = NDSolveValue[{-(D[u[x, y], x, x] + D[u[x, y], y, y]) == 1, DirichletCondition[u[x, y] == 0, x ≤ -1], DirichletCondition[u[x, y] == 1, x ≥ 1]}, u, {x, -1, 1}, {y, 0, 1}]Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"]InterpolatingFunctionCoordinates[if]ElementMeshをNDSolveに渡す:
NDSolveValue[{-Laplacian[u[x, y], {x, y}] == 1, DirichletCondition[u[x, y] == 0, x ≤ -1], DirichletCondition[u[x, y] == 1, x ≥ 1]}, u, {x, y}∈ToElementMesh[Rectangle[{-1, -1}, {1, 0}]]]NDEigensystem[Laplacian[u[x, y], {x, y}], u, {x, y}∈ToElementMesh[Rectangle[{-1, -1}, {1, 0}]], 3]ToElementMeshのオプションをNDSolveに渡し,定常偏微分方程式を解く:
if = NDSolveValue[{-(D[u[x, y], x, x] + D[u[x, y], y, y]) == 1, DirichletCondition[u[x, y] == 0, x ≤ -1], DirichletCondition[u[x, y] == 1, x ≥ 1]}, u, {x, y}∈Rectangle[{-1, -1}, {1, 0}], Method -> {"FiniteElement", "MeshOptions" -> {"MaxCellMeasure" -> 0.001}}]Needs["DifferentialEquations`InterpolatingFunctionAnatomy`"]InterpolatingFunctionCoordinates[if]ToElementMesh[Rectangle[{-1, -1}, {1, 0}], "MaxCellMeasure" -> 0.001]ToElementMeshのオプションをNDSolveに渡し,時間依存の偏微分方程式を解く:to solve a time-dependent PDE:
NDSolveValue[{D[u[t, x, y], t] - Laplacian[u[t, x, y], {x, y}] - 20 == 0, DirichletCondition[u[t, x, y] == 0, x == 0 || x == 2], u[0, x, y] == 0}, u, {t, 0, 1}, {x, y}∈Rectangle[{-1, -1}, {1, 0}], Method -> {"PDEDiscretization" -> {Automatic, "SpatialDiscretization" -> {"FiniteElement", "MeshOptions" -> {MaxCellMeasure -> 0.01}}}}]考えられる問題 (11)
入力の記号的領域に境界がない場合には,デフォルトの
からの境界ボックスが各空間方向に想定される:
ToElementMesh[ImplicitRegion[x ≤ 1 / 3 || 2 / 3 ≤ x, {x, y}]]["Wireframe"]
明示的な境界ボックスを指定することによって,デフォルトを無効にできる:
ToElementMesh[ImplicitRegion[x ≤ 1 / 3 || 2 / 3 ≤ x, {x, y}], {{0, 1}, {0, 1}}]["Wireframe"]ToElementMesh[RegionDifference[RegionUnion[Disk[], Rectangle[{0, 0}, {2, 2}]], Disk[{1 / 2, 1 / 2}, 1 / 16]], "BoundaryMeshGenerator" -> "RegionPlot"]["Wireframe"]ToElementMesh[RegionDifference[RegionUnion[Disk[], Rectangle[{0, 0}, {2, 2}]], Disk[{1 / 2, 1 / 2}, 1 / 16]], "BoundaryMeshGenerator" -> "RegionPlot", "MaxBoundaryCellMeasure" -> 0.05]["Wireframe"]ImplicitRegionでは,指定のない記号パラメータを使うことはできない:
ToElementMesh[ImplicitRegion[2a x ^ 2 - 1 <= y <= x ^ 2, {x, y}], {{-1, 1}, {-1, 1}}]a = 2ToElementMesh[ImplicitRegion[2a x ^ 2 - 1 <= y <= x ^ 2, {x, y}], {{-1, 1}, {-1, 1}}]境界ボックスが領域指定と交差する場合には,結果として低品質のメッシュが作成されることがある:
Ω = ImplicitRegion[x ^ 2 + y ^ 2 ≥ 1, {x, y}]mesh = ToElementMesh[Ω, {{-1, 1}, {-1, 1}}];
mesh["Wireframe"]Min[mesh["Quality"]]mesh = ToElementMesh[Ω, {{-1.1, 1.1}, {-1.1, 1.1}}];
mesh["Wireframe"]Min[mesh["Quality"]]ElementMeshのメッシュ要素は,同じ次数のものでなければならない:
coordinates = {{0., 0.}, {1., 0.}, {2., 0.}, {2.5, 0.5}, {0., 1.}, {1., 1.}, {2., 1.}, {3., 1.}, {2.5, 1.5}, {0., 2.}, {1., 2.}, {2., 2.}, {0., 0.5}, {0., 1.5}, {0.5, 0.}, {0.5, 1.}, {0.5, 2.}, {1., 0.5}, {1., 1.5}, {1.5, 0.}, {1.5, 1.}, {1.5, 2.}, {2., 0.5}, {2., 1.5}, {2.25, 0.25}, {2.25, 0.75}, {2.25, 1.25}, {2.25, 1.75}, {2.5, 1.}, {2.75, 0.75}, {2.75, 1.25}};triIncidents = {{3, 4, 7}, {4, 8, 7}, {7, 9, 12}, {7, 8, 9}};quadIncidents = {{1, 2, 6, 5, 15, 18, 16, 13}, {2, 3, 7, 6, 20, 23, 21, 18}, {5, 6, 11, 10, 16, 19, 17, 14}, {6, 7, 12, 11, 21, 24, 22, 19}};ToElementMesh["Coordinates" -> coordinates, "MeshElements" -> {TriangleElement[triIncidents],
QuadElement[quadIncidents]}];要素インシデントは,反時計回りの順に与えられなければならない:
ToElementMesh["Coordinates" -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}, "MeshElements" -> {QuadElement[{{1, 4, 3, 2}}]}]%["Wireframe"]ToElementMesh["Coordinates" -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}, "MeshElements" -> {QuadElement[{{1, 2, 3, 4}}]}]mesh = ToElementMesh["Coordinates" -> {{0, 0}, {1, 0}, {0.9, 0.9}, {0, 1}}, "MeshElements" -> {QuadElement[{{1, 4, 2, 3}}]}]mesh["Wireframe"]mesh = ToElementMesh["Coordinates" -> {{0, 0}, {1, 0}, {0.9, 0.9}, {0, 1}}, "MeshElements" -> {QuadElement[{{1, 2, 3, 4}}]}]mesh = ToElementMesh["Coordinates" -> {{0, 0}, {1, 0}, {0.9, 0.9}, {0, 1}}, "MeshElements" -> {QuadElement[{{1, 3, 2, 4}}]}]mesh["Wireframe"]MeshRegionからElementMeshへの変換が,メッシュを直接変換する形で行われるとは限らない:
pointsToMesh[data_] := MeshRegion[Transpose[{data}], Line@Table[{i, i + 1}, {i, Length[data] - 1}]];
data = Table[Exp[x], {x, 0., 2, 0.1}];
r1 = pointsToMesh[data];
mr = RegionProduct[r1, r1]ToElementMesh[mr]["Wireframe"]これは,ToElementMeshが与えられたメッシュのオプションに沿えることができなければならないためである.MeshRegionを生成するのに使われたパラメータを推定し,ToElementMeshオプションが満たされるかどうかを確かめることは不可能である.MeshRegionを直接ElementMeshに変換することが可能な場合もある:
mr["MakeRepresentation"["ElementMesh"]]["Wireframe"]この場合には,ToGradedMeshとElementMeshRegionProductを使うことによって,ElementMeshを直接生成することが可能である:
r2 = ToGradedMesh[Line[{{0}, {1}}], <|"Alignment" -> "Left"|>]ElementMeshRegionProduct[r2, r2]["Wireframe"]ToElementMeshの引数は規則として指定し,正しい順序("Coordinates","MeshElements"の順序で,次にオプショナルの規則"BoundaryElements"と"PointElements"を加える)で与えなければならない:
ToElementMesh["MeshElements" -> {TriangleElement[{{1, 2, 3}, {3, 4, 1}}]}, "Coordinates" -> {{0., 0.}, {1., 0.}, {1., 1.}, {0., 1.}}]ToElementMesh["Coordinates" -> {{0., 0.}, {1., 0.}, {1., 1.}, {0., 1.}}, "MeshElements" -> {TriangleElement[{{1, 2, 3}, {3, 4, 1}}]}]陰的な領域についてのメッシュ生成アルゴリズムの中には,完全には決定性ではなく,同じ入力に対して少し異なるメッシュを返すものもある:
Ω = ImplicitRegion[x ^ 2 + y ^ 2 + z ^ 2 <= 1, {x, y, z}];
mesh = ToElementMesh[Ω]mesh = ToElementMesh[Ω]おもしろい例題 (3)
スペースシャトルのオービタをElementMeshに変換する:
ToElementMesh[DiscretizeGraphics[ExampleData[{"Geometry3D", "SpaceShuttle"}, "GraphicsComplex"]]]["Wireframe"]画像を要素メッシュに変換するには,まず,画像を距離関数に変換する:
shape = [image];dist = DistanceTransform[Image[1 - ImageData[EdgeDetect[shape]]]];ImageAdjust@distdata = Transpose[Reverse[-ImageData[dist] * (2 * ImageData[shape] - 1)]];
dataRange = Transpose[{{x, y}, {1, 1}, Dimensions[data]}];
if = ListInterpolation[ data, dataRange[[All, {2, 3}]], InterpolationOrder -> 1];ToElementMesh[ImplicitRegion[if[x, y] ≤ 0, {x, y}], Transpose[{{1, 1}, Dimensions[data]}], "BoundaryMeshGenerator" -> "RegionPlot"]%["Wireframe"]以下の拡張例は,ペンローズの三角形を作成するもので,ラプラス方程式を解くことに基づく.パラメータを指定する:
Needs["NDSolve`FEM`"]parameters = {centerWidth -> 10, aveLen -> 1, minLen -> 0.05, sharpness -> 2};vertices = Table[{-r1 Sin[(2 π x/3)] - r2 Sin[(π x/2)] Sin[(1/6) π (-1 + 4 x)] - r2 Cos[(π x/2)] Sin[(1/6) π (1 + 4 x)], r1 Cos[(2 π x/3)] + r2 Cos[(π x/2)] Cos[(1/6) π (1 + 4 x)] + r2 Cos[(1/6) π (-1 + 4 x)] Sin[(π x/2)], r2 r3 Cos[(π x/2)] - r2 r3 Sin[(π x/2)]} /. {r1 -> (2 + centerWidth * 2 / 3)Sqrt[3 / 4], r2 -> 1, r3 -> 1}, {x, {0, 9, 8, 7, 10, 11}}] /. parameters;Graphics3D[Point[vertices]]指定の位置において,頂点間の最大間隔を2乗したものを返す関数を作成する:
edgeSquaredLengthFunction[plist_, {minLen_, aveLen_, sharpness_}] := Function[vertices, aveLen^2(1 - (1 - (minLen / aveLen)^2) 2 ^ (-sharpness(#.#&[plist[[6, ;; 2]] - Mean[vertices]] / (#.#&[{-1, 1}.plist[[{3, 6}, ;; 2]]]))))]指定の位置において,頂点間の最大間隔を2乗したものを返す関数を作成する:
edgeSquaredLength = edgeSquaredLengthFunction[vertices, {minLen, aveLen, sharpness} /. parameters];boundaryvals = Interpolation[N[{#[[1 ;; 2]], #[[3]]}]& /@ vertices, InterpolationOrder -> 1]lineToLine = Interpolation[Table[{i, vertices[[Mod[i, 6, 1], 1 ;; 2]]}, {i, 7}], InterpolationOrder -> 1, PeriodicInterpolation -> True]intermFunc[p1_, p2_] := If[p2 > p1, Join[{p1}, #, {p1 + p2} / 2, Reverse[p1 + p2 - #]], Join[{p2}, (p1 + p2) - #, {p1 + p2} / 2, Reverse[#]]]&[NestWhileList[# + (p2 - p1)Sqrt[edgeSquaredLength[{lineToLine[#]}]] / Norm[{-1, 1}.vertices[[Mod[{p1, p2}, 6, 1], ;; 2]]]&, p1, Between[{p1, (p1 + p2) / 2}]][[2 ;; -2]]];ラプラス方程式の境界多角形を構築する.頂点は,面を接合したときに辺上のすべての頂点が適切に重なるような間隔に置かれる:
boundary = Polygon[lineToLine /@ Flatten[{intermFunc[1, 2], intermFunc[3, 2], 3, Reverse[Rest[10 - #]], intermFunc[4, 5], intermFunc[6, 5], #}&[intermFunc[6, 7]]]];境界に点を追加せずに,ラプラス偏微分方程式を解くメッシュを作成する:
mesh = ToElementMesh[boundary, "SteinerPoints" -> False, MeshRefinementFunction -> Function[{vertices, area}, area > Evaluate[edgeSquaredLength[vertices]Sqrt[3] / 4]]];mesh["Wireframe"]sol = NDSolveValue[{Subsuperscript[∇, {x, y}, 2]u[x, y] == 0, DirichletCondition[u[x, y] == boundaryvals[x, y], True]}, u, {x, y}∈mesh]face = Plot3D[sol[x, y], {x, y}∈sol["ElementMesh"], Mesh -> None, AspectRatio -> {1, 1, 1}]gr = Graphics3D[Table[Rotate[Rotate[face[[1]], Pi j, {0, 1, 0}], i 2Pi / 3, {0, 0, 1}], {i, 3}, {j, 2}]]mesh = ToElementMesh[DiscretizeGraphics[gr]]mesh["Wireframe"]テクニカルノート
関連するガイド
-
▪
- 有限要素法
テキスト
Wolfram Research (2014), ToElementMesh, Wolfram言語関数, https://reference.wolfram.com/language/FEMDocumentation/ref/ToElementMesh.html (2026年に更新).
CMS
Wolfram Language. 2014. "ToElementMesh." Wolfram Language & System Documentation Center. Wolfram Research. Last Modified 2026. https://reference.wolfram.com/language/FEMDocumentation/ref/ToElementMesh.html.
APA
Wolfram Language. (2014). ToElementMesh. Wolfram Language & System Documentation Center. Retrieved from https://reference.wolfram.com/language/FEMDocumentation/ref/ToElementMesh.html
BibTeX
@misc{reference.wolfram_2026_toelementmesh, author="Wolfram Research", title="{ToElementMesh}", year="2026", howpublished="\url{https://reference.wolfram.com/language/FEMDocumentation/ref/ToElementMesh.html}", note=[Accessed: 05-September-2026]}
BibLaTeX
@online{reference.wolfram_2026_toelementmesh, organization={Wolfram Research}, title={ToElementMesh}, year={2026}, url={https://reference.wolfram.com/language/FEMDocumentation/ref/ToElementMesh.html}, note=[Accessed: 05-September-2026]}