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.
 
 
 
 

163 lines
5.4 KiB

%--------------------------
% @Author: Jingqiao Hu
% @Date: 2021-02-25 17:56:07
% @LastEditTime: 2022-01-24 23:55:27
% control pnts of one face of this macro-ele
% p00-p01-p02-p03
% p10-p11-p12-p13
% p20-p21-p22-p23
% p30-p31-p32-p33
% for one face, the order of c-pnts is col by col
% NOTE: assume num_add = 0
%--------------------------
function B = parametric_B(microx, num_add, num_b)
num_nodes = (microx+1)^2;
Be = parametric_B_one_face(microx, num_add, num_b); % [3, num_nodes^2*3, nnodes]
Be1 = permute(Be, [2,1,3]); % [~, 3, nnodes]
Be2 = reshape(Be1, [], 3 * num_nodes)'; % [n, ~]
[up_i, front_i, down_i, back_i, left_i, right_i, dnum_i] = surface_dofs_id(microx);
[up_a, front_a, down_a, back_a, left_a, right_a, dnum_a] = surface_dofs_id(num_b + 1);
B = zeros(dnum_i, dnum_a);
% NOTE: these six faces have shared edges, which should be compute only by one face
% B assumes the control pnts are ordered as col by col, but nodes in this surface is row by row
Be_row = row_order(Be2, num_b);
B(up_i, up_a) = Be_row;
fid_saved = remove_shared_edges(up_i, front_i);
B(front_i(fid_saved), front_a) = Be_row(fid_saved, :);
last_id = [up_i(:); front_i(:)];
did_saved = remove_shared_edges(last_id, down_i);
B(down_i(did_saved), down_a) = Be_row(did_saved, :);
last_id = [up_i(:); front_i(:); down_i(:)];
bid_saved = remove_shared_edges(last_id, back_i);
B(back_i(bid_saved), back_a) = Be_row(bid_saved, :);
last_id = [up_i(:); front_i(:); down_i(:); back_i(:)];
lid_saved = remove_shared_edges(last_id, left_i);
B(left_i(lid_saved), left_a) = Be_row(lid_saved, :);
last_id = [up_i(:); front_i(:); down_i(:); back_i(:); left_i(:)];
rid_saved = remove_shared_edges(last_id, right_i);
B(right_i(rid_saved), right_a) = Be_row(rid_saved, :);
end
function B3 = row_order(Be, num_b)
num_nodes = size(Be, 2);
B1 = reshape(Be, [], 3, num_b+2, num_b+2);
B2 = permute(B1, [1,2,4,3]);
B3 = reshape(B2, [], num_nodes);
end
function id_saved = remove_shared_edges(last_id, this_id)
[~, id_shared, ~] = intersect(this_id, last_id,'stable');
id_saved = setdiff(1:length(this_id), id_shared);
end
function B = parametric_B_one_face(microx, num_add, num_b)
segment_length = microx / (num_add+1);
Be = parametric_B_one_divided_face(segment_length); % 3,48,s^2
idx0_Be = reshape(1 : 4^2, 4, 4);
jdx0_Be = reshape(1 : (segment_length+1)^2, segment_length+1, segment_length+1);
% for the dimension correspondance
i1_e = 1:4;
j1_e = 1:4;
idx1_Be = idx0_Be(i1_e, j1_e);
idx2_Be = [3*idx1_Be(:)-2, 3*idx1_Be(:)-1, 3*idx1_Be(:)];
B = zeros(3, 3*(num_b+2)^2, (microx+1)^2);
idx0 = reshape(1 : (num_b+2)^2, num_b+2, num_b+2);
jdx0 = reshape(1 : (microx+1)^2, microx+1, microx+1);
for i = 1 : num_add+1
i1 = (i-1)*3 + 1 : i*3 + 1;
if i < num_add+1
i2 = (i-1)*segment_length + 1 : i*segment_length ;
i2_e = 1:segment_length;
else
i2 = (i-1)*segment_length + 1 : i*segment_length + 1;
i2_e = 1:segment_length + 1;
end
for j = 1 : num_add+1
j1 = (j-1)*3 + 1 : j*3 + 1;
if j < num_add+1
j2 = (j-1)*segment_length + 1 : j*segment_length ;
j2_e = 1:segment_length;
else
j2 = (j-1)*segment_length + 1 : j*segment_length + 1;
j2_e = 1:segment_length + 1;
end
jdx2_Be = jdx0_Be(j2_e, i2_e);
idx1 = idx0(i1, j1);
idx2 = [3*idx1(:)-2, 3*idx1(:)-1, 3*idx1(:)];
jdx1 = jdx0(j2, i2);
B(:, idx2(:), jdx1(:)) = Be(:, idx2_Be(:), jdx2_Be(:));
end
end
end
% B assume the control pnts is col by col
function B = parametric_B_one_divided_face(microx)
B = zeros(3, 48, (microx+1)^2);
I = eye(4);
for i = 0 : microx
for j = 0 : microx
u = i / microx; % project to [0,1]
v = j / microx;
Bu = Bezier_matrix(u); % [3,12]
Bv = Bezier_matrix(v); % [3,12]
B(:,:,j+1+i*(microx+1)) = Bu * kron(Bv, I); % [3,12]*[12,48]=[3,48]
end
end
end
function B = Bezier_matrix(t)
b = [1, t, t^2, t^3] * [1, 0,0,0;
-3,3,0,0;
3,-6,3,0;
-1,3,-3,1]; % 1,4
I = eye(3);
B = kron(b, I); % 3,12
end
% test
% [up_i, front_i, down_i, back_i, left_i, right_i, dnum_i] = surface_dofs_id(microx);
% fid_saved = remove_shared_edges(up_i, front_i);
%
% num_b = microx-1;
% [~, ~, edofMat_full] = assemble_bezier(nelx, nely, nelz, num_b);
% [~, ~, ~, alldofs] = design_domain(opt_scale, optDesign, nelx, nely, nelz, microx, vF, num_b, ref_nodes, lx, 1);
% ufull = zeros(alldofs, 1);
% tmp = ref_nodes';
% tmp = tmp(:);
% for ele = 1: nelx*nely*nelz
% edof = edofMat_ma(ele, :);
% ue = tmp(edof);
% ub = bezier_B * ue;
%
% edof = edofMat_full(ele, :);
% ufull(edof) = ub;
% end
% deform_nodes = reshape(ufull, 3, [])';
% figure; scatter3(deform_nodes(:,1), deform_nodes(:,2), deform_nodes(:,3), 'b', 'filled'); axis equal;
% hold on; scatter3(ref_nodes(:,1), ref_nodes(:,2), ref_nodes(:,3), 'k'); axis equal;