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.
133 lines
4.5 KiB
133 lines
4.5 KiB
3 years ago
|
%--------------------------
|
||
|
% @Author: Jingqiao Hu
|
||
|
% @Date: 2021-08-25 20:20:38
|
||
|
% @LastEditTime: 2021-11-28 15:11:57
|
||
|
%--------------------------
|
||
|
function [regulated_matrix, dFdx, dk_micro] = precomputation(nele_macro, microx, rho, bezier_B, e0, e1, De, penal, ke1, iK_mi, jK_mi, ...
|
||
|
bdofs_num, dofid, edofMat_mi, dx, bdofs_plus, idofs_plus)
|
||
|
|
||
|
nele_micro = microx^2;
|
||
|
regulated_matrix = cell(nele_macro, 1);
|
||
|
dFdx = cell(nele_macro);
|
||
|
|
||
|
bezier_B = sparse(bezier_B);
|
||
|
order1 = reshape(edofMat_mi', [], 1);
|
||
|
|
||
|
vdofs_num = size(bezier_B, 2);
|
||
|
% O = zeros(bdofs_num, vdofs_num);
|
||
|
|
||
|
dk_micro = zeros(vdofs_num, vdofs_num, nele_micro, nele_macro); % [v,v,m,M]
|
||
|
|
||
|
% NOTE: Nh is ordered as
|
||
|
% 2 4
|
||
|
% 1 3
|
||
|
[~, dNh_ele, ~] = shape_gradient_ele(dx/2, dx/2, 4);
|
||
|
|
||
|
for ele = 1 : nele_macro
|
||
|
rho_e = rho(:, ele);
|
||
|
drho = penal * rho_e.^(penal-1) * (e1 - e0);
|
||
|
rho_penal = e0 + rho_e.^penal * (e1-e0); % m,1 micro-rho need to be penal
|
||
|
|
||
|
% Assemble the micro global stiffness as the order of [dofid]
|
||
|
% i.e. [4-borders, inner], to be specific, [bottom, right, up, left, inner]
|
||
|
% this order is determined by bezier_B
|
||
|
% tic
|
||
|
K = assemble_micro_k(dofid, rho_e, e0, e1, penal, ke1, iK_mi, jK_mi, 8);
|
||
|
% toc
|
||
|
phi = build_M_simply(bdofs_num, K, bezier_B);
|
||
|
|
||
|
Re = [bezier_B; phi]; % NOTE: current order of ndofs is as of [dofid]
|
||
|
R1 = Re(dofid(order1), :);
|
||
|
R2 = reshape(R1, 8, []); % [8, nele*v]
|
||
|
|
||
|
%% sensitivities
|
||
|
dFe_gp = zeros(3, vdofs_num, nele_micro, 4);
|
||
|
for gp = 1:4
|
||
|
dNe_g = dNh_ele{gp}; % [3, 8]
|
||
|
dFe = dNe_g * R2; % [3, nele*v]
|
||
|
dF1 = reshape(dFe, 3, nele_micro, vdofs_num); % [3, nele, v]
|
||
|
dFe_gp(:, :, :, gp) = permute(dF1, [1,3,2]); % [3, v, nele]
|
||
|
end
|
||
|
dFdx{ele} = dFe_gp;
|
||
|
|
||
|
dk_micro(:,:,:,ele) = dkdx_micro(edofMat_mi, microx, vdofs_num, bdofs_num, bezier_B, phi, drho, rho_penal, De, ke1, dx, dFe_gp, dNh_ele, ...
|
||
|
dofid, K, bdofs_plus, idofs_plus);
|
||
|
regulated_matrix{ele} = Re;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
%%
|
||
|
function dk_micro = dkdx_micro(edofMat_mi, microx, vdofs_num, bdofs_num, bezier_B, phi, drho, rho_penal, De, ke, dx, dFdx, dNh_ele, ...
|
||
|
dofid, K, bdofs_plus, idofs_plus)
|
||
|
|
||
|
nele_micro = microx^2;
|
||
|
ndofs = 2 * (microx + 1)^2;
|
||
|
jac = dx^2 / 4;
|
||
|
|
||
|
dk2 = zeros(vdofs_num^2, nele_micro);
|
||
|
k22 = K(bdofs_num+1 : end, bdofs_num+1 : end);
|
||
|
|
||
|
dk = zeros(ndofs, ndofs);
|
||
|
O = zeros(bdofs_num, vdofs_num);
|
||
|
|
||
|
% ke_s = zeros(9,9); % expand to 9 is for the bdofs or idofs are not in this micro-ele
|
||
|
% ke_s(1:8, 1:8) = ke;
|
||
|
% dke = ke_s(:) * drho(:)'; % [9*9, m]
|
||
|
% dke1 = reshape(dke, 9, 9, nele_micro); % [9, 9, m]
|
||
|
|
||
|
|
||
|
|
||
|
% dke2 = permute(dke1, [3,2,1]); % [m, 9, 9]
|
||
|
|
||
|
% tmp = dke2(bdofs_plus, :);
|
||
|
|
||
|
% dke3 = reshape(dek2, [], 8); % [m*9, 8]
|
||
|
|
||
|
% % dek4 = dke3(bdofs_plus(:), :); % [m*9, 8]
|
||
|
% dke5 = reshape(dke4, nele_micro, 9, 8); % [m, 9, 8]
|
||
|
|
||
|
% % bezier [2b,v] -> [m,8,v]
|
||
|
% bezier_B;
|
||
|
|
||
|
for ele_mi = 1:nele_micro
|
||
|
edof = dofid(edofMat_mi(ele_mi, :));
|
||
|
dke = ke * drho(ele_mi);
|
||
|
dk(edof, edof) = dke; % assemble by the order of [dofid]
|
||
|
|
||
|
dk21 = dk(bdofs_num+1 : end, 1 : bdofs_num) * bezier_B;
|
||
|
dk22 = dk(bdofs_num+1 : end, bdofs_num+1 : end) * (-phi);
|
||
|
dk2_pre = k22 \ (dk22 - dk21); % NOTE: not including \bO
|
||
|
|
||
|
dphi = [O; dk2_pre]; % 2n,6r
|
||
|
|
||
|
for gp = 1:4
|
||
|
dNe_g = dNh_ele{gp}; % [3, 8]
|
||
|
|
||
|
dFe = squeeze(dFdx(:, :, ele_mi, gp));
|
||
|
dk_micro2_former = dFe; % [3,6r]
|
||
|
dk_micro2_latter = dNe_g * dphi(edof, :); % [3,6r]
|
||
|
|
||
|
dk_tmp = rho_penal(ele_mi) * 2 * dk_micro2_former' * De * dk_micro2_latter; % 6r,6r
|
||
|
dk2(:, ele_mi) = dk2(:, ele_mi) + dk_tmp(:) * jac;
|
||
|
end
|
||
|
dk(:) = 0;
|
||
|
end
|
||
|
|
||
|
% expand De to D as [3,3,m]
|
||
|
dD = kron(drho(:), De); % [3m,3]
|
||
|
dD1 = reshape(dD', 3,3,[]);
|
||
|
|
||
|
dk1_tmp = 0;
|
||
|
for gp = 1:4
|
||
|
dFe = dFdx(:, :, :, gp); % [3,v,m]
|
||
|
dF1 = permute(dFe, [2,1,3]); % v * 3 * eleNum_mi
|
||
|
|
||
|
dk1_tmp = dk1_tmp + mtimesx(mtimesx(dF1, dD1), dFe) * jac; % [v,v,m]
|
||
|
end
|
||
|
dk1 = reshape(dk1_tmp, [], nele_micro);
|
||
|
dk_micro = reshape(dk1 + dk2, vdofs_num, vdofs_num, nele_micro);
|
||
|
|
||
|
% fprintf('dk1:%5.3f dk2:%5.3f scalar:%5.3f\n', max(dk1(:)), max(dk2(:)), max(dk1(:))/max(dk2(:)));
|
||
|
end
|
||
|
|