그레이드 메쉬 생성
왼쪽 절반에 더 미세한 메쉬와 오른쪽 절반에 거친 메쉬를 사용하여 큐브 내부에 그레이딩 된 메쉬를 만들고 싶습니다. 내 계획은 2D 평면으로 큐브를 분할 한 다음 경계 메쉬를 생성 한 다음 ToBoundaryMesh(파티션에도 경계 메쉬를 생성하기위한 의도 임) 파티션 의 왼쪽과 오른쪽에 ToElementMesh다르게 적용하는 것이 었습니다 MaxCellMeasure. 내 코드는 다음과 같습니다.
reg = RegionUnion[Cuboid[],
ImplicitRegion[x == 0.5 && 0 <= y <= 1 && 0 <= z <= 1, {x, y, z}]];
ToBoundaryMesh[reg]
다음과 같은 오류가 발생합니다.
BoundaryDiscretizeRegion::brepl: There are components in RegionUnion[Cuboid[{0,0,0}],ImplicitRegion[x==0.5&&0<=y<=1&&0<=z<=1,{x,y,z}]] having dimension lower than the embedding dimension 3 that will not be included in the boundary representation.
그레이드 메쉬를 어떻게 얻을 수 있습니까? 어떤 도움이라도 대단히 감사합니다.
편집하다
나는 다음을 시도했다. 공통 경계가있는 두 개의 직육면체를 만들어 Or. 두 입방 영역 (라벨 (10, 20))를 사용하여 마킹시키면서 I 메쉬 생성 RegionMarkerI 또한 지정하는, MaxCellMeasure1 : 0.01로 두 영역을. 다음은 코드입니다.
reg = ImplicitRegion[Or[0 <= x <= 0.5 && 0 <= y <= 1 && 0 <= z <= 1,
0.5 <= x <= 1 && 0 <= y <= 1 && 0 <= z <= 1], {x, y, z}];
mesh = ToElementMesh[reg,
"RegionMarker" -> {{{0.1, 0.5, 0.5}, 10, 1}, {{0.6, 0.5, 0.5}, 20, 0.01}}];
그러나 여전히 두 영역에서 균일 한 크기의 메시를 생성합니다. 문제를 극복하는 방법에 대한 아이디어가 있습니까?
답변
이방성 육면체 메시를 만드는 방법은 "단순한"솔루션에 대한 OP의 욕구를 충족시키지 못합니다.
영감은 Tensor Product Grid Example 에서 비롯됩니다 . 아이디어는 각 방향을 따라 일련의 1D 메쉬 세그먼트를 만들고 RegionProduct.
다음은 x 방향을 따라 균일 한 메쉬에 연결된 그레이딩 된 메쉬의 예입니다. 이러한 유형의 메싱의 실제 예는 유체가 벽에서 열 구배를 포착하기 위해 경계층 또는 등급이 매겨진 메시를 가지며 고체가 균일하게 메시 될 수있는 복합 열 전달입니다.
그레이 디드 메시를 빌드하는 일부 도우미 함수 :
(* Import required package *)
Needs["NDSolve`FEM`"];
(* Define Some Helper Functions For Structured Quad Mesh*)
pointsToMesh[data_] :=
MeshRegion[Transpose[{data}],
Line@Table[{i, i + 1}, {i, Length[data] - 1}]];
unitMeshGrowth[n_, r_] :=
Table[(r^(j/(-1 + n)) - 1.)/(r - 1.), {j, 0, n - 1}]
meshGrowth[x0_, xf_, n_, r_] := (xf - x0) unitMeshGrowth[n, r] + x0
firstElmHeight[x0_, xf_, n_, r_] :=
Abs@First@Differences@meshGrowth[x0, xf, n, r]
lastElmHeight[x0_, xf_, n_, r_] :=
Abs@Last@Differences@meshGrowth[x0, xf, n, r]
findGrowthRate[x0_, xf_, n_, fElm_] :=
Quiet@Abs@
FindRoot[firstElmHeight[x0, xf, n, r] - fElm, {r, 1.0001, 100000},
Method -> "Brent"][[1, 2]]
meshGrowthByElm[x0_, xf_, n_, fElm_] :=
N@Sort@Chop@meshGrowth[x0, xf, n, findGrowthRate[x0, xf, n, fElm]]
meshGrowthByElm0[len_, n_, fElm_] := meshGrowthByElm[0, len, n, fElm]
flipSegment[l_] := (#1 - #2) & @@ {First[#], #} &@Reverse[l];
extendMesh[mesh_, newmesh_] := Union[mesh, Max@mesh + newmesh]
그레이딩 된 메시를 만들기위한 주석이 달린 워크 플로우 :
(*Define parameters*)
(*Lengths*)
(*2 horizontal segments*)
h1 = 0.5;
h2 = 0.5;
v = 1;(*Vertical*)
d = 1;(*Depth*)
(*Number of elements per segment*)
nh1 = 15;
nh2 = 10;
nv = 20;
nd = 5;
(*Association for Clearer Region Assignment*)
reg = <|"left" -> 1, "right" -> 2|>;
(*Create mesh segments*)
(*Horizontal segments*)
(* left segment *)
(*First element is 1/50th of seg length*)
(*Flip segment so smallest elm at interface *)
sh1 = flipSegment@meshGrowthByElm0[h1, nh1, h1/50];
(*Make right segment uniform mesh size*)
sh2 = Subdivide[h2, nh2];
(*Glue segments together*)
segh = extendMesh[sh1, sh2];
(*View individual horizontal segments*)
Print["Horizontal segments"]
pointsToMesh /@ {sh1, sh2}
(*View combined segments*)
Print["Combined horizontal segments"]
rh = pointsToMesh@segh
(*Vertical Segment*)
Print["Vertical segment"]
rv = pointsToMesh@Subdivide[v, nv]
(*View Region Product of horiz and vert segs*)
Print["2D Region via RegionProduct"]
RegionProduct[rh, rv]
(*Depth Segment*)
Print["Depth segment"]
rd = pointsToMesh@Subdivide[d, nd]
(*Create a tensor product grid from h,v,and d segments*)
rp = RegionProduct[rh, rv, rd];
(*View mesh*)
Print["Full Extruded 3D Region via RegionProduct"]
HighlightMesh[rp, Style[1, Orange]]
(*Extract Coords from RegionProduct*)
crd = MeshCoordinates[rp];
(*grab hexa element incidents RegionProduct mesh*)
inc = Delete[0] /@ MeshCells[rp, 3];
mesh = ToElementMesh["Coordinates" -> crd,
"MeshElements" -> {HexahedronElement[inc]}];
(*Extract bmesh*)
bmesh = ToBoundaryMesh[mesh];
(*Iron RegionMember Function*)
Ω3Diron = Cuboid[{0, 0, 0}, {h1, v, d}];
rmf = RegionMember[Ω3Diron];
regmarkerfn = If[rmf[#], reg["left"], reg["right"]] &;
(*Get mean coordinate of each hexa for region marker assignment*)
mean = Mean /@ GetElementCoordinates[mesh["Coordinates"], #] & /@
ElementIncidents[mesh["MeshElements"]] // First;
regmarkers = regmarkerfn /@ mean;
(*Create and view element mesh*)
Print["Converted Hexa Element Mesh"]
mesh = ToElementMesh["Coordinates" -> mesh["Coordinates"],
"MeshElements" -> {HexahedronElement[inc, regmarkers]}];
Graphics3D[
ElementMeshToGraphicsComplex[bmesh,
VertexColors -> (ColorData["BrightBands"] /@
Rescale[regmarkerfn /@ bmesh["Coordinates"]])], Boxed -> False]