Raw File
interpolation_on_mesh.m
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This file is part of NS2DDV.                                                      %
%                                                                                   %
% Copyright(C) 2011-2018    C. Calgaro  (caterina.calgaro@math.univ-lille1.fr)      %
%                           E. Creusé   (emmanuel.creuse@math.univ-lille1.fr)       %
%                           T. Goudon   (thierry.goudon@inria.fr)                   %
%                           A. Mouton   (alexandre.mouton@math.univ-lille1.fr)      %
%                                                                                   %
% NS2DDV 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.           %
%                                                                                   %
% NS2DDV 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      %
% NS2DDV. If not, see <http://www.gnu.org/licenses/>.                               %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function[unew] = interpolation_on_mesh(uold, METHOD, MESHOLD, MESHNEW, PARAMETERS)

	% INPUT
	% uold 			Data discretized on nodes of old mesh
	% METHOD		FE method associated to the discretization of uold
	% MESHOLD		Old mesh
	% MESHNEW		New mesh
	% PARAMETERS	List of simulation parameters
	%
	% OUTPUT
	% unew			Data interpolated on nodes of new mesh

	switch METHOD
		case {'P1'}
			pold = MESHOLD.p1;
			npold = MESHOLD.np1;
			told = MESHOLD.t1;
			ntold = MESHOLD.nt1;

			pnew = MESHNEW.p1;
			npnew = MESHNEW.np1;
			tnew = MESHNEW.t1;
			ntnew = MESHNEW.nt1;

			nDOF = 3;
		case {'P2'}
			pold = MESHOLD.p2;
			npold = MESHOLD.np2;
			told = MESHOLD.t2;
			ntold = MESHOLD.nt2;

			pnew = MESHNEW.p2;
			npnew = MESHNEW.np2;
			tnew = MESHNEW.t2;
			ntnew = MESHNEW.nt2;

			nDOF = 6;
		case {'P1B'}
			pold = MESHOLD.p1b;
			npold = MESHOLD.np1b;
			told = MESHOLD.t1b;
			ntold = MESHOLD.nt1b;

			pnew = MESHNEW.p1b;
			npnew = MESHNEW.np1b;
			tnew = MESHNEW.t1b;
			ntnew = MESHNEW.nt1b;

			nDOF = 4;
		otherwise
			error('Unknown FE method');
	end

	cprec = 1e-10;

	loctab = zeros(npnew,1);
	unew = zeros(npnew,size(uold,2));

	switch PARAMETERS.PARALLELIZATION.TOOLBOX
		case {'PCT'}
			parfor ipnew=1:npnew
				% We look for the triangle in the old mesh where the new node is located
				P = pnew(:,ipnew);
				for itold=1:ntold
					% We compute the barycentric coordinates of the new node in the old triangle
					p1 = pold(:,told(1,itold));
					p2 = pold(:,told(2,itold));
					p3 = pold(:,told(3,itold));
					lambda1 = ((p2(2)-p3(2))*(P(1)-p3(1)) + (p3(1)-p2(1))*(P(2)-p3(2))) / ...
									((p2(2)-p3(2))*(p1(1)-p3(1)) + (p3(1)-p2(1))*(p1(2)-p3(2)));
					lambda2 = ((p3(2)-p1(2))*(P(1)-p3(1)) + (p1(1)-p3(1))*(P(2)-p3(2))) / ...
									((p2(2)-p3(2))*(p1(1)-p3(1)) + (p3(1)-p2(1))*(p1(2)-p3(2)));
					lambda3 = 1. - lambda1 - lambda2;
					in = ((max(max([lambda1,lambda2,lambda3])) <= 1+cprec) && ...
								(min(min([lambda1,lambda2,lambda3])) >= -cprec));

					if in
						% The current old triangle will be used for interpolating on the new node
						loctab(ipnew) = itold;
						break;
					end
				end

				if (loctab(ipnew) == 0)
					error(sprintf('Node %d has not been localized (%g,%g)', ipnew, P(1), P(2)));
				else
					% At this point, we have found an old triangle that will be used to interpolate on the current
					% new node
					% We evaluate the old DOF functions on the new node
					% func_base doit être évalué dans le triangle de référence (utiliser phi_T^-1)

					itoldloc = loctab(ipnew);
					p1 = pold(:,told(1,itoldloc));
					p2 = pold(:,told(2,itoldloc));
					p3 = pold(:,told(3,itoldloc));
					M = [p3(2)-p1(2), p1(1)-p3(1); p1(2)-p2(2), p2(1)-p1(1)];
					d = (p2(1)-p1(1))*(p3(2)-p1(2)) - (p2(2)-p1(2))*(p3(1)-p1(1));
					Pref = M*(P-p1)/d;

					oldphiloc = func_base(METHOD, 0, Pref');
					uoldloc = uold(told(1:nDOF,itoldloc),:);
					unew(ipnew,:) = oldphiloc*uoldloc;
				end
			end

		case {'SERIAL'}
			for ipnew=1:npnew
				% We look for the triangle in the old mesh where the new node is located
				P = pnew(:,ipnew);
				for itold=1:ntold
					% We compute the barycentric coordinates of the new node in the old triangle
					p1 = pold(:,told(1,itold));
					p2 = pold(:,told(2,itold));
					p3 = pold(:,told(3,itold));
					lambda1 = ((p2(2)-p3(2))*(P(1)-p3(1)) + (p3(1)-p2(1))*(P(2)-p3(2))) / ...
									((p2(2)-p3(2))*(p1(1)-p3(1)) + (p3(1)-p2(1))*(p1(2)-p3(2)));
					lambda2 = ((p3(2)-p1(2))*(P(1)-p3(1)) + (p1(1)-p3(1))*(P(2)-p3(2))) / ...
									((p2(2)-p3(2))*(p1(1)-p3(1)) + (p3(1)-p2(1))*(p1(2)-p3(2)));
					lambda3 = 1. - lambda1 - lambda2;
					in = ((max(max([lambda1,lambda2,lambda3])) <= 1+cprec) && ...
								(min(min([lambda1,lambda2,lambda3])) >= -cprec));

					if in
						% The current old triangle will be used for interpolating on the new node
						loctab(ipnew) = itold;
						break;
					end
				end

				if (loctab(ipnew) == 0)
					error(sprintf('Node %d has not been localized (%g,%g)', ipnew, P(1), P(2)));
				else
					% At this point, we have found an old triangle that will be used to interpolate on the current
					% new node
					% We evaluate the old DOF functions on the new node
					% func_base doit être évalué dans le triangle de référence (utiliser phi_T^-1)

					itoldloc = loctab(ipnew);
					p1 = pold(:,told(1,itoldloc));
					p2 = pold(:,told(2,itoldloc));
					p3 = pold(:,told(3,itoldloc));
					M = [p3(2)-p1(2), p1(1)-p3(1); p1(2)-p2(2), p2(1)-p1(1)];
					d = (p2(1)-p1(1))*(p3(2)-p1(2)) - (p2(2)-p1(2))*(p3(1)-p1(1));
					Pref = M*(P-p1)/d;

					oldphiloc = func_base(METHOD, 0, Pref');
					uoldloc = uold(told(1:nDOF,itoldloc),:);
					unew(ipnew,:) = oldphiloc*uoldloc;
				end
			end

		otherwise
			error('Unknown parallelization technique');
	end

end
back to top