%-------------------------- % @Author: Jingqiao Hu % @Date: 2022-01-23 14:35:37 % @LastEditTime: 2022-04-27 20:30:45 % 1. find the global-id for each surface % 2. build B for each surface % 3. for current surface: remove duplicated dofs with previous surfaces %-------------------------- function c_B = parametric_B_cvt_free(c_polygon, c_nodeFine, c_bnid, c_bnidSaved, ... c_bnidSavedID, c_edofMat, c_nid, c_dupB, nbnidFine, nodes, c_nodeCoarse, ) ncell = size(c_polygon, 1); c_B = cell(ncell, 1); % figure; for ele = 1 : ncell edof = c_edofMat{ele}; c_poly = c_polygon{ele}; nodeFine = c_nodeFine{ele}; c_bnid_e = c_bnid{ele}; c_bnidSavedID_e = c_bnidSavedID{ele}; c_bnidSaved_e = c_bnidSaved{ele}; c_nid_e = c_nid{ele}; c_B{ele} = B_one_cell(c_poly, c_bnid_e, c_bnidSaved_e, c_bnidSavedID_e, ... nodeFine, edof, c_nid_e, c_dupB{ele}, nbnidFine(ele), nodes, c_nodeCoarse{ele}); end % % test % figure; % nc = reshape(cbns', 3, []); % for ele = 1:npnts % edof = c_edofMat{ele}; % ue = nc(edof); % nb = ue; % nb = c_phi{ele} * ue(:); % nb = reshape(nb, 3, [])'; % scatter3(nb(:,1), nb(:,2), nb(:,3), 'filled'); hold on; axis equal; % end end function B = B_one_cell(c_poly, c_bnid, c_bnidSaved, c_bnidSavedID, nodeFine, ... edof, c_nid, c_dupB, nbnid, nodes, nodesCoarse) ndofs = length(edof); % number of coarse edof B = zeros(3*nbnid, ndofs); nface = size(c_poly, 1); nc = reshape(nodes', 3, []); nb = nc(edof); nb = reshape(nb, 3, [])'; % scatter3(nb(:,1), nb(:,2), nb(:,3), 'filled'); hold on; for i = 1 : nface segsPerFace = c_poly{i}; % [n,6] bnid = c_bnid{i}; bnidSavedID = c_bnidSavedID{i}(:)'; bnidSaved = c_bnidSaved{i}(:)'; nid = c_nid{i}(:)'; c_dupB_f = c_dupB{i}; % bdofs-id in this cell bGlobal = [3*bnidSaved-2; 3*bnidSaved-1; 3*bnidSaved]; nGlobal = [3*nid-2; 3*nid-1; 3*nid]; bnodes = nodeFine(bnid, :); Bf = B_one_face(segsPerFace, bnodes); % sum the dofs in Bf for the duplicated nodes Bf1 = zeros(length(bnidSavedID(:)), length(nid(:))); for j = 1 : length(nid) idx = c_dupB_f{j}; Bf1(:, j) = sum(Bf(bnidSavedID(:), idx), 2); end Bf1 = kron(Bf1, eye(3)); % nid must be whole, since it needs sum on all control points B(bGlobal(:), nGlobal(:)) = Bf1; % x = segsPerFace(:,[1,4]); % y = segsPerFace(:,[2,5]); % z = segsPerFace(:,[3,6]); % plot3(x',y',z','LineWidth',2); hold on; end % nc = reshape(nodes', 3, []); % ue = nc(edof); % nb = B * ue; % % nc = reshape(nodesCoarse', 3, []); % % nb = B * nc(:); % nb = reshape(nb, 3, [])'; % scatter3(nb(:,1), nb(:,2), nb(:,3), 'filled'); hold on; end function B = B_one_face(segsPerFace, bnodes) % detect end vertex polygon vertex = segsPerFace(:, 1:3); nseg = size(segsPerFace, 1); if nseg>7 && nseg~=10 error("Side of Polygon > 7 or != 10 !"); end tol = 1e-4; % compute generalized barycentric basis w nb = size(bnodes, 1); w = zeros(nb, nseg); for i = 1:nb ni = bnodes(i, :); [idx, ~] = find(abs(vertex(:,1) - ni(1)) < tol & ... abs(vertex(:,2) - ni(2)) < tol & ... abs(vertex(:,3) - ni(3)) < tol); if isempty(idx) w(i,:) = compute_barycentric(vertex, ni); else w(i,:) = 0; w(i, idx) = 1; end end % s-patch switch nseg case 3 % 200,101,002,011,020,110 nvar = 6; B = zeros(nb, nvar); B(:,1) = w(:, 1) .^ 2; B(:,2) = 2 * w(:, 1) .* w(:, 2); B(:,3) = 2 * w(:, 1) .* w(:, 3); B(:,4) = w(:, 2) .^ 2; B(:,5) = 2 * w(:, 2) .* w(:, 3); B(:,6) = w(:, 3) .^ 2; case 4 % 2000,1100,0200,0110,0020, % 0011,0002,1001,0101,1010 nvar = 10; B = zeros(nb, nvar); B(:,1) = w(:, 1) .^ 2; B(:,2) = 2 * w(:, 1) .* w(:, 2); B(:,3) = 2 * w(:, 1) .* w(:, 3); B(:,4) = 2 * w(:, 1) .* w(:, 4); B(:,5) = w(:, 2) .^ 2; B(:,6) = 2 * w(:, 2) .* w(:, 3); B(:,7) = 2 * w(:, 2) .* w(:, 4); B(:,8) = w(:, 3) .^ 2; B(:,9) = 2 * w(:, 3) .* w(:, 4); B(:,10) = w(:, 4) .^ 2; case 5 % 20000,11000,10100,10010,10001, % 02000,01100,01010,01001,00200, % 00110,00101,00020,00011,00002 nvar = 15; B = zeros(nb, nvar); B(:,1) = w(:, 1) .^ 2; B(:,2) = 2 * w(:, 1) .* w(:, 2); B(:,3) = 2 * w(:, 1) .* w(:, 3); B(:,4) = 2 * w(:, 1) .* w(:, 4); B(:,5) = 2 * w(:, 1) .* w(:, 5); B(:,6) = w(:, 2) .^ 2; B(:,7) = 2 * w(:, 2) .* w(:, 3); B(:,8) = 2 * w(:, 2) .* w(:, 4); B(:,9) = 2 * w(:, 2) .* w(:, 5); B(:,10) = w(:, 3) .^ 2; B(:,11) = 2 * w(:, 3) .* w(:, 4); B(:,12) = 2 * w(:, 3) .* w(:, 5); B(:,13) = w(:, 4) .^ 2; B(:,14) = 2 * w(:, 4) .* w(:, 5); B(:,15) = w(:, 5) .^ 2; case 6 nvar = 21; B = zeros(nb, nvar); B(:,1) = w(:, 1) .^ 2; B(:,2) = 2 * w(:, 1) .* w(:, 2); B(:,3) = 2 * w(:, 1) .* w(:, 3); B(:,4) = 2 * w(:, 1) .* w(:, 4); B(:,5) = 2 * w(:, 1) .* w(:, 5); B(:,6) = 2 * w(:, 1) .* w(:, 6); B(:,7) = w(:, 2) .^ 2; B(:,8) = 2 * w(:, 2) .* w(:, 3); B(:,9) = 2 * w(:, 2) .* w(:, 4); B(:,10) = 2 * w(:, 2) .* w(:, 5); B(:,11) = 2 * w(:, 2) .* w(:, 6); B(:,12) = w(:, 3) .^ 2; B(:,13) = 2 * w(:, 3) .* w(:, 4); B(:,14) = 2 * w(:, 3) .* w(:, 5); B(:,15) = 2 * w(:, 3) .* w(:, 6); B(:,16) = w(:, 4) .^ 2; B(:,17) = 2 * w(:, 4) .* w(:, 5); B(:,18) = 2 * w(:, 4) .* w(:, 6); B(:,19) = w(:, 5) .^ 2; B(:,20) = 2 * w(:, 5) .* w(:, 6); B(:,21) = w(:, 6) .^ 2; case 7 nvar = 28; B = zeros(nb, nvar); B(:,1) = w(:, 1) .^ 2; B(:,2) = 2 * w(:, 1) .* w(:, 2); B(:,3) = 2 * w(:, 1) .* w(:, 3); B(:,4) = 2 * w(:, 1) .* w(:, 4); B(:,5) = 2 * w(:, 1) .* w(:, 5); B(:,6) = 2 * w(:, 1) .* w(:, 6); B(:,7) = 2 * w(:, 1) .* w(:, 7); B(:,8) = w(:, 2) .^ 2; B(:,9) = 2 * w(:, 2) .* w(:, 3); B(:,10) = 2 * w(:, 2) .* w(:, 4); B(:,11) = 2 * w(:, 2) .* w(:, 5); B(:,12) = 2 * w(:, 2) .* w(:, 6); B(:,13) = 2 * w(:, 2) .* w(:, 7); B(:,14) = w(:, 3) .^ 2; B(:,15) = 2 * w(:, 3) .* w(:, 4); B(:,16) = 2 * w(:, 3) .* w(:, 5); B(:,17) = 2 * w(:, 3) .* w(:, 6); B(:,18) = 2 * w(:, 3) .* w(:, 7); B(:,19) = w(:, 4) .^ 2; B(:,20) = 2 * w(:, 4) .* w(:, 5); B(:,21) = 2 * w(:, 4) .* w(:, 6); B(:,22) = 2 * w(:, 4) .* w(:, 7); B(:,23) = w(:, 5) .^ 2; B(:,24) = 2 * w(:, 5) .* w(:, 6); B(:,25) = 2 * w(:, 5) .* w(:, 7); B(:,26) = w(:, 6) .^ 2; B(:,27) = 2 * w(:, 6) .* w(:, 7); B(:,28) = w(:, 7) .^ 2; case 10 idx = 1; B = zeros(nb, 55); for i = 1:10 scalar = 1; for j = i:10 B(:,idx) = w(:, i) .* w(:, j) * scalar; scalar = 2; idx = idx + 1; end end end % B = kron(B, eye(3)); end