function Anew = haloNodes(A, noElem)
% HALONODES returns a variant array containing localPart of the input
% distributed array and band of elements of thickness noElem from its left
% and right neighbors.
%
% This function currently works for 1D distributions of
% 2D arrays, takes a distributed array, returns the localPart plus
% overlapping (halo) nodes
distCheck = strcmp(class(A),'codistributed');
if distCheck
% Getting distribution information
distA = codistributor(A);
dimA = distributionDimension(distA);
sizeA = size(localPart(A));
% Padding the size of A to include surrounding values
sizeA(dimA) = sizeA(dimA) + noElem * 2;
Anew = zeros(sizeA);
% Setting the offset for each array part
offset(1:2) = 0;
offset(dimA) = noElem;
% Creating local part of A and filling with values
Anew(1+offset(1):offset(1)+size(localPart(A),1),1+offset(2):...
offset(2)+size(localPart(A),2))...
= localPart(A);
% Getting the surrounding values (to the right) and putting into A
if labindex < numlabs; labFrom = labindex + 1;
else labFrom = 1; end;
if labindex > 1; labTo = labindex - 1;
else labTo = numlabs; end;
myDataSize = sizeA;
myDataSize(dimA) = noElem;
myData = Anew(1+offset(1):offset(1)+myDataSize(1),...
1+offset(2):offset(2)+myDataSize(2));
haloData = labSendReceive(labTo, labFrom, myData);
myReceiveSize = size(haloData);
if ~isempty(haloData)
Anew(end+1-myReceiveSize(1):end,end+1-myReceiveSize(2):end)=...
haloData;
end
% Getting the surrounding values (to the left) and putting into A
if labindex > 1; labFrom = labindex - 1;
else labFrom = numlabs; end;
if labindex < numlabs; labTo = labindex + 1;
else labTo = 1; end;
myDataSize = sizeA;
myDataSize(dimA) = noElem;
myData = Anew(end - myDataSize(1)+1-offset(1): end - offset(1), ...
end - myDataSize(2) + 1 - offset(2):end - offset(2));
haloData = labSendReceive(labTo, labFrom, myData);
myReceiveSize = size(haloData);
if ~isempty(haloData)
Anew(1:myReceiveSize(1),1: myReceiveSize(2))=...
haloData;
end
else
Anew = A;
end