Mercurial > forge
view extra/nurbs/inst/nrbmultipatch.m @ 12662:2a027badd794 octave-forge
Added a message id in the warning
author | rafavzqz |
---|---|
date | Tue, 07 Jul 2015 13:52:48 +0000 |
parents | 1e7c06788339 |
children |
line wrap: on
line source
function [interfaces, boundary] = nrbmultipatch (nurbs) % % NRBMULTIPATCH: construct the information for gluing conforming NURBS patches, using the same format as in GeoPDEs. % % Calling Sequence: % % [interfaces, boundary] = nrbmultipatch (nurbs); % % INPUT: % % nurbs : an array of NURBS surfaces or volumes (not both), see nrbmak. % % OUTPUT: % % interfaces: array with the information for each interface, that is: % - number of the first patch (patch1), and the local side number (side1) % - number of the second patch (patch2), and the local side number (side2) % - flag (faces and volumes), ornt1, ornt2 (only volumes): information % on how the two patches match, see below. % boundary: array with the boundary faces that do not belong to any interface % - nsides: total number of sides on the boundary array (numel(boundary)) % - patches: number of the patch to which the boundary belongs to % - sides: number of the local side on the patch % % Copyright (C) 2014 Rafael Vazquez % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see <http://www.gnu.org/licenses/>. npatch = numel (nurbs); if (~iscell (nurbs(1).knots)) error ('Multipatch only works for 2D and 3D geometries') elseif (size(nurbs(1).knots,2) == 2) ndim = 2; face_corners = @(x) x.coefs(:, [1 end]); compare_corners = @(nrb1, nrb2) compare_corners_univariate (nrb1, nrb2); elseif (size(nurbs(1).knots,2) == 3) ndim = 3; face_corners = @(x) x.coefs(:, [1 end], [1 end]); compare_corners = @(nrb1, nrb2) compare_corners_bivariate (nrb1, nrb2); end non_set_faces = cell (npatch, 1); for ii = 1:npatch if (~iscell (nurbs(ii).knots)) error ('Multipatch only works for 2D and 3D geometries') elseif (ndim ~= size(nurbs(ii).knots,2)) error ('All the patches must have the same dimension (at least for now)') end non_set_faces{ii} = 1:2*ndim; end num_interfaces = 0; boundary.nsides = 0; boundary.patches = []; boundary.faces = []; for i1 = 1:npatch nrb_faces1 = nrbextract (nurbs(i1)); for j1 = non_set_faces{i1} % This is to fix a bug when two faces of the same patch form an interface % (for instance, in a ring or a torus) if (isempty (intersect (non_set_faces{i1}, j1))); continue; end nrb1 = nrb_faces1(j1); corners1 = face_corners (nrb1); non_set_faces{i1} = setdiff (non_set_faces{i1}, j1); flag = 0; i2 = i1 - 1; while (~flag && i2 < npatch) i2 = i2 + 1; nrb_faces2 = nrbextract (nurbs(i2)); j2 = 0; while (~flag && j2 < numel (non_set_faces{i2})) j2 = j2 + 1; nrb2 = nrb_faces2(non_set_faces{i2}(j2)); if (numel(nrb1.coefs) ~= numel(nrb2.coefs)) continue else corners2 = face_corners (nrb2); if (ndim == 2) flag = compare_corners (corners1, corners2); elseif (ndim == 3) [flag, ornt1, ornt2] = compare_corners (corners1, corners2); end end end end if (flag) intrfc.patch1 = i1; intrfc.side1 = j1; intrfc.patch2 = i2; intrfc.side2 = non_set_faces{i2}(j2); if (ndim ==3) intrfc.flag = flag; intrfc.ornt1 = ornt1; intrfc.ornt2 = ornt2; else intrfc.ornt = flag; end non_set_faces{i2} = setdiff (non_set_faces{i2}, non_set_faces{i2}(j2)); num_interfaces = num_interfaces + 1; interfaces(num_interfaces) = intrfc; else boundary.nsides = boundary.nsides + 1; boundary.patches = [boundary.patches; i1]; boundary.faces = [boundary.faces; j1]; end end end if (num_interfaces == 0) interfaces = []; end if (boundary.nsides == 0) boundary = []; end end function [flag, ornt1, ornt2] = compare_corners_bivariate (coefs1, coefs2) coefs1 = reshape (coefs1, 4, []); coefs2 = reshape (coefs2, 4, []); % Should use some sort of relative error if (max (max (abs (coefs1 - coefs2))) < 1e-13) flag = 1; ornt1 = 1; ornt2 = 1; elseif (max (max (abs (coefs1 - coefs2(:,[1 3 2 4])))) < 1e-13) flag = -1; ornt1 = 1; ornt2 = 1; elseif (max (max (abs (coefs1 - coefs2(:,[3 1 4 2])))) < 1e-13) flag = -1; ornt1 = -1; ornt2 = 1; elseif (max (max (abs (coefs1 - coefs2(:,[2 1 4 3])))) < 1e-13) flag = 1; ornt1 = -1; ornt2 = 1; elseif (max (max (abs (coefs1 - coefs2(:,[4 3 2 1])))) < 1e-13) flag = 1; ornt1 = -1; ornt2 = -1; elseif (max (max (abs (coefs1 - coefs2(:,[4 2 3 1])))) < 1e-13) flag = -1; ornt1 = -1; ornt2 = -1; elseif (max (max (abs (coefs1 - coefs2(:,[2 4 1 3])))) < 1e-13) flag = -1; ornt1 = 1; ornt2 = -1; elseif (max (max (abs (coefs1 - coefs2(:,[3 4 1 2])))) < 1e-13) flag = 1; ornt1 = 1; ornt2 = -1; else flag = 0; ornt1 = 0; ornt2 = 0; end end function flag = compare_corners_univariate (coefs1, coefs2) coefs1 = reshape (coefs1, 4, []); coefs2 = reshape (coefs2, 4, []); % Should use some sort of relative error if (max (max (abs (coefs1 - coefs2))) < 1e-13) flag = 1; elseif (max (max (abs (coefs1 - coefs2(:,[end 1])))) < 1e-13) flag = -1; else flag = 0; end end