You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.5 KiB
156 lines
5.5 KiB
%--------------------------
|
|
% @Author: Jingqiao Hu
|
|
% @Date: 2021-02-25 15:13:41
|
|
% @LastEditTime: 2021-02-26 19:43:34
|
|
|
|
% Generate 3d hex mesh for FEM;
|
|
% y 4-----3
|
|
% | /| /|
|
|
% 0---x 8-----7 2
|
|
% / | |/
|
|
% z 5-----6
|
|
% 1. COORDINATES: first y(1-0) -> x(0-1) -> z(0-1)
|
|
% 2. CONNECTIVITY: 1->8 TODO:
|
|
% 3. PARAMETERS: nelx * nely * nelz macro-elements with microx^3 micro-elements,
|
|
% size of each element is lx^3
|
|
% 4. RETRUN: nodes: nodes coordinates as (cx, cy, cz), size of [nodes_num, 3]
|
|
%--------------------------
|
|
function nodes = mesh3D(nelx, nely, nelz, microx, num_b, lx, opt_scale)
|
|
|
|
if opt_scale==1
|
|
%% 1-scale
|
|
|
|
dx = lx / microx;
|
|
globaly = nely * microx;
|
|
globalx = nelx * microx;
|
|
globalz = nelz * microx;
|
|
% Number of points
|
|
npx = globalx + 1;
|
|
npy = globaly + 1;
|
|
npz = globalz + 1;
|
|
% Discretizing
|
|
nx = linspace(0, dx*globalx, npx);
|
|
ny = linspace(0, dx*globaly, npy);
|
|
nz = linspace(0, dx*globalz, npz);
|
|
[gridx, gridy, gridz] = meshgrid(nx, fliplr(ny), nz);
|
|
% [gridx, gridy, gridz] = meshgrid(nx, (ny), nz);
|
|
|
|
nodes = [gridx(:), gridy(:), gridz(:)];
|
|
|
|
else
|
|
%% 2-scale
|
|
nodes = nodes_2scale(nelx, nely, nelz, num_b, lx);
|
|
end
|
|
end
|
|
|
|
function nodes = nodes_2scale(nelx, nely, nelz, num_b, lx)
|
|
|
|
new_nelx = nelx * (num_b + 1);
|
|
new_nely = nely * (num_b + 1);
|
|
new_nelz = nelz * (num_b + 1);
|
|
Num_node = (1+new_nelx) * (new_nely+1) * (new_nelz+1);
|
|
nodenrs = reshape(1:Num_node, 1+new_nely, 1+new_nelx, 1+new_nelz);
|
|
|
|
dx = lx / (num_b+1);
|
|
nx = linspace(0, lx*nelx, new_nelx+1);
|
|
ny = linspace(0, lx*nely, new_nely+1);
|
|
nz = linspace(0, lx*nelz, new_nelz+1);
|
|
[gridx, gridy, gridz] = meshgrid(nx, fliplr(ny), nz);
|
|
gridx = gridx(:);
|
|
gridy = gridy(:);
|
|
gridz = gridz(:);
|
|
|
|
[up, front, down, back, left, right, dofs_num] = surface_dofs_id(num_b+1);
|
|
surface_nodes = zeros(nelx, nely, nelz, dofs_num/3);
|
|
|
|
for i = 1 : nelx
|
|
for j = 1 : nely
|
|
for k = 1 : nelz
|
|
nodes_ele = nodenrs((j-1)*(num_b+1)+1 : j*(num_b+1)+1, ...
|
|
(i-1)*(num_b+1)+1 : i*(num_b+1)+1, ...
|
|
(k-1)*(num_b+1)+1 : k*(num_b+1)+1);
|
|
inner = nodes_ele(2:end-1, 2:end-1, 2:end-1);
|
|
surface_nodes(i,j,k,:) = setdiff(nodes_ele(:), inner(:));
|
|
end
|
|
end
|
|
end
|
|
global_nodes = unique(surface_nodes(:)); % remove interior nodes of every macro-ele
|
|
|
|
nodes = [gridx(global_nodes), gridy(global_nodes), gridz(global_nodes)];
|
|
end
|
|
|
|
function nodes_2scale_way2()
|
|
dx = lx / (num_b+1);
|
|
new_nelx = nelx * (num_b + 1);
|
|
new_nely = nely * (num_b + 1);
|
|
new_nelz = nelz * (num_b + 1);
|
|
|
|
% there are two nodes distribution of y0x, n is orignal node & p is bezier pnt
|
|
% 1. n-p-p-n 2. p-p-p-p
|
|
% p-p-p-p p p
|
|
% p-p-p-p p p
|
|
% n-p-p-n p-p-p-p
|
|
xy_nodes1_num = (new_nelx+1) * (new_nely+1);
|
|
xy_nodes2_num = (nelx+1)*(nely+1) + num_b*nely*(nelx+1) + num_b*nelx*(nely+1);
|
|
|
|
nodes = zeros(xy_nodes1_num*(nelz+1) + xy_nodes2_num*nelz*num_b, 3);
|
|
nodes_y0x = mesh_y0x(lx, nelx, nely, num_b);
|
|
|
|
nz = linspace(0, dx*new_nelz, new_nelz+1);
|
|
nid = 0;
|
|
% figure;
|
|
for k = 1 : nelz*(num_b+1) + 1
|
|
% now nid is the last node-id of this y0x
|
|
if mod(k-1, num_b+1)==0
|
|
nx = linspace(0, lx*nelx, new_nelx+1);
|
|
ny = linspace(0, lx*nely, new_nely+1);
|
|
[gridx, gridy, gridz] = meshgrid(nx, fliplr(ny), nz(k));
|
|
|
|
nodes(nid+1:nid+xy_nodes1_num, :) = [gridx(:), gridy(:), gridz(:)];
|
|
% scatter3(nodes(nid+1:nid+xy_nodes1_num,1),nodes(nid+1:nid+xy_nodes1_num,2),nodes(nid+1:nid+xy_nodes1_num,3),'filled'); axis equal; hold on
|
|
nid = nid + xy_nodes1_num;
|
|
else
|
|
gridz = repmat(nz(k), size(nodes_y0x(:,1)));
|
|
nodes(nid+1:nid+xy_nodes2_num, :) = [nodes_y0x, gridz(:)];
|
|
% scatter3(nodes(nid+1:nid+xy_nodes2_num,1),nodes(nid+1:nid+xy_nodes2_num,2),nodes(nid+1:nid+xy_nodes2_num,3),'filled'); axis equal;
|
|
nid = nid + xy_nodes2_num;
|
|
end
|
|
end
|
|
% figure; scatter3(nodes(:,1),nodes(:,2),nodes(:,3),'filled'); axis equal;
|
|
end
|
|
|
|
% mesh nodes distribution-2 of y0x
|
|
% addNum: add control points num, could be zero
|
|
% nodes order: col by col
|
|
function [nodes] = mesh_y0x(lx, nelx, nely, addNum)
|
|
nodeNum = (nelx+1)*(nely+1) + addNum*nely*(nelx+1) + addNum*nelx*(nely+1);
|
|
nodes = zeros(nodeNum, 2);
|
|
|
|
left_pnum = nely+1 + addNum*nely;
|
|
center_pnum = (nely+1) * addNum;
|
|
dx = lx / (addNum+1);
|
|
|
|
for i = 0:nelx
|
|
% left col
|
|
cy = linspace(lx*nely, 0, left_pnum)';
|
|
cx = repmat(lx * i, left_pnum, 1);
|
|
|
|
idx = (1:left_pnum) + i * (left_pnum + center_pnum);
|
|
nodes(idx, :) = [cx, cy];
|
|
|
|
if i>nelx-1
|
|
break;
|
|
end
|
|
|
|
% center col
|
|
cy = linspace(lx*nely, 0, nely+1)';
|
|
cy = repmat(cy, addNum, 1);
|
|
cx = linspace(lx * i+dx, lx * (i+1)-dx, addNum);
|
|
cx = repmat(cx, nely+1, 1);
|
|
|
|
idx = (1:center_pnum)+left_pnum + i * (left_pnum + center_pnum);
|
|
nodes(idx, :) = [cx(:), cy];
|
|
|
|
% NOTE: no right col, as it is next left col
|
|
end
|
|
end
|