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

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