%-------------------------- % @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