Code covered by the BSD License

# immiscible LB

by

### G. Sken (view profile)

23 Jul 2009 (Updated )

Implements Immiscible Lattice Boltzmann (ILB, D2Q9) method for two phase flows

findfirst(A, dim, count, firstlast)
```function B = findfirst(A, dim, count, firstlast)
% B = FINDFIRST(A)
%
% Look for the row-indices of a first non-zero element(s) for all columns
% in the array. It is equivalent to doing:
%
%       B=zeros(1,size(A,1));
%       for j=1:size(A,2)
%           Bj = find(A(:,j), 1, 'first');
%           if ~isempty(Bj); B(j)=Bj; end
%       end
%
% B = FINDFIRST(A, DIM): operate along the dimension DIM
% B = FINDFIRST(A, DIM, COUNT): look for the most COUNT non-zeros elements
%                               (by default COUNT is 1)
% B = FINDFIRST(A, DIM, COUNT, 'LAST'): returns most last non-zero indices
%
% INPUTS:
%       A: array of dimension (N1 x N2 x ...x Nd x ... Nn)
%          A can be any numerical class
% OUTPUT:
%       B: same dimension than A, but only Nd is contracted to COUNT
%          where d is the dimension specified by the second input (DIM)
%          and COUNT is specified by the third input
%       B dimension is (N1 x N2 x ... x COUNT x ... Nn)
%       B contains indices non-zero elements of A along DIM
%       B is filled when it's possible, the rest is filles with zeros if A
%         contains less than COUNT non-zero elements.
%
% NOTES: - Sparse matrix is not suuported
%        - Inplace engine, i.e., no duplicated temporary array is created
%
% USAGE EXAMPLES:
%
%    A = [ 0  1  1
%          1  0  1
%          0  0  0
%          0  0  1
%          1  1  1 ]
%
% OPERATE ALONG COLUMNS: > B = FINDFIRST(A) % returns [2 1 1]
%
% OPERATE ALONG ROWS: > B=FINDFIRST(A,2) % returns [2 1 0 3 1]'
%
% > B=FINDFIRST(A,1,2) % returns two indexes for each column [2 1 1
%                                                             5 5 2]
%
% > B=FINDFIRST(A,1,2, 'last') % returns two last indexes [5 5 5
%                                                          2 1 4]
%
%
% AUTHOR: Bruno Luong <brunoluong@yahoo.com>
% HISTORY
%   Original: 05-Jul-2009
%

% Default working dimension
if nargin<2 || isempty(dim)
dim = 1;
end
% Check if it's correct
if ~isscalar(dim)
error('FINDFIRST: dim must be a scalar');
end
dim = round(dim);
if dim<=0
error('FINDFIRST: dim must be positive number');
end

% Default count
if nargin<3 || isempty(count)
count = 1;
end
% Check if it's correct
if ~isscalar(count)
error('FINDFIRST: count must be a scalar');
end
count = round(double(count));

% Default 'first' 'last flag
if nargin<4 || isempty(firstlast)
firstlast = 'first';
end
if ~ischar(firstlast) || isempty(strmatch(firstlast,{'first' 'last'}))
error('FINDFIRST: Fourth argument must be ''first'' or ''last''');
end

if issparse(A)
error('FINDFIRST: A must be full matrix')
end

% Extend trailing singleton dimension if needed
szA = size(A);
szA(end+1:dim) = 1;

% Reshape A in 3D arrays, working dimension is the middle
% That is the form the FIND1DMEX
k = prod(szA(1:dim-1)); % return 1 if empty
m = szA(dim);
n = prod(szA(dim+1:end)); % return 1 if empty
A = reshape(A,[k m n]);

% Call mex engine
if strcmpi(firstlast, 'first')
B = find1dmex(A, count);
else
B = find1dmex(A, -count);
end

% Dimension of the output
szB = szA;
szB(dim) = count;
B = reshape(B,szB);

end
```