Tạo lưới phân loại
Tôi muốn tạo lưới phân cấp bên trong một khối lập phương, với lưới mịn hơn ở nửa bên trái và lưới thô hơn ở nửa bên phải. Kế hoạch của tôi là phân vùng khối lập phương bằng một mặt phẳng 2D và sau đó tạo lưới ranh giới với ToBoundaryMesh(nó được dự định để tạo lưới ranh giới trên phân vùng) và sau đó áp dụng ToElementMeshvới MaxCellMeasurecác bên trái và bên phải của phân vùng. Đây là mã của tôi:
reg = RegionUnion[Cuboid[],
ImplicitRegion[x == 0.5 && 0 <= y <= 1 && 0 <= z <= 1, {x, y, z}]];
ToBoundaryMesh[reg]
dẫn đến lỗi sau:
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.
Làm thế nào tôi có thể đạt được một lưới được phân loại? Bất kỳ sự giúp đỡ nào cũng được đánh giá cao.
Biên tập
Tôi đã thử những điều sau đây. Tôi đã tạo hai hình khối có ranh giới chung và nối chúng với Or. Sau đó, tôi tạo một lưới trong khi đánh dấu hai vùng hình khối (nhãn 10 và 20) bằng cách sử dụng RegionMarker, trong đó tôi cũng chỉ định MaxCellMeasurehai vùng là 1 và 0,01. Đây là mã:
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}}];
Nhưng nó vẫn tạo ra một lưới có kích thước đồng đều ở hai vùng. Bất kỳ ý tưởng về cách khắc phục vấn đề?
Trả lời
Đây là một phương pháp để xây dựng một lưới lục diện dị hướng, mặc dù nó không đáp ứng mong muốn của OP về một giải pháp "đơn giản".
Nguồn cảm hứng đến từ Ví dụ Lưới Sản phẩm Tensor . Ý tưởng là tạo ra một loạt các đoạn lưới 1D dọc theo mỗi hướng và xây dựng lưới bằng cách sử dụng RegionProduct.
Đây là một ví dụ về lưới được phân cấp được kết nối với lưới đồng nhất dọc theo hướng x. Một ví dụ thực tế của kiểu chia lưới này là sự truyền nhiệt liên hợp trong đó chất lỏng có lớp ranh giới hoặc lưới phân cấp để thu giữ các gradien nhiệt tại thành và chất rắn có thể được chia lưới đồng nhất.
Một số chức năng trợ giúp để xây dựng các lưới được phân loại:
(* 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]
Quy trình làm việc đã nhận xét để tạo lưới được phân loại:
(*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]